From c98b2f82a4e532ca61592b08e3ad60749eb9f8d7 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 8 Mar 2002 21:12:35 +0000 Subject: Initial revision --- tools/Makefile.am | 10 + tools/Makefile.in | 433 +++++++++++++++++++++++++++++ tools/hciattach.8 | 102 +++++++ tools/hciattach.c | 751 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/hciconfig.c | 524 +++++++++++++++++++++++++++++++++++ tools/hcisecfilter.c | 79 ++++++ tools/hcitool.c | 368 +++++++++++++++++++++++++ tools/l2ping.8 | 49 ++++ tools/l2ping.c | 251 +++++++++++++++++ tools/l2test.c | 493 +++++++++++++++++++++++++++++++++ tools/scotest.c | 358 ++++++++++++++++++++++++ 11 files changed, 3418 insertions(+) create mode 100644 tools/Makefile.am create mode 100644 tools/Makefile.in create mode 100644 tools/hciattach.8 create mode 100644 tools/hciattach.c create mode 100644 tools/hciconfig.c create mode 100644 tools/hcisecfilter.c create mode 100644 tools/hcitool.c create mode 100644 tools/l2ping.8 create mode 100644 tools/l2ping.c create mode 100644 tools/l2test.c create mode 100644 tools/scotest.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 00000000..d3133e5f --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,10 @@ +# +# $Id$ +# + +mandir = $(prefix)/usr/share/man + +sbin_PROGRAMS = hciattach hciconfig +bin_PROGRAMS = hcitool l2ping + +man_MANS = hciattach.8 l2ping.8 diff --git a/tools/Makefile.in b/tools/Makefile.in new file mode 100644 index 00000000..fe838a44 --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,433 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# $Id$ +# + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AWK = @AWK@ +CC = @CC@ +DISTRO = @DISTRO@ +GLIB = @GLIB@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LDFLAGS = @GLIB_LDFLAGS@ +LD = @LD@ +LEX = @LEX@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +PCMCIA = @PCMCIA@ +VERSION = @VERSION@ +YACC = @YACC@ + +mandir = $(prefix)/usr/share/man + +sbin_PROGRAMS = hciattach hciconfig +bin_PROGRAMS = hcitool l2ping + +man_MANS = hciattach.8 l2ping.8 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +hcitool_SOURCES = hcitool.c +hcitool_OBJECTS = hcitool.o +hcitool_LDADD = $(LDADD) +hcitool_DEPENDENCIES = +hcitool_LDFLAGS = +l2ping_SOURCES = l2ping.c +l2ping_OBJECTS = l2ping.o +l2ping_LDADD = $(LDADD) +l2ping_DEPENDENCIES = +l2ping_LDFLAGS = +hciattach_SOURCES = hciattach.c +hciattach_OBJECTS = hciattach.o +hciattach_LDADD = $(LDADD) +hciattach_DEPENDENCIES = +hciattach_LDFLAGS = +hciconfig_SOURCES = hciconfig.c +hciconfig_OBJECTS = hciconfig.o +hciconfig_LDADD = $(LDADD) +hciconfig_DEPENDENCIES = +hciconfig_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +man8dir = $(mandir)/man8 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DEP_FILES = .deps/hciattach.P .deps/hciconfig.P .deps/hcitool.P \ +.deps/l2ping.P +SOURCES = hcitool.c l2ping.c hciattach.c hciconfig.c +OBJECTS = hcitool.o l2ping.o hciattach.o hciconfig.o + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +mostlyclean-sbinPROGRAMS: + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + +distclean-sbinPROGRAMS: + +maintainer-clean-sbinPROGRAMS: + +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(sbindir) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(sbin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +hcitool: $(hcitool_OBJECTS) $(hcitool_DEPENDENCIES) + @rm -f hcitool + $(LINK) $(hcitool_LDFLAGS) $(hcitool_OBJECTS) $(hcitool_LDADD) $(LIBS) + +l2ping: $(l2ping_OBJECTS) $(l2ping_DEPENDENCIES) + @rm -f l2ping + $(LINK) $(l2ping_LDFLAGS) $(l2ping_OBJECTS) $(l2ping_LDADD) $(LIBS) + +hciattach: $(hciattach_OBJECTS) $(hciattach_DEPENDENCIES) + @rm -f hciattach + $(LINK) $(hciattach_LDFLAGS) $(hciattach_OBJECTS) $(hciattach_LDADD) $(LIBS) + +hciconfig: $(hciconfig_OBJECTS) $(hciconfig_DEPENDENCIES) + @rm -f hciconfig + $(LINK) $(hciconfig_LDFLAGS) $(hciconfig_OBJECTS) $(hciconfig_LDADD) $(LIBS) + +install-man8: + $(mkinstalldirs) $(DESTDIR)$(man8dir) + @list='$(man8_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ + done + +uninstall-man8: + @list='$(man8_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ + rm -f $(DESTDIR)$(man8dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-man8 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-man8 + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = tools + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu tools/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS install-sbinPROGRAMS +install-exec: install-exec-am + +install-data-am: install-man +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS uninstall-man +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(MANS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir) \ + $(DESTDIR)$(mandir)/man8 + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-sbinPROGRAMS \ + mostlyclean-compile mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-sbinPROGRAMS clean-compile clean-tags \ + clean-depend clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-sbinPROGRAMS \ + distclean-compile distclean-tags distclean-depend \ + distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-sbinPROGRAMS maintainer-clean-compile \ + maintainer-clean-tags maintainer-clean-depend \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \ +maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ +install-sbinPROGRAMS mostlyclean-compile distclean-compile \ +clean-compile maintainer-clean-compile install-man8 uninstall-man8 \ +install-man uninstall-man tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir mostlyclean-depend \ +distclean-depend clean-depend maintainer-clean-depend info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tools/hciattach.8 b/tools/hciattach.8 new file mode 100644 index 00000000..b327336b --- /dev/null +++ b/tools/hciattach.8 @@ -0,0 +1,102 @@ +.TH HCIATTACH 8 "Jan 22 2002" BlueZ "Linux System Administration" +.SH NAME +hciattach \- attach serial devices via UART HCI to BlueZ stack +.SH SYNOPSIS +.B hciattach +< +.I tty +> < +.I type +| +.I id +> [ +.I speed +] [ +.I flow +] +.SH DESCRIPTION +.LP +Hciattach is used to attach a serial UART to the Bluetooth stack as HCI +transport interface. +.SH OPTIONS +.TP +.I +This specifies the serial device to attach. A leading +.B /dev +can be omitted. Examples: +.B /dev/ttyS1 +.B ttyS2 +.TP +.I +The +.B type +or +.B id +of the Bluetooth device that is to be attached, i.e. vendor or other device +specific identifier. Currently supported types are +.RS +.TP +.B type +.B description +.TP +any +Unspecified HCI_UART interface, no vendor specific options +.TP +ericsson +Ericsson based modules +.TP +digi +Digianswer based cards +.TP +xircom +Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter +.TP +csr +CSR Casira serial adapter or BrainBoxes serial dongle (BL642) +.TP +bboxes +BrainBoxes PCMCIA card (BL620) +.TP +swave +Silicon Wave kits +.RE + +Supported IDs are (manufacturer id, product id) +.RS +.TP +0x0105, 0x080a +Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter +.TP +0x0160, 0x0002 +BrainBoxes PCMCIA card (BL620) +.RE + +.TP +.I +The +.B speed +specifies the UART speed to use. Baudrates higher than 115.200bps require +vendor specific initializations that are not implemented for all types of +devices. In general the following speeds are supported: + +.B 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 + +Supported vendor devices are automatically initialised to their respective +best settings. +.TP +.I +If the keyword +.B flow +is appended to the list of options then hardware flow control is forced on +the serial link ( +.B CRTSCTS +). All above mentioned device types have +.B flow +set by default. To force no flow control use +.B noflow +instead. + +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Nils Faerber diff --git a/tools/hciattach.c b/tools/hciattach.c new file mode 100644 index 00000000..a4489019 --- /dev/null +++ b/tools/hciattach.c @@ -0,0 +1,751 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +struct uart_t { + char *type; + int m_id; + int p_id; + int proto; + int speed; + int flags; + int (*init) (int fd, struct uart_t *u, struct termios *ti); +}; + +#define FLOW_CTL 0x0001 + +static int uart_speed(int s) +{ + switch (s) { + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; + case 57600: + return B57600; + case 115200: + return B115200; + case 230400: + return B230400; + case 460800: + return B460800; + case 921600: + return B921600; + default: + return B57600; + } +} + +static int set_speed(int fd, struct termios *ti, int speed) +{ + cfsetospeed(ti, uart_speed(speed)); + return tcsetattr(fd, TCSANOW, ti); +} + +static void sig_alarm(int sig) +{ + fprintf(stderr, "Initialization timed out.\n"); + exit(1); +} + +/* + * Read an HCI event from the given file descriptor. + */ +static int read_hci_event(int fd, unsigned char* buf, int size) +{ + int remain, r; + int count = 0; + + if (size <= 0) + return -1; + + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ + while (1) { + r = read(fd, buf, 1); + if (r <= 0) + return -1; + if (buf[0] == 0x04) + break; + } + count++; + + /* The next two bytes are the event code and parameter total length. */ + while (count < 3) { + r = read(fd, buf + count, 3 - count); + if (r <= 0) + return -1; + count += r; + } + + /* Now we read the parameters. */ + if (buf[2] < (size - 3)) + remain = buf[2]; + else + remain = size - 3; + + while ((count - 3) < remain) { + r = read(fd, buf + count, remain - (count - 3)); + if (r <= 0) + return -1; + count += r; + } + return count; +} + +/* + * Ericsson specific initialization + */ +static int ericsson(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[10]; + + /* Switch to default Ericsson baudrate*/ + if (set_speed(fd, ti, 57600) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x09; + cmd[2] = 0xfc; + cmd[3] = 0x01; + + switch (u->speed) { + case 57600: + cmd[4] = 0x03; + break; + case 115200: + cmd[4] = 0x02; + break; + case 230400: + cmd[4] = 0x01; + break; + case 460800: + cmd[4] = 0x00; + break; + default: + cmd[4] = 0x03; + u->speed = 57600; + break; + } + + /* Send initialization command */ + if (write(fd, cmd, 5) != 5) { + perror("Failed to write init command"); + return -1; + } + nanosleep(&tm, NULL); + return 0; +} + +/* + * Digianswer specific initialization + */ +static int digi(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[10]; + + /* Switch to default Digi baudrate*/ + if (set_speed(fd, ti, 9600) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + /* DigiAnswer set baud rate command */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x07; + cmd[2] = 0xfc; + cmd[3] = 0x01; + + switch (u->speed) { + case 57600: + cmd[4] = 0x08; + break; + case 115200: + cmd[4] = 0x09; + break; + default: + cmd[4] = 0x09; + u->speed = 115200; + break; + } + + /* Send initialization command */ + if (write(fd, cmd, 5) != 5) { + perror("Failed to write init command"); + return -1; + } + nanosleep(&tm, NULL); + return 0; +} + +/* + * CSR specific initialization + * Inspired strongly by code in OpenBT and experimentations with Brainboxes + * Pcmcia card. + * Jean Tourrilhes - 14.11.01 + */ +static int csr(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 10000000}; /* 10ms - be generous */ + unsigned char cmd[30]; /* Command */ + unsigned char resp[30]; /* Response */ + int clen = 0; /* Command len */ + static int csr_seq = 0; /* Sequence number of command */ + int divisor; + + /* Switch to default CSR baudrate */ + if (set_speed(fd, ti, 115200) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + /* It seems that if we set the CSR UART speed straight away, it + * won't work, the CSR UART gets into a state where we can't talk + * to it anymore. + * On the other hand, doing a read before setting the CSR speed + * seems to be ok. + * Therefore, the strategy is to read the build ID (useful for + * debugging) and only then set the CSR UART speed. Doing like + * this is more complex but at least it works ;-) + * The CSR UART control may be slow to wake up or something because + * every time I read its speed, its bogus... + * Jean II */ + + /* Try to read the build ID of the CSR chip */ + clen = 5 + (5 + 6) * 2; + /* HCI header */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x00; /* CSR command */ + cmd[2] = 0xfc; /* MANUFACTURER_SPEC */ + cmd[3] = 1 + (5 + 6) * 2; /* len */ + /* CSR MSG header */ + cmd[4] = 0xC2; /* first+last+channel=BCC */ + /* CSR BCC header */ + cmd[5] = 0x00; /* type = GET-REQ */ + cmd[6] = 0x00; /* - msB */ + cmd[7] = 5 + 4; /* len */ + cmd[8] = 0x00; /* - msB */ + cmd[9] = csr_seq & 0xFF;/* seq num */ + cmd[10] = (csr_seq >> 8) & 0xFF; /* - msB */ + csr_seq++; + cmd[11] = 0x19; /* var_id = CSR_CMD_BUILD_ID */ + cmd[12] = 0x28; /* - msB */ + cmd[13] = 0x00; /* status = STATUS_OK */ + cmd[14] = 0x00; /* - msB */ + /* CSR BCC payload */ + memset(cmd + 15, 0, 6 * 2); + + /* Send command */ + do { + if (write(fd, cmd, clen) != clen) { + perror("Failed to write init command (GET_BUILD_ID)"); + return -1; + } + + /* Read reply. */ + if (read_hci_event(fd, resp, 100) < 0) { + perror("Failed to read init response (GET_BUILD_ID)"); + return -1; + } + + /* Event code 0xFF is for vendor-specific events, which is + * what we're looking for. */ + } while (resp[1] != 0xFF); + +#ifdef CSR_DEBUG + { + char temp[512]; + int i; + for (i=0; i < rlen; i++) + sprintf(temp + (i*3), "-%02X", resp[i]); + fprintf(stderr, "Reading CSR build ID %d [%s]\n", rlen, temp + 1); + // In theory, it should look like : + // 04-FF-13-FF-01-00-09-00-00-00-19-28-00-00-73-00-00-00-00-00-00-00 + } +#endif + /* Display that to user */ + fprintf(stderr, "CSR build ID 0x%02X-0x%02X\n", + resp[15] & 0xFF, resp[14] & 0xFF); + + /* Try to read the current speed of the CSR chip */ + clen = 5 + (5 + 4)*2; + /* -- HCI header */ + cmd[3] = 1 + (5 + 4)*2; /* len */ + /* -- CSR BCC header -- */ + cmd[9] = csr_seq & 0xFF; /* seq num */ + cmd[10] = (csr_seq >> 8) & 0xFF; /* - msB */ + csr_seq++; + cmd[11] = 0x02; /* var_id = CONFIG_UART */ + cmd[12] = 0x68; /* - msB */ + +#ifdef CSR_DEBUG + /* Send command */ + do { + if (write(fd, cmd, clen) != clen) { + perror("Failed to write init command (GET_BUILD_ID)"); + return -1; + } + + /* Read reply. */ + if (read_hci_event(fd, resp, 100) < 0) { + perror("Failed to read init response (GET_BUILD_ID)"); + return -1; + } + + /* Event code 0xFF is for vendor-specific events, which is + * what we're looking for. */ + } while (resp[1] != 0xFF); + + { + char temp[512]; + int i; + for (i=0; i < rlen; i++) + sprintf(temp + (i*3), "-%02X", resp[i]); + fprintf(stderr, "Reading CSR UART speed %d [%s]\n", rlen, temp+1); + } +#endif + + /* Now, create the command that will set the UART speed */ + /* CSR BCC header */ + cmd[5] = 0x02; /* type = SET-REQ */ + cmd[6] = 0x00; /* - msB */ + cmd[9] = csr_seq & 0xFF; /* seq num */ + cmd[10] = (csr_seq >> 8) & 0xFF;/* - msB */ + csr_seq++; + + switch (u->speed) { + case 9600: + divisor = 0x0027; + break; + /* Various speeds ommited */ + case 57600: + divisor = 0x00EC; + break; + case 115200: + divisor = 0x01D8; + break; + /* For Brainbox Pcmcia cards */ + case 460800: + divisor = 0x075F; + break; + case 921600: + divisor = 0x0EBF; + break; + default: + /* Safe default */ + divisor = 0x01D8; + u->speed = 115200; + break; + } + /* No parity, one stop bit -> divisor |= 0x0000; */ + cmd[15] = (divisor) & 0xFF; /* divider */ + cmd[16] = (divisor >> 8) & 0xFF; /* - msB */ + /* The rest of the payload will be 0x00 */ + +#ifdef CSR_DEBUG + { + char temp[512]; + int i; + for(i = 0; i < clen; i++) + sprintf(temp + (i*3), "-%02X", cmd[i]); + fprintf(stderr, "Writing CSR UART speed %d [%s]\n", clen, temp + 1); + // In theory, it should look like : + // 01-00-FC-13-C2-02-00-09-00-03-00-02-68-00-00-BF-0E-00-00-00-00-00-00 + // 01-00-FC-13-C2-02-00-09-00-01-00-02-68-00-00-D8-01-00-00-00-00-00-00 + } +#endif + + /* Send the command to set the CSR UART speed */ + if (write(fd, cmd, clen) != clen) { + perror("Failed to write init command (SET_UART_SPEED)"); + return -1; + } + nanosleep(&tm, NULL); + return 0; +} + +/* + * Silicon Wave specific initialization + * Thomas Moser + */ +static int swave(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 500000}; + char cmd[10], rsp[100]; + int r; + + /* Switch to default Silicon Wave baudrate*/ + if (set_speed(fd, ti, 115200) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + // Silicon Wave set baud rate command + // see HCI Vendor Specific Interface from Silicon Wave + // first send a "param access set" command to set the + // appropriate data fields in RAM. Then send a "HCI Reset + // Subcommand", e.g. "soft reset" to make the changes effective. + + cmd[0] = HCI_COMMAND_PKT; // it's a command packet + cmd[1] = 0x0B; // OCF 0x0B = param access set + cmd[2] = 0xfc; // OGF bx111111 = vendor specific + cmd[3] = 0x06; // 6 bytes of data following + cmd[4] = 0x01; // param sub command + cmd[5] = 0x11; // tag 17 = 0x11 = HCI Transport Params + cmd[6] = 0x03; // length of the parameter following + cmd[7] = 0x01; // HCI Transport flow control enable + cmd[8] = 0x01; // HCI Transport Type = UART + + switch (u->speed) { + case 19200: + cmd[9] = 0x03; + break; + case 38400: + cmd[9] = 0x02; + break; + case 57600: + cmd[9] = 0x01; + break; + case 115200: + cmd[9] = 0x00; + break; + default: + u->speed = 115200; + cmd[9] = 0x00; + break; + } + + /* Send initialization command */ + if (write(fd, cmd, 10) != 5) { + perror("Failed to write init command"); + return -1; + } + + // We should wait for a "GET Event" to confirm the success of + // the baud rate setting. Wait some time before reading. Better: + // read with timeout, parse data + // until correct answer, else error handling ... todo ... + + nanosleep(&tm, NULL); + + r = read(fd, rsp, sizeof(rsp)); + if (r > 0) { + // guess it's okay, but we should parse the reply. But since + // I don't react on an error anyway ... todo + // Response packet format: + // 04 Event + // FF Vendor specific + // 07 Parameter length + // 0B Subcommand + // 01 Setevent + // 11 Tag specifying HCI Transport Layer Parameter + // 03 length + // 01 flow on + // 01 Hci Transport type = Uart + // xx Baud rate set (see above) + } else { + // ups, got error. + return -1; + } + + // we probably got the reply. Now we must send the "soft reset": + cmd[0] = HCI_COMMAND_PKT; // it's a command packet + cmd[1] = 0x0B; // OCF 0x0B = param access set + cmd[2] = 0xfc; // OGF bx111111 = vendor specific + cmd[3] = 0x01; // 1 byte of data following + cmd[4] = 0x03; // HCI Reset Subcommand + + // Send initialization command + if (write(fd, cmd, 5) != 5) { + perror("Can't write Silicon Wave reset cmd."); + return -1; + } + + nanosleep(&tm, NULL); + + // now the uart baud rate on the silicon wave module is set and effective. + // change our own baud rate as well. Then there is a reset event comming in + // on the *new* baud rate. This is *undocumented*! The packet looks like this: + // 04 FF 01 0B (which would make that a confirmation of 0x0B = "Param + // subcommand class". So: change to new baud rate, read with timeout, parse + // data, error handling. BTW: all param access in Silicon Wave is done this way. + // Maybe this code would belong in a seperate file, or at least code reuse... + + return 0; +} + +struct uart_t uart[] = { + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, + + /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + + /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, csr }, + + /* BrainBoxes PCMCIA card (BL620) */ + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 460800, FLOW_CTL, csr }, + + /* Silicon Wave kits */ + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, swave }, + + /* Sphinx Electronics PICO Card */ + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + + { NULL, 0 } +}; + +struct uart_t * get_by_id(int m_id, int p_id) +{ + int i; + for (i = 0; uart[i].type; i++) { + if (uart[i].m_id == m_id && uart[i].p_id == p_id) + return &uart[i]; + } + return NULL; +} + +struct uart_t * get_by_type(char *type) +{ + int i; + for (i = 0; uart[i].type; i++) { + if (!strcmp(uart[i].type, type)) + return &uart[i]; + } + return NULL; +} + +/* Initialize UART driver */ +int init_uart(char *dev, struct uart_t *u) +{ + struct termios ti; + int fd, i; + + fd = open(dev, O_RDWR | O_NOCTTY); + if (fd < 0) { + perror("Can't open serial port"); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (tcgetattr(fd, &ti) < 0) { + perror("Can't get port settings"); + return -1; + } + + cfmakeraw(&ti); + + ti.c_cflag |= CLOCAL; + if (u->flags & FLOW_CTL) + ti.c_cflag |= CRTSCTS; + else + ti.c_cflag &= ~CRTSCTS; + + if (tcsetattr(fd, TCSANOW, &ti) < 0) { + perror("Can't set port settings"); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (u->init && u->init(fd, u, &ti) < 0) + return -1; + + tcflush(fd, TCIOFLUSH); + + /* Set actual baudrate */ + if (set_speed(fd, &ti, u->speed) < 0) { + perror("Can't set baud rate"); + return -1; + } + + /* Set TTY to N_HCI line discpline */ + i = N_HCI; + if (ioctl(fd, TIOCSETD, &i) < 0) { + perror("Can't set line disc"); + return -1; + } + + if (ioctl(fd, HCIUARTSETPROTO, u->proto) < 0) { + perror("Can't set device"); + return -1; + } + + return fd; +} + +static void usage(void) +{ + printf("hciattach - HCI UART driver initialization utility\n"); + printf("Usage:\n"); + printf("\thciattach [speed] [flow]\n"); + printf("\thciattach -l\n"); +} + +extern int optind, opterr, optopt; +extern char *optarg; + +int main(int argc, char *argv[]) +{ + struct uart_t *u = NULL; + int detach, opt, i, n; + int to = 5; + struct sigaction sa; + char dev[20]; + + detach = 1; + + while ((opt=getopt(argc, argv, "nt:l")) != EOF) { + switch(opt) { + case 'n': + detach = 0; + break; + + case 't': + to = atoi(optarg); + break; + + case 'l': + for (i = 0; uart[i].type; i++) { + printf("%-10s0x%04x,0x%04x\n", uart[i].type, + uart[i].m_id, uart[i].p_id); + } + exit(0); + + default: + usage(); + exit(1); + } + } + + n = argc - optind; + if (n < 2) { + usage(); + exit(1); + } + + for (n = 0; optind < argc; n++, optind++) { + char *opt; + + opt = argv[optind]; + + switch(n) { + case 0: + dev[0] = 0; + if (!strchr(opt, '/')) + strcpy(dev, "/dev/"); + strcat(dev, opt); + break; + + case 1: + if (strchr(argv[optind], ',')) { + int m_id, p_id; + sscanf(argv[optind], "%x,%x", &m_id, &p_id); + u = get_by_id(m_id, p_id); + } else { + u = get_by_type(opt); + } + + if (!u) { + fprintf(stderr, "Unknow device type or id\n"); + exit(1); + } + + break; + + case 2: + u->speed = atoi(argv[optind]); + break; + + case 3: + if (!strcmp("flow", argv[optind])) + u->flags |= FLOW_CTL; + else + u->flags &= ~FLOW_CTL; + break; + } + } + + if (!u) { + fprintf(stderr, "Unknow device type or id\n"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_alarm; + sigaction(SIGALRM, &sa, NULL); + + /* 5 seconds should be enought for intialization */ + alarm(to); + + n = init_uart(dev, u); + if (n < 0) { + perror("Can't init device"); + exit(1); + } + + alarm(0); + + if (detach) { + if (fork()) return 0; + for (i=0; i<20; i++) + if (i != n) close(i); + } + + while (1) sleep(999999999); + return 0; +} diff --git a/tools/hciconfig.c b/tools/hciconfig.c new file mode 100644 index 00000000..3cbec922 --- /dev/null +++ b/tools/hciconfig.c @@ -0,0 +1,524 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +extern int optind,opterr,optopt; +extern char *optarg; + +static struct hci_dev_info di; +static int all; + +void print_dev_hdr(struct hci_dev_info *di); +void print_dev_info(int ctl, struct hci_dev_info *di); + +void print_dev_list(int ctl, int flags) +{ + struct hci_dev_list_req *dl; + struct hci_dev_req *dr; + int i; + + if( !(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t))) ) { + perror("Can't allocate memory"); + exit(1); + } + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if( ioctl(ctl, HCIGETDEVLIST, (void*)dl) ) { + perror("Can't get device list"); + exit(1); + } + for(i=0; i< dl->dev_num; i++) { + di.dev_id = (dr+i)->dev_id; + if( ioctl(ctl, HCIGETDEVINFO, (void*)&di) ) + continue; + print_dev_info(ctl, &di); + } +} + +void print_pkt_type(struct hci_dev_info *di) +{ + printf("\tPacket type: %s\n", hci_ptypetostr(di->pkt_type)); +} + +void print_link_policy(struct hci_dev_info *di) +{ + printf("\tLink policy: %s\n", hci_lptostr(di->link_policy)); +} + +void print_link_mode(struct hci_dev_info *di) +{ + printf("\tLink mode: %s\n", hci_lmtostr(di->link_mode)); +} + +void print_dev_features(struct hci_dev_info *di) +{ + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + di->features[0], di->features[1], + di->features[2], di->features[3] ); +} + +void cmd_rstat(int ctl, int hdev, char *opt) +{ + /* Reset HCI device stat counters */ + if( ioctl(ctl, HCIDEVRESTAT, hdev) < 0 ) { + printf("Can't reset stats counters hci%d. %s(%d)\n", hdev, + strerror(errno), errno); + exit(1); + } +} + +void cmd_scan(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + dr.dev_opt = SCAN_DISABLED; + if( !strcmp(opt, "iscan") ) + dr.dev_opt = SCAN_INQUIRY; + else if( !strcmp(opt, "pscan") ) + dr.dev_opt = SCAN_PAGE; + else if( !strcmp(opt, "piscan") ) + dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; + + if( ioctl(ctl, HCISETSCAN, (unsigned long)&dr) < 0 ) { + printf("Can't set scan mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_auth(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + if( !strcmp(opt, "auth") ) + dr.dev_opt = AUTH_ENABLED; + else + dr.dev_opt = AUTH_DISABLED; + + if( ioctl(ctl, HCISETAUTH, (unsigned long)&dr) < 0 ) { + printf("Can't set auth on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_encrypt(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + if( !strcmp(opt, "encrypt") ) + dr.dev_opt = ENCRYPT_P2P; + else + dr.dev_opt = ENCRYPT_DISABLED; + + if( ioctl(ctl, HCISETENCRYPT, (unsigned long)&dr) < 0 ) { + printf("Can't set encrypt on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_up(int ctl, int hdev, char *opt) +{ + int ret; + + /* Start HCI device */ + if( (ret = ioctl(ctl, HCIDEVUP, hdev)) < 0 ) { + if( errno == EALREADY ) + return; + printf("Can't init device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + cmd_scan(ctl, hdev, "piscan"); +} + +void cmd_down(int ctl, int hdev, char *opt) +{ + /* Stop HCI device */ + if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) { + printf("Can't down device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_reset(int ctl, int hdev, char *opt) +{ + /* Reset HCI device + if( ioctl(ctl, HCIDEVRESET, hdev) < 0 ){ + printf("Reset failed hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + */ + cmd_down(ctl, hdev, "down"); + cmd_up(ctl, hdev, "up"); +} + +void cmd_ptype(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + + if (hci_strtoptype(opt, &dr.dev_opt)) { + if (ioctl(ctl, HCISETPTYPE, (unsigned long)&dr) < 0) { + printf("Can't set pkttype on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + } else { + print_dev_hdr(&di); + print_pkt_type(&di); + } +} + +void cmd_lp(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + + if (hci_strtolp(opt, &dr.dev_opt)) { + if (ioctl(ctl, HCISETLINKPOL, (unsigned long)&dr) < 0) { + printf("Can't set link policy on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + print_dev_hdr(&di); + print_link_policy(&di); + } +} + +void cmd_lm(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + + if (hci_strtolm(opt, &dr.dev_opt)) { + if (ioctl(ctl, HCISETLINKMODE, (unsigned long)&dr) < 0) { + printf("Can't set default link mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + print_dev_hdr(&di); + print_link_mode(&di); + } +} + +void cmd_features(int ctl, int hdev, char *opt) +{ + print_dev_hdr(&di); + print_dev_features(&di); +} + +void cmd_name(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + change_local_name_cp cp; + strcpy(cp.name, opt); + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_CHANGE_LOCAL_NAME; + rq.cparam = &cp; + rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't change local name on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + read_local_name_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_NAME; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_NAME_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read local name on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read local name on hci%d returned status %d\n", hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + printf("\tName: '%s'\n", rp.name); + } +} + +void cmd_class(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + if (opt) { + uint32_t cod = htobl(strtoul(opt, NULL, 16)); + write_class_of_dev_cp cp; + + memcpy(cp.dev_class, &cod, 3); + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CLASS_OF_DEV; + rq.cparam = &cp; + rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't write local class of device on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + read_class_of_dev_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CLASS_OF_DEV; + rq.rparam = &rp; + rq.rlen = READ_CLASS_OF_DEV_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read class of device on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (rp.status) { + printf("Read class of device on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + printf("\tClass: 0x%02x%02x%02x\n", + rp.dev_class[2], rp.dev_class[1], rp.dev_class[0]); + } +} + +void cmd_version(int ctl, int hdev, char *opt) +{ + struct hci_version ver; + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + printf("Can't read version info hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf( "\tHCI Ver: 0x%x HCI Rev: 0x%x LMP Ver: 0x%x LMP Subver: 0x%x\n" + "\tManufacturer: %d\n", + ver.hci_ver, ver.hci_rev, ver.lmp_ver, ver.lmp_subver, + ver.manufacturer); +} + +void print_dev_hdr(struct hci_dev_info *di) +{ + static int hdr = -1; + bdaddr_t bdaddr; + + if (hdr == di->dev_id) + return; + hdr = di->dev_id; + + baswap(&bdaddr, &di->bdaddr); + + printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); + printf("\tBD Address: %s ACL MTU: %d:%d SCO: MTU %d:%d\n", + batostr(&bdaddr), di->acl_mtu, di->acl_max, + di->sco_mtu, di->sco_max); +} + +void print_dev_info(int ctl, struct hci_dev_info *di) +{ + struct hci_dev_stats *st = &di->stat; + + print_dev_hdr(di); + + printf("\t%s\n", hci_dflagstostr(di->flags) ); + + printf("\tRX bytes:%d acl:%d sco:%d events:%d errors:%d\n", + st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx); + + printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n", + st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); + + if (all) { + print_dev_features(di); + print_pkt_type(di); + print_link_policy(di); + print_link_mode(di); + + cmd_name(ctl, di->dev_id, NULL); + cmd_class(ctl, di->dev_id, NULL); + cmd_version(ctl, di->dev_id, NULL); + } + + printf("\n"); +} + +struct { + char *cmd; + void (*func)(int ctl, int hdev, char *opt); + char *opt; + char *doc; +} command[] = { + { "up", cmd_up, 0, "Open and initialize HCI device" }, + { "down", cmd_down, 0, "Close HCI device" }, + { "reset", cmd_reset, 0, "Reset HCI device" }, + { "rstat", cmd_rstat, 0, "Reset statistic counters" }, + { "auth", cmd_auth, 0, "Enable Authentication" }, + { "noauth", cmd_auth, 0, "Disable Authentication" }, + { "encrypt",cmd_encrypt,0, "Enable Encryption" }, + { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, + { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, + { "noscan", cmd_scan, 0, "Disable scan" }, + { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, + { "pscan", cmd_scan, 0, "Enable Page scan" }, + { "ptype", cmd_ptype, "[type]", "Get/Set default packet type" }, + { "lm", cmd_lm, "[mode]", "Get/Set default link mode" }, + { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, + { "name", cmd_name, "[name]", "Get/Set local name" }, + { "class", cmd_class, "[class]", "Get/Set class of device" }, + { "version", cmd_version, 0, "Display version information" }, + { "features", cmd_features, 0,"Display device features" }, + { NULL, NULL, 0} +}; + +void usage(void) +{ + int i; + + printf("hciconfig - HCI device configuration utility\n"); + printf("Usage:\n" + "\thciconfig\n" + "\thciconfig [-a] hciX [command]\n"); + printf("Commands:\n"); + for (i=0; command[i].cmd; i++) + printf("\t%-10s %-8s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); +} + +int main(int argc, char *argv[], char *env[]) +{ + int opt, ctl, i, cmd=0; + char *dev; + + while ((opt=getopt(argc, argv,"ha")) != EOF) { + switch(opt) { + case 'a': + all = 1; + break; + case 'h': + usage(); + exit(0); + } + } + + /* Open HCI socket */ + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { + perror("Can't open HCI socket."); + exit(1); + } + + if (argc - optind < 1) { + print_dev_list(ctl, 0); + exit(0); + } + + dev = strdup(argv[optind]); + di.dev_id = atoi(argv[optind]+3); + optind++; + + if (ioctl(ctl, HCIGETDEVINFO, (void*)&di)) { + perror("Can't get device info"); + exit(1); + } + + while (optind < argc) { + for (i=0; command[i].cmd; i++) { + if (strncmp(command[i].cmd, argv[optind],4)) + continue; + + if (command[i].opt) + optind++; + + command[i].func(ctl, di.dev_id, argv[optind]); + cmd = 1; + break; + } + optind++; + } + + if (!cmd) + print_dev_info(ctl, &di); + + close(ctl); + return 0; +} diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c new file mode 100644 index 00000000..bee16df1 --- /dev/null +++ b/tools/hcisecfilter.c @@ -0,0 +1,79 @@ +#include +#include + +#include +#include +#include + +int main(void) +{ + uint32_t type_mask; + uint32_t event_mask[2]; + uint32_t ocf_mask[4]; + + // Packet types + memset((void *)&type_mask, 0, sizeof(type_mask)); + hci_set_bit(HCI_EVENT_PKT, &type_mask); + + printf("Type mask: { 0x%lx }\n", type_mask); + + // Events + memset((void *)event_mask, 0, sizeof(event_mask)); + hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); + hci_set_bit(EVT_INQUIRY_RESULT, event_mask); + + hci_set_bit(EVT_CONN_COMPLETE, event_mask); + hci_set_bit(EVT_CONN_REQUEST, event_mask); + hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); + + hci_set_bit(EVT_AUTH_COMPLETE, event_mask); + hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); + + hci_set_bit(EVT_CMD_COMPLETE, event_mask); + hci_set_bit(EVT_CMD_STATUS, event_mask); + + hci_set_bit(EVT_READ_REMOTE_FEATURES_COMPLETE, event_mask); + hci_set_bit(EVT_READ_REMOTE_VERSION_COMPLETE, event_mask); + hci_set_bit(EVT_REMOTE_NAME_REQ_COMPLETE, event_mask); + + printf("Event mask: { 0x%lx, 0x%lx }\n", event_mask[0], event_mask[1]); + + // OGF_LINK_CTL + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_INQUIRY, ocf_mask); + hci_set_bit(OCF_REMOTE_NAME_REQ, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_VERSION, ocf_mask); + + printf("OGF_LINK_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + // OGF_LINK_POLICY + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); + hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); + + printf("OGF_LINK_POLICY: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + // OGF_HOST_CTL + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_AUTH_ENABLE, ocf_mask); + hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); + hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); + + printf("OGF_HOST_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + // OGF_INFO_PARAM + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_LOCAL_VERSION, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_BUFFER_SIZE, ocf_mask); + hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); + hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); + + printf("OGF_INFO_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); +} diff --git a/tools/hcitool.c b/tools/hcitool.c new file mode 100644 index 00000000..4d6380fb --- /dev/null +++ b/tools/hcitool.c @@ -0,0 +1,368 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +extern int optind,opterr,optopt; +extern char *optarg; + +static int ctl; + +static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) +{ + struct hci_dev_list_req *dl; + struct hci_dev_req *dr; + int i; + + dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); + if (!dl) { + perror("Can't allocate memory"); + return -1; + } + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { + perror("Can't get device list"); + return -1; + } + + if (!dl->dev_num) + return -1; + + for (i=0; i < dl->dev_num; i++, dr++) { + if (dr->dev_opt & (1<dev_id, arg)) + return dr->dev_id; + } + } + return -1; +} + +static int other_bdaddr(int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + return 0; + return bacmp((bdaddr_t *)arg, &di.bdaddr); +} + +static int get_route(bdaddr_t *bdaddr) +{ + if (bdaddr) + return for_each_dev(HCI_UP, other_bdaddr, (long) bdaddr); + else + return for_each_dev(HCI_UP, NULL, 0); +} + +static int dev_info(int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + bdaddr_t bdaddr; + if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + return 0; + + baswap(&bdaddr, &di.bdaddr); + printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); + return 0; +} + +static int conn_list(int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int i; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + perror("Can't get connection list"); + exit(1); + } + + for (i=0; i < cl->conn_num; i++, ci++) { + bdaddr_t bdaddr; + baswap(&bdaddr, &ci->bdaddr); + printf("\t%s %s %s handle %d state %d lm %s\n", + ci->out ? "<" : ">", + ci->type == ACL_LINK ? "ACL" : "SCO", + batostr(&bdaddr), ci->handle, + ci->state, + hci_lmtostr(ci->link_mode)); + } + return 0; +} + +static int find_conn(int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int i; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + perror("Can't get connection list"); + exit(1); + } + + for (i=0; i < cl->conn_num; i++, ci++) + if (!bacmp((bdaddr_t *)arg, &ci->bdaddr)) + return 1; + return 0; +} + +static void cmd_dev(int dev_id, char **opt, int nopt) +{ + printf("Devices:\n"); + for_each_dev(HCI_UP, dev_info, 0); +} + +static void cmd_inq(int dev_id, char **opt, int nopt) +{ + inquiry_info *info; + int i, num_rsp = 0, length, flags; + bdaddr_t bdaddr; + + if (dev_id < 0) + dev_id = get_route(NULL); + + if (nopt >= 1) + length = atoi(opt[0]); + else + length = 10; /* 10 seconds */ + + flags = 0; + if (nopt >= 2) + flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + printf("Inquiring ...\n"); + info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); + + if (!info) { + perror("Inquiry failed."); + exit(1); + } + + for (i = 0; i < num_rsp; i++) { + baswap(&bdaddr, &(info+i)->bdaddr); + printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", + batostr(&bdaddr), (info+i)->clock_offset, + (info+i)->dev_class[2], + (info+i)->dev_class[1], + (info+i)->dev_class[0]); + } + free(info); +} + +static void cmd_con(int dev_id, char **opt, int nopt) +{ + printf("Connections:\n"); + if (dev_id < 0) + for_each_dev(HCI_UP, conn_list, 0); + else + conn_list(dev_id, 0); +} + +static void cmd_cc(int dev_id, char **opt, int nopt) +{ + bdaddr_t bdaddr; + int dd, ptype, role; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(opt[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (nopt >= 2) + hci_strtoptype(opt[1], &ptype); + else + ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; + + if (nopt >= 3) + role = !strncasecmp("m", opt[2], 1) ? 0 : 1; + else + role = 0; + + hci_create_connection(dd, &bdaddr, ptype, role, 1000); + + hci_close_dev(dd); +} + +static void cmd_dc(int dev_id, char **opt, int nopt) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int dd; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(*opt)); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + hci_disconnect(dd, cr->conn_info->handle, 0, 100); + + close(dd); + free(cr); +} + +struct { + char *cmd; + void (*func)(int dev_id, char **opt, int nopt); + char *opt; + char *doc; +} command[] = { + { "dev", cmd_dev, 0, "Display local devices" }, + { "inq", cmd_inq, "[lenght] [flush]", "Inquire remote devices" }, + { "con", cmd_con, 0, "Display active connections" }, + { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, + { "dc", cmd_dc, "", "Disconnect from remote device" }, + { NULL, NULL, 0} +}; + +static void usage(void) +{ + int i; + + printf("hcitool - HCI Tool\n"); + printf("Usage:\n" + "\thcitool [-i hciX] [command]\n"); + printf("Commands:\n"); + for (i=0; command[i].cmd; i++) + printf("\t%-4s %-20s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); +} + +int main(int argc, char *argv[], char *env[]) +{ + int opt, i, dev_id = -1; + char *dev; + + while ((opt=getopt(argc, argv, "i:h")) != EOF) { + switch(opt) { + case 'i': + dev = strdup(optarg); + dev_id = atoi(dev + 3); + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + if (argc - optind < 1) { + usage(); + exit(0); + } + + /* Open HCI socket */ + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { + perror("Can't open HCI socket."); + exit(1); + } + + for (i=0; command[i].cmd; i++) { + if (strncmp(command[i].cmd, argv[optind], 3)) + continue; + optind++; + command[i].func(dev_id, argv + optind, argc - optind); + break; + } + + close(ctl); + return 0; +} diff --git a/tools/l2ping.8 b/tools/l2ping.8 new file mode 100644 index 00000000..41becdba --- /dev/null +++ b/tools/l2ping.8 @@ -0,0 +1,49 @@ +.TH L2PING 8 "Jan 22 2002" BlueZ "Linux System Administration" +.SH NAME +l2ping \- Send L2CAP echo request and receive answer +.SH SYNOPSIS +.B l2ping +[ +.I -S source addr +] [ +.I -s size +] [ +.I -c count +] [ +.I -f +] < +.I bd_addr +> +.SH DESCRIPTION +.LP +L2ping sends a L2CAP echo request to the Bluetooth MAC address +.B bd_addr +given in dotted hex notation. +.SH OPTIONS +.TP +.I -S source addr +Select address to be used as source address for the request. +.TP +.I -s size +The +.B size +of the data packets to be sent. +.TP +.I -c count +Send +.B count +number of packets then exit. +.TP +.I -f +Kind of flood ping. Use with care! It reduces the delay time between packets +to 0. +.TP +.I bd_addr +The Bluetooth MAC address to be pinged in dotted hex notation like +.B 01:02:03:ab:cd:ef +or +.B 01:EF:cd:aB:02:03 +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Nils Faerber diff --git a/tools/l2ping.c b/tools/l2ping.c new file mode 100644 index 00000000..9bb8a4d6 --- /dev/null +++ b/tools/l2ping.c @@ -0,0 +1,251 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "bluetooth.h" +#include "l2cap.h" + +/* Defaults */ +bdaddr_t bdaddr; +int size = 20; +int ident = 200; +int delay = 1; +int count = -1; + +/* Stats */ +int sent_pkt = 0, recv_pkt = 0; + +static float tv2fl(struct timeval tv) +{ + return (float)(tv.tv_sec*1000.0) + (float)(tv.tv_usec/1000.0); +} + +static void stat(int sig) +{ + int loss = sent_pkt ? (float)((sent_pkt-recv_pkt)/(sent_pkt/100.0)) : 0; + printf("%d sent, %d received, %d%% loss\n", sent_pkt, recv_pkt, loss); + exit(0); +} + +static void ping(char *svr) +{ + struct sockaddr_l2 addr; + struct sigaction sa; + char buf[2048]; + int s, i, opt, lost; + uint8_t id; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = stat; + sigaction(SIGINT, &sa, NULL); + + if ((s = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { + perror("Can't create socket."); + exit(1); + } + + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + addr.l2_bdaddr = bdaddr; + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't bind socket."); + exit(1); + } + + baswap(&addr.l2_bdaddr, strtoba(svr)); + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror("Can't connect."); + exit(1); + } + + /* Get local address */ + opt = sizeof(addr); + if( getsockname(s, (struct sockaddr *)&addr, &opt) < 0 ) { + perror("Can't get local address."); + exit(1); + } + baswap(&bdaddr, &addr.l2_bdaddr); + + printf("Ping: %s from %s (data size %d) ...\n", svr, batostr(&bdaddr), size); + + /* Initialize buffer */ + for(i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) + buf[i]=(i%40)+'A'; + + id = ident; + + while( count == -1 || count-- > 0 ){ + struct timeval tv_send, tv_recv, tv_diff; + l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; + + /* Build command header */ + cmd->code = L2CAP_ECHO_REQ; + cmd->ident = id; + cmd->len = __cpu_to_le16(size); + + gettimeofday(&tv_send, NULL); + + /* Send Echo Request */ + if( send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0 ){ + perror("Send failed"); + exit(1); + } + + /* Wait for Echo Response */ + lost = 0; + while( 1 ) { + struct pollfd pf[1]; + register int err; + + pf[0].fd = s; pf[0].events = POLLIN; + if( (err = poll(pf, 1, 10*1000)) < 0 ) { + perror("Poll failed"); + exit(1); + } + + if( !err ){ + lost = 1; + break; + } + + if( (err = recv(s, buf, sizeof(buf), 0)) < 0 ) { + perror("Recv failed"); + exit(1); + } + + if( !err ){ + printf("Disconnected\n"); + exit(1); + } + + cmd->len = __le16_to_cpu(cmd->len); + + /* Check for our id */ + if( cmd->ident != id ) + continue; + + /* Check type */ + if( cmd->code == L2CAP_ECHO_RSP ) + break; + if( cmd->code == L2CAP_COMMAND_REJ ){ + printf("Peer doesn't support Echo packets\n"); + exit(1); + } + + } + sent_pkt++; + + if( !lost ){ + recv_pkt++; + + gettimeofday(&tv_recv, NULL); + timersub(&tv_recv, &tv_send, &tv_diff); + + printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id, tv2fl(tv_diff)); + + if( delay ) sleep(delay); + } else { + printf("no response from %s: id %d\n", svr, id); + } + + if( ++id > 254 ) id = ident; + } + stat(0); +} + +static void usage(void) +{ + printf("l2ping - L2CAP ping\n"); + printf("Usage:\n"); + printf("\tl2ping [-S source addr] [-s size] [-c count] [-f] \n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc, char *argv[]) +{ + register int opt; + + /* Default options */ + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt(argc,argv,"s:c:fS:")) != EOF) { + switch(opt) { + case 'f': + /* Kinda flood ping */ + delay = 0; + break; + + case 'c': + count = atoi(optarg); + break; + + case 's': + size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + default: + usage(); + exit(1); + } + } + + if (!(argc - optind)) { + usage(); + exit(1); + } + + ping(argv[optind]); + + return 0; +} diff --git a/tools/l2test.c b/tools/l2test.c new file mode 100644 index 00000000..be0b59e1 --- /dev/null +++ b/tools/l2test.c @@ -0,0 +1,493 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP, + CONNECT +}; + +unsigned char *buf; + +/* Default mtu */ +int imtu = 672; +int omtu = 0; + +/* Default data size */ +long data_size = 672; + +/* Default addr and psm */ +bdaddr_t bdaddr; +unsigned short psm = 10; + +int master = 0; +int auth = 0; +int encrypt = 0; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_l2 rem_addr, loc_addr; + struct l2cap_options opts; + int s, opt; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.l2_family = AF_BLUETOOTH; + loc_addr.l2_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Get default options */ + opt = sizeof(opts); + if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + /* Set new options */ + opts.omtu = omtu; + opts.imtu = imtu; + if( setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0 ) { + syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.l2_family = AF_BLUETOOTH; + baswap(&rem_addr.l2_bdaddr, strtoba(svr)); + rem_addr.l2_psm = htobs(psm); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + return -1; + } + + opt = sizeof(opts); + if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ + syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d]\n", + opts.imtu, opts.omtu, opts.flush_to); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_l2 loc_addr, rem_addr; + struct l2cap_options opts; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.l2_family = AF_BLUETOOTH; + loc_addr.l2_bdaddr = bdaddr; + loc_addr.l2_psm = htobs(psm); + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Get default options */ + opt = sizeof(opts); + if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { + syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Set new options */ + opts.imtu = imtu; + if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { + syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection on psm %d ...", psm); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + opt = sizeof(opts); + if( getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + baswap(&ba, &rem_addr.l2_bdaddr); + syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", + batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO,"Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO,"Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + uint32_t sq; + uint16_t l; + int i,r; + + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + + /* Check sequence */ + sq = btohl(*(uint32_t *)buf); + if (seq != sq) { + syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); + seq = sq; + } + seq++; + + /* Check length */ + l = btohs(*(uint16_t *)(buf+4)); + if (r != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + continue; + } + + /* Verify data */ + for (i=6; i < r; i++) { + if (buf[i] != 0x7f) + syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); + } + + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + } +} + +void send_mode(char *svr) +{ + uint32_t seq; + int s, i; + + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Sending ..."); + + for(i=6; i < data_size; i++) + buf[i]=0x7f; + + seq = 0; + while(1){ + *(uint32_t *)buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if( send(s, buf, data_size, 0) <= 0 ) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } +} + +void reconnect_mode(char *svr) +{ + while(1){ + int s; + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + exit(1); + } + close(s); + + usleep(10); + } +} + +void connect_mode(char *svr) +{ + int s; + if ((s = do_connect(svr)) < 0) { + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", + strerror(errno), errno); + exit(1); + } + sleep(99999999); +} + +void multy_connect_mode(char *svr) +{ + while(1){ + int i, s; + for(i=0; i<10; i++){ + if( fork() ) continue; + + /* Child */ + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + } + close(s); + exit(0); + } + sleep(19); + } +} + +void usage(void) +{ + printf("l2test - L2CAP testing\n" + "Usage:\n"); + printf("\tl2test [-b bytes] [-S bd_addr] [-P psm] [-I imtu] [-O omtu] [-M] [bd_addr]\n"); + printf("Modes:\n" + "\t-d dump (server)\n" + "\t-n silent connect (client)\n" + "\t-c reconnect (client)\n" + "\t-m multiple connects (client)\n" + "\t-r receive (server)\n" + "\t-s send (client)\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + struct sigaction sa; + int opt, mode = RECV; + + while ((opt=getopt(argc,argv,"rdscmnb:P:I:O:S:MAE")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + break; + + case 'n': + mode = CONNECT; + break; + + case 'm': + mode = MULTY; + break; + + case 'b': + data_size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + case 'P': + psm = atoi(optarg); + break; + + case 'I': + imtu = atoi(optarg); + break; + + case 'O': + omtu = atoi(optarg); + break; + + case 'M': + master = 1; + break; + + case 'A': + auth = 1; + break; + + case 'E': + encrypt = 1; + break; + + default: + usage(); + exit(1); + } + } + + if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + send_mode(argv[optind]); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multy_connect_mode(argv[optind]); + break; + + case CONNECT: + connect_mode(argv[optind]); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} diff --git a/tools/scotest.c b/tools/scotest.c new file mode 100644 index 00000000..4b56d081 --- /dev/null +++ b/tools/scotest.c @@ -0,0 +1,358 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP +}; + +unsigned char *buf; + +/* Default data size */ +long data_size = 672; + +bdaddr_t bdaddr; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_sco rem_addr, loc_addr; + int s; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.sco_family = AF_BLUETOOTH; + loc_addr.sco_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.sco_family = AF_BLUETOOTH; + baswap(&rem_addr.sco_bdaddr, strtoba(svr)); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + return -1; + } + + syslog(LOG_INFO, "Connected\n"); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_sco loc_addr, rem_addr; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.sco_family = AF_BLUETOOTH; + loc_addr.sco_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection ..."); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + baswap(&ba, &rem_addr.sco_bdaddr); + syslog(LOG_INFO, "Connect from %s\n", batostr(&ba)); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO,"Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO, "Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + int r; + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb",total, + tv2fl(tv_diff) / 60.0, + (float)( total / tv2fl(tv_diff) ) / 1024.0 ); + } +} + +void send_mode(char *svr) +{ + struct sco_options so; + uint32_t seq; + int s, i, opt; + + if ((s = do_connect(svr)) < 0) { + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", + strerror(errno), errno); + exit(1); + } + + opt = sizeof(so); + if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { + syslog(LOG_ERR, "Can't get SCO options. %s(%d)", + strerror(errno), errno); + exit(1); + } + + + syslog(LOG_INFO,"Sending ..."); + + for (i=6; i < so.mtu; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *)buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, so.mtu, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", + strerror(errno), errno); + exit(1); + } + usleep(1); + } +} + +void reconnect_mode(char *svr) +{ + while(1){ + int s; + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + exit(1); + } + close(s); + + sleep(5); + } +} + +void multy_connect_mode(char *svr) +{ + while(1){ + int i, s; + for(i=0; i<10; i++){ + if( fork() ) continue; + + /* Child */ + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + } + close(s); + exit(0); + } + sleep(19); + } +} + +void usage(void) +{ + printf("scotest - SCO testing\n" + "Usage:\n"); + printf("\tscotest [-b bytes] [bd_addr]\n"); + printf("Modes:\n" + "\t-d dump (server)\n" + "\t-c reconnect (client)\n" + "\t-m multiple connects (client)\n" + "\t-r receive (server)\n" + "\t-s send (client)\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + struct sigaction sa; + int opt, mode = RECV; + + while ((opt=getopt(argc,argv,"rdscmb:")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + break; + + case 'm': + mode = MULTY; + break; + + case 'b': + data_size = atoi(optarg); + break; + + default: + usage(); + exit(1); + } + } + + if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("scotest", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + send_mode(argv[optind]); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multy_connect_mode(argv[optind]); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} -- cgit From d5355b836015bbe6d4bb4b4229c2cc7c8d330d9d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 18 Mar 2002 19:36:42 +0000 Subject: Support for Inventel devices. --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index a4489019..cf882b92 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -544,6 +544,9 @@ struct uart_t uart[] = { /* Sphinx Electronics PICO Card */ { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + /* Inventel BlueBird Module */ + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { NULL, 0 } }; -- cgit From 50fc3563a46bb0b217b0b3ab941b8b7c012073e1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 18 Mar 2002 19:38:39 +0000 Subject: -a option fixes. Don't try to display name,etc of the down devices. --- tools/hciconfig.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3cbec922..25e91012 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -414,9 +414,11 @@ void print_dev_info(int ctl, struct hci_dev_info *di) print_link_policy(di); print_link_mode(di); - cmd_name(ctl, di->dev_id, NULL); - cmd_class(ctl, di->dev_id, NULL); - cmd_version(ctl, di->dev_id, NULL); + if (di->flags & (1 << HCI_UP)) { + cmd_name(ctl, di->dev_id, NULL); + cmd_class(ctl, di->dev_id, NULL); + cmd_version(ctl, di->dev_id, NULL); + } } printf("\n"); -- cgit From aba9dc216df7ddacbaa10d9e25c7aba05ab28afb Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 18 Mar 2002 19:39:45 +0000 Subject: Don't foget to compile l2test. l2test output nicefication :) --- tools/Makefile.am | 8 ++++++++ tools/Makefile.in | 12 ++++++++++-- tools/l2test.c | 28 +++++++++++++--------------- 3 files changed, 31 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index d3133e5f..53e3e21d 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -8,3 +8,11 @@ sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 + +CLEANFILES = l2test.o l2test + + +all-local: l2test + +l2test: l2test.o + $(LINK) l2test.o $(LDFLAGS) $(LIBS) diff --git a/tools/Makefile.in b/tools/Makefile.in index fe838a44..fae41912 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -87,6 +87,8 @@ sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 + +CLEANFILES = l2test.o l2test mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) @@ -368,7 +370,7 @@ install-am: all-am install: install-am uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS uninstall-man uninstall: uninstall-am -all-am: Makefile $(PROGRAMS) $(MANS) +all-am: Makefile $(PROGRAMS) $(MANS) all-local all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install @@ -380,6 +382,7 @@ installdirs: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) @@ -423,11 +426,16 @@ clean-tags maintainer-clean-tags distdir mostlyclean-depend \ distclean-depend clean-depend maintainer-clean-depend info-am info \ dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs \ +uninstall-am uninstall all-local all-redirect all-am all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean +all-local: l2test + +l2test: l2test.o + $(LINK) l2test.o $(LDFLAGS) $(LIBS) + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/tools/l2test.c b/tools/l2test.c index be0b59e1..e527fc60 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -292,10 +292,8 @@ void send_mode(char *svr) uint32_t seq; int s, i; - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + if( (s = do_connect(svr)) < 0 ) exit(1); - } syslog(LOG_INFO,"Sending ..."); @@ -318,10 +316,9 @@ void reconnect_mode(char *svr) { while(1){ int s; - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + if( (s = do_connect(svr)) < 0 ) exit(1); - } + close(s); usleep(10); @@ -331,11 +328,8 @@ void reconnect_mode(char *svr) void connect_mode(char *svr) { int s; - if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", - strerror(errno), errno); + if ((s = do_connect(svr)) < 0) exit(1); - } sleep(99999999); } @@ -347,9 +341,7 @@ void multy_connect_mode(char *svr) if( fork() ) continue; /* Child */ - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); - } + s = do_connect(svr); close(s); exit(0); } @@ -361,14 +353,20 @@ void usage(void) { printf("l2test - L2CAP testing\n" "Usage:\n"); - printf("\tl2test [-b bytes] [-S bd_addr] [-P psm] [-I imtu] [-O omtu] [-M] [bd_addr]\n"); + printf("\tl2test [options] [bdaddr]\n"); printf("Modes:\n" + "\t-r receive (server)\n" "\t-d dump (server)\n" "\t-n silent connect (client)\n" "\t-c reconnect (client)\n" "\t-m multiple connects (client)\n" - "\t-r receive (server)\n" "\t-s send (client)\n"); + printf("Options:\n" + "\t[-b bytes] [-S bdaddr] [-P psm]\n" + "\t[-I imtu] [-O omtu]\n" + "\t[-A] request authentication\n" + "\t[-E] request encryption\n" + "\t[-M] become master\n"); } extern int optind,opterr,optopt; -- cgit From eb965f147eaa15028d1abca397a6dc49c55d7868 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 19 Mar 2002 05:37:10 +0000 Subject: COM One PC Card support --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index cf882b92..a7f89e21 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -547,6 +547,9 @@ struct uart_t uart[] = { /* Inventel BlueBird Module */ { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + /* COM One Platinium Bluetooth PC Card */ + { "comone", 0xffff, 0x0101, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { NULL, 0 } }; -- cgit From 18527eedb9243335fb47c4297e97afcc8722c1c6 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 19 Mar 2002 18:06:30 +0000 Subject: Added inquiry params command --- tools/hciconfig.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 25e91012..779cef0f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -377,6 +376,73 @@ void cmd_version(int ctl, int hdev, char *opt) ver.manufacturer); } +void cmd_inq_parms(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + uint16_t window, interval; + write_inq_activity_cp cp; + + if (sscanf(opt,"%4u/%4u", &window, &interval)!=2) { + printf("Invalid argument format\n"); + exit(1); + } + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQ_ACTIVITY; + rq.cparam = &cp; + rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; + + cp.window = htobs(window); + cp.interval = htobs(interval); + + if (window < 0x12 || window > 0x1000) + printf("Warning: inquiry window out of range!\n"); + + if (interval < 0x12 || interval > 0x1000) + printf("Warning: inquiry interval out of range!\n"); + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't set inquiry parameters name on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint16_t window, interval; + read_inq_activity_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQ_ACTIVITY; + rq.rparam = &rp; + rq.rlen = READ_INQ_ACTIVITY_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read inquiry parameters on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read inquiry parameters on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + + window = btohs(rp.window); + interval = btohs(rp.interval); + printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", + interval, (float)interval * 0.625, window, (float)window * 0.625); + } +} + void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; @@ -447,6 +513,7 @@ struct { { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, + { "inqparms",cmd_inq_parms, "[int/win]","Get/Set device inquiry window and iterval" }, { "version", cmd_version, 0, "Display version information" }, { "features", cmd_features, 0,"Display device features" }, { NULL, NULL, 0} -- cgit From 9738e36a881497bc94d60b273f50dfa27b95030c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 21 Mar 2002 23:23:36 +0000 Subject: Support for company id and more readable version numbers. --- tools/hciconfig.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 779cef0f..3cae9792 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -370,10 +370,11 @@ void cmd_version(int ctl, int hdev, char *opt) } print_dev_hdr(&di); - printf( "\tHCI Ver: 0x%x HCI Rev: 0x%x LMP Ver: 0x%x LMP Subver: 0x%x\n" - "\tManufacturer: %d\n", - ver.hci_ver, ver.hci_rev, ver.lmp_ver, ver.lmp_subver, - ver.manufacturer); + printf( "\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n" + "\tManufacturer: %s (%d)\n", + hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, + lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, + bt_compidtostr(ver.manufacturer), ver.manufacturer); } void cmd_inq_parms(int ctl, int hdev, char *opt) -- cgit From 67230a9bb66546eedfe2a6587c125e3d3c23abf2 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:08:41 +0000 Subject: Fix compiler options and warnings --- tools/hciconfig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3cae9792..ad576c96 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -389,7 +389,7 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) memset(&rq, 0, sizeof(rq)); if (opt) { - uint16_t window, interval; + unsigned int window, interval; write_inq_activity_cp cp; if (sscanf(opt,"%4u/%4u", &window, &interval)!=2) { @@ -402,8 +402,8 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) rq.cparam = &cp; rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; - cp.window = htobs(window); - cp.interval = htobs(interval); + cp.window = htobs((uint16_t)window); + cp.interval = htobs((uint16_t)interval); if (window < 0x12 || window > 0x1000) printf("Warning: inquiry window out of range!\n"); -- cgit From 945768a289b2114b26c0139f8875d1471a300c6b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:47:05 +0000 Subject: connect and disconnect fixes. --- tools/hcitool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 4d6380fb..ed537031 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -219,7 +219,9 @@ static void cmd_con(int dev_id, char **opt, int nopt) static void cmd_cc(int dev_id, char **opt, int nopt) { bdaddr_t bdaddr; - int dd, ptype, role; + int ptype, dd; + uint16_t handle; + uint8_t role; if (nopt < 1) return; @@ -250,7 +252,7 @@ static void cmd_cc(int dev_id, char **opt, int nopt) else role = 0; - hci_create_connection(dd, &bdaddr, ptype, role, 1000); + hci_create_connection(dd, &bdaddr, ptype, role, 0, &handle, 1000); hci_close_dev(dd); } @@ -291,7 +293,7 @@ static void cmd_dc(int dev_id, char **opt, int nopt) exit(1); } - hci_disconnect(dd, cr->conn_info->handle, 0, 100); + hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); close(dd); free(cr); -- cgit From acc7ace68c67f8bd356aaab04ce7b29914962607 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:53:29 +0000 Subject: create_connection fix. --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index ed537031..aa6ac4ac 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -252,7 +252,7 @@ static void cmd_cc(int dev_id, char **opt, int nopt) else role = 0; - hci_create_connection(dd, &bdaddr, ptype, role, 0, &handle, 1000); + hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); hci_close_dev(dd); } -- cgit From 2f0421e884d8ef73ad71a5f6ffcb8416bc17ad1c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 26 Mar 2002 18:00:16 +0000 Subject: Support for HCISETACLMTU and HCISETSCOMTU ioctls. Minor cleanup. --- tools/hciconfig.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ad576c96..aca8a29d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -247,6 +247,42 @@ void cmd_lm(int ctl, int hdev, char *opt) } } +void cmd_aclmtu(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr = { dev_id: hdev }; + uint16_t mtu, mpkt; + + if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) + return; + + *((uint16_t *)&dr.dev_opt + 1) = mtu; + *((uint16_t *)&dr.dev_opt + 0) = mpkt; + + if (ioctl(ctl, HCISETACLMTU, (unsigned long)&dr) < 0) { + printf("Can't set ACL mtu on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_scomtu(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr = { dev_id: hdev }; + uint16_t mtu, mpkt; + + if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) + return; + + *((uint16_t *)&dr.dev_opt + 1) = mtu; + *((uint16_t *)&dr.dev_opt + 0) = mpkt; + + if (ioctl(ctl, HCISETSCOMTU, (unsigned long)&dr) < 0) { + printf("Can't set SCO mtu on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } +} + void cmd_features(int ctl, int hdev, char *opt) { print_dev_hdr(&di); @@ -392,7 +428,7 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) unsigned int window, interval; write_inq_activity_cp cp; - if (sscanf(opt,"%4u/%4u", &window, &interval)!=2) { + if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) { printf("Invalid argument format\n"); exit(1); } @@ -456,9 +492,9 @@ void print_dev_hdr(struct hci_dev_info *di) baswap(&bdaddr, &di->bdaddr); printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); - printf("\tBD Address: %s ACL MTU: %d:%d SCO: MTU %d:%d\n", - batostr(&bdaddr), di->acl_mtu, di->acl_max, - di->sco_mtu, di->sco_max); + printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", + batostr(&bdaddr), di->acl_mtu, di->acl_pkts, + di->sco_mtu, di->sco_pkts); } void print_dev_info(int ctl, struct hci_dev_info *di) @@ -514,7 +550,9 @@ struct { { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, - { "inqparms",cmd_inq_parms, "[int/win]","Get/Set device inquiry window and iterval" }, + { "inqparms",cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, + { "aclmtu", cmd_aclmtu, "","Set ACL MTU and number of packets" }, + { "scomtu", cmd_scomtu, "","Set SCO MTU and number of packets" }, { "version", cmd_version, 0, "Display version information" }, { "features", cmd_features, 0,"Display device features" }, { NULL, NULL, 0} -- cgit From 04c60e71e4b19ca904a5ea158a9e28297855350d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 27 Mar 2002 05:30:35 +0000 Subject: New test modes. --- tools/l2test.c | 63 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/l2test.c b/tools/l2test.c index e527fc60..56adad96 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -52,7 +52,9 @@ enum { RECONNECT, MULTY, DUMP, - CONNECT + CONNECT, + CRECV, + LSEND }; unsigned char *buf; @@ -287,13 +289,10 @@ void recv_mode(int s) } } -void send_mode(char *svr) +void send_mode(int s) { uint32_t seq; - int s, i; - - if( (s = do_connect(svr)) < 0 ) - exit(1); + int i; syslog(LOG_INFO,"Sending ..."); @@ -355,12 +354,15 @@ void usage(void) "Usage:\n"); printf("\tl2test [options] [bdaddr]\n"); printf("Modes:\n" - "\t-r receive (server)\n" - "\t-d dump (server)\n" - "\t-n silent connect (client)\n" - "\t-c reconnect (client)\n" - "\t-m multiple connects (client)\n" - "\t-s send (client)\n"); + "\t-r listen and receive\n" + "\t-w listen and send\n" + "\t-d listen and dump incomming data\n" + "\t-s connect and send\n" + "\t-u connect and receive\n" + "\t-n connect and be silent\n" + "\t-c connect, disconnect, connect, ...\n" + "\t-m multiple connects\n"); + printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" @@ -374,10 +376,12 @@ extern char *optarg; int main(int argc ,char *argv[]) { + int opt, mode, s, need_addr; struct sigaction sa; - int opt, mode = RECV; - while ((opt=getopt(argc,argv,"rdscmnb:P:I:O:S:MAE")) != EOF) { + mode = RECV; need_addr = 0; + + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -385,6 +389,16 @@ int main(int argc ,char *argv[]) case 's': mode = SEND; + need_addr = 1; + break; + + case 'w': + mode = LSEND; + break; + + case 'u': + mode = CRECV; + need_addr = 1; break; case 'd': @@ -393,14 +407,17 @@ int main(int argc ,char *argv[]) case 'c': mode = RECONNECT; + need_addr = 1; break; case 'n': mode = CONNECT; + need_addr = 1; break; case 'm': mode = MULTY; + need_addr = 1; break; case 'b': @@ -441,7 +458,7 @@ int main(int argc ,char *argv[]) } } - if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + if (need_addr && !(argc - optind)) { usage(); exit(1); } @@ -463,12 +480,26 @@ int main(int argc ,char *argv[]) do_listen(recv_mode); break; + case CRECV: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + recv_mode(s); + break; + case DUMP: do_listen(dump_mode); break; case SEND: - send_mode(argv[optind]); + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + send_mode(s); + break; + + case LSEND: + do_listen(send_mode); break; case RECONNECT: -- cgit From 46ee343d9d3f6fe1786089b87402a24fc460144c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 28 Mar 2002 01:32:42 +0000 Subject: Set default inquiry length to 10 seconds. --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index aa6ac4ac..bebdfbd4 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -182,7 +182,7 @@ static void cmd_inq(int dev_id, char **opt, int nopt) if (nopt >= 1) length = atoi(opt[0]); else - length = 10; /* 10 seconds */ + length = 8; /* ~ 10 seconds */ flags = 0; if (nopt >= 2) -- cgit From 4962b360716e1fd17a4f3cbddc7a305b4fd24668 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 9 Apr 2002 18:13:05 +0000 Subject: Added scan and rev commands. --- tools/hcitool.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index bebdfbd4..70e4b56d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -107,6 +107,55 @@ static int dev_info(int dev_id, long arg) return 0; } +static int rev_info(int dev_id, long arg) +{ + struct hci_version ver; + int dd; + + struct hci_request rq; + unsigned char buf[102]; + + + dd = hci_open_dev(dev_id); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", dev_id, strerror(errno), errno); + return -1; + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + printf("Can't read version info hci%d. %s(%d)\n", + dev_id, strerror(errno), errno); + return -1; + } + + printf("hci%d:", dev_id); + switch (ver.manufacturer) { + case 0: + memset(&rq, 0, sizeof(rq)); + rq.ogf = 0x3f; + rq.ocf = 0x000f; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\n Can't read revision info. %s(%d)\n", + strerror(errno), errno); + return -1; + } + + printf("%s\n", buf + 1); + break; + default: + printf("\n Manufacturer not supported\n"); + break; + } + printf("\n"); + + return 0; +} + static int conn_list(int dev_id, long arg) { struct hci_conn_list_req *cl; @@ -207,6 +256,54 @@ static void cmd_inq(int dev_id, char **opt, int nopt) free(info); } +static void cmd_scan(int dev_id, char **opt, int nopt) +{ + inquiry_info *info; + int i, num_rsp = 0, length, flags; + bdaddr_t bdaddr; + int dd; + char name[248]; + + if (dev_id < 0) + dev_id = get_route(NULL); + + if (nopt >= 1) + length = atoi(opt[0]); + else + length = 8; /* ~ 10 seconds */ + + flags = 0; + if (nopt >= 2) + flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + printf("Scanning ...\n"); + info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); + + if (!info) { + perror("Inquiry failed."); + exit(1); + } + + for (i = 0; i < num_rsp; i++) { + dd = hci_open_dev(dev_id); + memset(name, 0, sizeof(name)); + if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + close(dd); + baswap(&bdaddr, &(info+i)->bdaddr); + printf("\t%s\t%s\n", batostr(&bdaddr), name); + } + free(info); +} + +static void cmd_rev(int dev_id, char **opt, int nopt) +{ + if (dev_id < 0) + for_each_dev(HCI_UP, rev_info, 0); + else + rev_info(dev_id, 0); +} + static void cmd_con(int dev_id, char **opt, int nopt) { printf("Connections:\n"); @@ -305,8 +402,10 @@ struct { char *opt; char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "inq", cmd_inq, "[lenght] [flush]", "Inquire remote devices" }, + { "dev", cmd_dev, 0, "Display local devices" }, + { "rev", cmd_rev, 0, "Display revison information" }, + { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, + { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From c7073a0113d641580f49b171b8ece52f59f76e15 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 11 Apr 2002 16:58:54 +0000 Subject: Support for human readble display of device features. --- tools/hciconfig.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index aca8a29d..96d4c7b4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -91,11 +91,16 @@ void print_link_mode(struct hci_dev_info *di) printf("\tLink mode: %s\n", hci_lmtostr(di->link_mode)); } -void print_dev_features(struct hci_dev_info *di) +void print_dev_features(struct hci_dev_info *di, int format) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + if (!format) { + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", di->features[0], di->features[1], di->features[2], di->features[3] ); + } else { + printf("\tFeatures:\n%s\n", + lmp_featurestostr(di->features, "\t\t", 3)); + } } void cmd_rstat(int ctl, int hdev, char *opt) @@ -286,7 +291,7 @@ void cmd_scomtu(int ctl, int hdev, char *opt) void cmd_features(int ctl, int hdev, char *opt) { print_dev_hdr(&di); - print_dev_features(&di); + print_dev_features(&di, 1); } void cmd_name(int ctl, int hdev, char *opt) @@ -512,7 +517,7 @@ void print_dev_info(int ctl, struct hci_dev_info *di) st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); if (all) { - print_dev_features(di); + print_dev_features(di, 0); print_pkt_type(di); print_link_policy(di); print_link_mode(di); -- cgit From 8720383cae063462a97c39f7bccdc5340a58594a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 15 Apr 2002 16:53:32 +0000 Subject: Added "info" command --- tools/hcitool.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 70e4b56d..b30d93d1 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -296,6 +296,64 @@ static void cmd_scan(int dev_id, char **opt, int nopt) free(info); } +static void cmd_info(int dev_id, char **opt, int nopt) +{ + bdaddr_t bdaddr; + uint16_t handle; + int dd; + char name[248]; + unsigned char features[8]; + struct hci_version version; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(opt[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + printf("Requesting information ...\n"); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + printf("\tBD Address: %s\n", opt[0]); + + if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + close(dd); + exit(1); + } + + if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + printf("\tDevice Name: %s\n", name); + + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" + "\tManufacturer: %s (%d)\n", + lmp_vertostr(version.lmp_ver), version.lmp_ver, version.lmp_subver, + bt_compidtostr(version.manufacturer), version.manufacturer); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("\tFeatures:\n%s\n", + lmp_featurestostr(features, "\t\t", 3)); + } + + hci_disconnect(dd, handle, 0x13, 10000); + + close(dd); + +} + static void cmd_rev(int dev_id, char **opt, int nopt) { if (dev_id < 0) @@ -402,13 +460,14 @@ struct { char *opt; char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "rev", cmd_rev, 0, "Display revison information" }, - { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, - { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, - { "con", cmd_con, 0, "Display active connections" }, + { "dev", cmd_dev, 0, "Display local devices" }, + { "rev", cmd_rev, 0, "Display revison information" }, + { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, + { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, + { "info", cmd_info, "", "Get information from remote device" }, + { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, - { "dc", cmd_dc, "", "Disconnect from remote device" }, + { "dc", cmd_dc, "", "Disconnect from remote device" }, { NULL, NULL, 0} }; -- cgit From c4f18f46436d80592fa3bd500b74737a5e349a56 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 01:26:12 +0000 Subject: Simplified 'cmd' command --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index b30d93d1..b5256300 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -32,12 +32,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -48,6 +50,8 @@ extern char *optarg; static int ctl; +static void usage(void); + static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) { struct hci_dev_list_req *dl; @@ -213,6 +217,23 @@ static int find_conn(int dev_id, long arg) return 0; } +static void hex_dump(char *pref, int width, unsigned char *buf, int len) +{ + register int i,n; + + for (i=0, n=1; i 0x3f) || (htobs(ocf) > 0x3ff)) { + usage(); + return; + } + + for (i = 2, len = 0; i < nopt && len < sizeof(buf); i++, len++) + *ptr++ = (uint8_t) strtol(opt[i], NULL, 16); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + /* Setup filter */ + hci_filter_clear(&flt); + hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_all_events(&flt); + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + perror("HCI filter setup failed"); + exit(EXIT_FAILURE); + } + + printf("< HCI Command: OGF 0x%02x, OCF 0x%04x, plen %d\n", ogf, ocf, len); + hex_dump(" ", 20, buf, len); + fflush(stdout); + + if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { + perror("Send failed"); + exit(EXIT_FAILURE); + } + + len = read(dd, buf, sizeof(buf)); + if (len < 0) { + perror("Read failed"); + exit(EXIT_FAILURE); + } + + hdr = (void *)(buf + 1); + ptr = buf + (1 + HCI_EVENT_HDR_SIZE); + len -= (1 + HCI_EVENT_HDR_SIZE); + + printf("> HCI Event: 0x%02x plen %d:\n", hdr->evt, hdr->plen); + hex_dump(" ", 20, ptr, len); + fflush(stdout); + + return; +} + static void cmd_rev(int dev_id, char **opt, int nopt) { if (dev_id < 0) @@ -465,6 +555,7 @@ struct { { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "info", cmd_info, "", "Get information from remote device" }, + { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From ba150fb166ed968105942dd97992be83afd4af50 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 16:45:12 +0000 Subject: cmd_cmd cleanup --- tools/hcitool.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index b5256300..96448533 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -156,7 +156,6 @@ static int rev_info(int dev_id, long arg) break; } printf("\n"); - return 0; } @@ -185,8 +184,7 @@ static int conn_list(int dev_id, long arg) printf("\t%s %s %s handle %d state %d lm %s\n", ci->out ? "<" : ">", ci->type == ACL_LINK ? "ACL" : "SCO", - batostr(&bdaddr), ci->handle, - ci->state, + batostr(&bdaddr), ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } return 0; @@ -237,7 +235,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) static void cmd_dev(int dev_id, char **opt, int nopt) { printf("Devices:\n"); - for_each_dev(HCI_UP, dev_info, 0); + for_each_dev(HCI_UP, dev_info, 0); } static void cmd_inq(int dev_id, char **opt, int nopt) @@ -282,8 +280,8 @@ static void cmd_scan(int dev_id, char **opt, int nopt) inquiry_info *info; int i, num_rsp = 0, length, flags; bdaddr_t bdaddr; - int dd; char name[248]; + int dd; if (dev_id < 0) dev_id = get_route(NULL); @@ -372,7 +370,6 @@ static void cmd_info(int dev_id, char **opt, int nopt) hci_disconnect(dd, handle, 0x13, 10000); close(dd); - } static void cmd_cmd(int dev_id, char **opt, int nopt) @@ -380,9 +377,9 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; + int i, len, dd; uint16_t ocf; uint8_t ogf; - int i, len, dd; if (nopt < 2) { usage(); @@ -395,7 +392,7 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) errno = 0; ogf = strtol(opt[0], NULL, 16); ocf = strtol(opt[1], NULL, 16); - if (errno == ERANGE || (ogf > 0x3f) || (htobs(ocf) > 0x3ff)) { + if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) { usage(); return; } @@ -418,9 +415,8 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) exit(EXIT_FAILURE); } - printf("< HCI Command: OGF 0x%02x, OCF 0x%04x, plen %d\n", ogf, ocf, len); - hex_dump(" ", 20, buf, len); - fflush(stdout); + printf("< HCI Command: ogf 0x%02x, ocf 0x%04x, plen %d\n", ogf, ocf, len); + hex_dump(" ", 20, buf, len); fflush(stdout); if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); @@ -437,10 +433,10 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); - printf("> HCI Event: 0x%02x plen %d:\n", hdr->evt, hdr->plen); - hex_dump(" ", 20, ptr, len); - fflush(stdout); + printf("> HCI Event: 0x%02x plen %d\n", hdr->evt, hdr->plen); + hex_dump(" ", 20, ptr, len); fflush(stdout); + hci_close_dev(dd); return; } @@ -555,7 +551,7 @@ struct { { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "info", cmd_info, "", "Get information from remote device" }, - { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, + { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From 996b96baf78a1e77e94c08f391e00a8bc7822955 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 20:04:13 +0000 Subject: New improved argument processing. --- tools/hcitool.c | 397 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 313 insertions(+), 84 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 96448533..35509f22 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,8 @@ extern int optind,opterr,optopt; extern char *optarg; +#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) + static int ctl; static void usage(void); @@ -232,29 +235,79 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) printf("\n"); } -static void cmd_dev(int dev_id, char **opt, int nopt) +/* Display local devices */ + +static struct option dev_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *dev_help = + "Usage:\n" + "\tdev\n"; + +static void cmd_dev(int dev_id, int argc, char **argv) { + int opt; + for_each_opt(opt, dev_options, NULL) { + switch(opt) { + default: + printf(dev_help); + return; + } + } + printf("Devices:\n"); for_each_dev(HCI_UP, dev_info, 0); } -static void cmd_inq(int dev_id, char **opt, int nopt) +/* Inquiry */ + +static struct option inq_options[] = { + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, + {0, 0, 0, 0} +}; + +static char *inq_help = + "Usage:\n" + "\tinq [--length=N] [--numrsp=N] [--flush]\n"; + +static void cmd_inq(int dev_id, int argc, char **argv) { + int num_rsp, length, flags; inquiry_info *info; - int i, num_rsp = 0, length, flags; bdaddr_t bdaddr; - - if (dev_id < 0) - dev_id = get_route(NULL); - - if (nopt >= 1) - length = atoi(opt[0]); - else - length = 8; /* ~ 10 seconds */ + int i, opt; + length = 8; /* ~10 seconds */ + num_rsp = 10; flags = 0; - if (nopt >= 2) - flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + for_each_opt(opt, inq_options, NULL) { + switch(opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; + + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(inq_help); + return; + } + } + + if (dev_id < 0) + dev_id = get_route(NULL); printf("Inquiring ...\n"); info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); @@ -275,25 +328,54 @@ static void cmd_inq(int dev_id, char **opt, int nopt) free(info); } -static void cmd_scan(int dev_id, char **opt, int nopt) +/* Device scanning */ + +static struct option scan_options[] = { + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, + {0, 0, 0, 0} +}; + +static char *scan_help = + "Usage:\n" + "\tscan [--length=N] [--numrsp=N] [--flush]\n"; + +static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info; - int i, num_rsp = 0, length, flags; + int num_rsp, length, flags; bdaddr_t bdaddr; char name[248]; - int dd; + int i, opt, dd; - if (dev_id < 0) - dev_id = get_route(NULL); + length = 8; /* ~10 seconds */ + num_rsp = 10; + flags = 0; - if (nopt >= 1) - length = atoi(opt[0]); - else - length = 8; /* ~ 10 seconds */ + for_each_opt(opt, scan_options, NULL) { + switch(opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; - flags = 0; - if (nopt >= 2) - flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(scan_help); + return; + } + } + + if (dev_id < 0) + dev_id = get_route(NULL); printf("Scanning ...\n"); info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); @@ -315,19 +397,42 @@ static void cmd_scan(int dev_id, char **opt, int nopt) free(info); } -static void cmd_info(int dev_id, char **opt, int nopt) +/* Info about remote device */ + +static struct option info_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *info_help = + "Usage:\n" + "\tinfo \n"; + +static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; - int dd; char name[248]; unsigned char features[8]; struct hci_version version; + int opt, dd; + + for_each_opt(opt, info_options, NULL) { + switch(opt) { + default: + printf(info_help); + return; + } + } + argc -= optind; + argv += optind; - if (nopt < 1) + if (argc < 1) { + printf(info_help); return; + } - baswap(&bdaddr, strtoba(opt[0])); + baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { dev_id = get_route(&bdaddr); @@ -345,7 +450,7 @@ static void cmd_info(int dev_id, char **opt, int nopt) exit(1); } - printf("\tBD Address: %s\n", opt[0]); + printf("\tBD Address: %s\n", argv[0]); if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { close(dd); @@ -372,17 +477,40 @@ static void cmd_info(int dev_id, char **opt, int nopt) close(dd); } -static void cmd_cmd(int dev_id, char **opt, int nopt) +/* Send arbitrary HCI commands */ + +static struct option cmd_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *cmd_help = + "Usage:\n" + "\tcmd [parameters]\n" + "Example:\n" + "\tcmd 0x03 0x0013 0x41 0x42 0x43 0x44\n"; + +static void cmd_cmd(int dev_id, int argc, char **argv) { char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; - int i, len, dd; + int i, opt, len, dd; uint16_t ocf; uint8_t ogf; - if (nopt < 2) { - usage(); + for_each_opt(opt, cmd_options, NULL) { + switch(opt) { + default: + printf(cmd_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(cmd_help); return; } @@ -390,15 +518,15 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) dev_id = get_route(NULL); errno = 0; - ogf = strtol(opt[0], NULL, 16); - ocf = strtol(opt[1], NULL, 16); + ogf = strtol(argv[0], NULL, 16); + ocf = strtol(argv[1], NULL, 16); if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) { - usage(); + printf(cmd_help); return; } - for (i = 2, len = 0; i < nopt && len < sizeof(buf); i++, len++) - *ptr++ = (uint8_t) strtol(opt[i], NULL, 16); + for (i = 2, len = 0; i < argc && len < sizeof(buf); i++, len++) + *ptr++ = (uint8_t) strtol(argv[i], NULL, 16); dd = hci_open_dev(dev_id); if (dd < 0) { @@ -440,16 +568,58 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) return; } -static void cmd_rev(int dev_id, char **opt, int nopt) +/* Display revision info */ + +static struct option rev_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *rev_help = + "Usage:\n" + "\trev\n"; + +static void cmd_rev(int dev_id, int argc, char **argv) { + int opt; + + for_each_opt(opt, rev_options, NULL) { + switch(opt) { + default: + printf(rev_help); + return; + } + } + if (dev_id < 0) for_each_dev(HCI_UP, rev_info, 0); else rev_info(dev_id, 0); } -static void cmd_con(int dev_id, char **opt, int nopt) +/* Display active connections */ + +static struct option con_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *con_help = + "Usage:\n" + "\tcon\n"; + +static void cmd_con(int dev_id, int argc, char **argv) { + int opt; + + for_each_opt(opt, con_options, NULL) { + switch(opt) { + default: + printf(con_help); + return; + } + } + printf("Connections:\n"); if (dev_id < 0) for_each_dev(HCI_UP, conn_list, 0); @@ -457,17 +627,56 @@ static void cmd_con(int dev_id, char **opt, int nopt) conn_list(dev_id, 0); } -static void cmd_cc(int dev_id, char **opt, int nopt) +/* Create connection */ + +static struct option cc_options[] = { + {"help", 0,0, 'h'}, + {"role", 1,0, 'r'}, + {"ptype", 1,0, 'p'}, + {0, 0, 0, 0} +}; + +static char *cc_help = + "Usage:\n" + "\tcc [--role=m|s] [--ptype=pkt_types] \n" + "Example:\n" + "\tcc --ptype=dm1,dh3,dh5 01:02:03:04:05:06\n" + "\tcc --role=m 01:02:03:04:05:06\n"; + +static void cmd_cc(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; - int ptype, dd; + int opt, ptype, dd; uint16_t handle; uint8_t role; - if (nopt < 1) + role = 0; + ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; + + for_each_opt(opt, cc_options, NULL) { + switch(opt) { + case 'p': + hci_strtoptype(optarg, &ptype); + break; + + case 'r': + role = optarg[0] == 'm' ? 0 : 1; + break; + + default: + printf(cc_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(cc_help); return; + } - baswap(&bdaddr, strtoba(opt[0])); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = get_route(&bdaddr); @@ -483,31 +692,43 @@ static void cmd_cc(int dev_id, char **opt, int nopt) exit(1); } - if (nopt >= 2) - hci_strtoptype(opt[1], &ptype); - else - ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; - - if (nopt >= 3) - role = !strncasecmp("m", opt[2], 1) ? 0 : 1; - else - role = 0; - hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); - hci_close_dev(dd); } -static void cmd_dc(int dev_id, char **opt, int nopt) +/* Close connection */ + +static struct option dc_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *dc_help = + "Usage:\n" + "\tdc \n"; + +static void cmd_dc(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; - int dd; + int opt, dd; + + for_each_opt(opt, dc_options, NULL) { + switch(opt) { + default: + printf(dc_help); + return; + } + } + argc -= optind; + argv += optind; - if (nopt < 1) + if (argc < 1) { + printf(dc_help); return; + } - baswap(&bdaddr, strtoba(*opt)); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -542,19 +763,18 @@ static void cmd_dc(int dev_id, char **opt, int nopt) struct { char *cmd; - void (*func)(int dev_id, char **opt, int nopt); - char *opt; + void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "rev", cmd_rev, 0, "Display revison information" }, - { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, - { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, - { "info", cmd_info, "", "Get information from remote device" }, - { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, - { "con", cmd_con, 0, "Display active connections" }, - { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, - { "dc", cmd_dc, "", "Disconnect from remote device" }, + { "dev", cmd_dev, "Display local devices" }, + { "rev", cmd_rev, "Display revison information" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, { NULL, NULL, 0} }; @@ -564,24 +784,30 @@ static void usage(void) printf("hcitool - HCI Tool\n"); printf("Usage:\n" - "\thcitool [-i hciX] [command]\n"); + "\thcitool [options] [command parameters]\n"); + printf("Options:\n" + "\t--help\tDisplay help\n" + "\t-i dev\tHCI device\n"); printf("Commands:\n"); for (i=0; command[i].cmd; i++) - printf("\t%-4s %-20s\t%s\n", command[i].cmd, - command[i].opt ? command[i].opt : " ", + printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); } -int main(int argc, char *argv[], char *env[]) +static struct option main_options[] = { + {"help", 0,0, 'h'}, + {"device", 1,0, 'i'}, + {0, 0, 0, 0} +}; + +int main(int argc, char **argv) { int opt, i, dev_id = -1; - char *dev; - while ((opt=getopt(argc, argv, "i:h")) != EOF) { + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { case 'i': - dev = strdup(optarg); - dev_id = atoi(dev + 3); + dev_id = atoi(optarg + 3); break; case 'h': @@ -591,22 +817,25 @@ int main(int argc, char *argv[], char *env[]) } } - if (argc - optind < 1) { + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { usage(); exit(0); } - /* Open HCI socket */ + /* Open HCI socket */ if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { perror("Can't open HCI socket."); exit(1); } for (i=0; command[i].cmd; i++) { - if (strncmp(command[i].cmd, argv[optind], 3)) + if (strncmp(command[i].cmd, argv[0], 3)) continue; - optind++; - command[i].func(dev_id, argv + optind, argc - optind); + command[i].func(dev_id, argc, argv); break; } -- cgit From 98f6f92be002a098fb4f3b773939ab7c94834a0d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 22 Apr 2002 20:16:27 +0000 Subject: Display feature bytes in hex --- tools/hciconfig.c | 4 +++- tools/hcitool.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 96d4c7b4..21f7bc1c 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -98,7 +98,9 @@ void print_dev_features(struct hci_dev_info *di, int format) di->features[0], di->features[1], di->features[2], di->features[3] ); } else { - printf("\tFeatures:\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + di->features[0], di->features[1], + di->features[2], di->features[3], lmp_featurestostr(di->features, "\t\t", 3)); } } diff --git a/tools/hcitool.c b/tools/hcitool.c index 35509f22..06c426ca 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -468,7 +468,8 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("\tFeatures:\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + features[0], features[1], features[2], features[3], lmp_featurestostr(features, "\t\t", 3)); } -- cgit From d65d0510cd20a55a08b64f476714b229c5436396 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 22 Apr 2002 20:43:10 +0000 Subject: Argument parsing fixes --- tools/hciconfig.c | 38 +++++++++++++++++++++++++------------- tools/hcitool.c | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 21f7bc1c..4b4844ff 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -580,55 +581,66 @@ void usage(void) command[i].doc); } -int main(int argc, char *argv[], char *env[]) +static struct option main_options[] = { + {"help", 0,0, 'h'}, + {"all", 0,0, 'a'}, + {0, 0, 0, 0} +}; + +int main(int argc, char **argv, char **env) { int opt, ctl, i, cmd=0; - char *dev; - while ((opt=getopt(argc, argv,"ha")) != EOF) { + while ((opt=getopt_long(argc, argv, "ah", main_options, NULL)) != -1) { switch(opt) { case 'a': all = 1; break; + case 'h': + default: usage(); exit(0); } } + argc -= optind; + argv += optind; + optind = 0; + /* Open HCI socket */ if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { perror("Can't open HCI socket."); exit(1); } - if (argc - optind < 1) { + if (argc < 1) { print_dev_list(ctl, 0); exit(0); } - dev = strdup(argv[optind]); - di.dev_id = atoi(argv[optind]+3); - optind++; + di.dev_id = atoi(argv[0] + 3); + argc--; argv++; if (ioctl(ctl, HCIGETDEVINFO, (void*)&di)) { perror("Can't get device info"); exit(1); } - while (optind < argc) { + while (argc > 0) { for (i=0; command[i].cmd; i++) { - if (strncmp(command[i].cmd, argv[optind],4)) + if (strncmp(command[i].cmd, *argv, 4)) continue; - if (command[i].opt) - optind++; + if (command[i].opt) { + argc--; argv++; + } - command[i].func(ctl, di.dev_id, argv[optind]); + command[i].func(ctl, di.dev_id, *argv); cmd = 1; break; } - optind++; + argc--; argv++; } if (!cmd) diff --git a/tools/hcitool.c b/tools/hcitool.c index 06c426ca..8ec564d7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -783,7 +783,7 @@ static void usage(void) { int i; - printf("hcitool - HCI Tool\n"); + printf("hcitool - HCI Tool ver %s\n", VERSION); printf("Usage:\n" "\thcitool [options] [command parameters]\n"); printf("Options:\n" -- cgit From 095e2ef25275e4682b9c1a51d6f9f233f0360d18 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 2 May 2002 20:54:47 +0000 Subject: Added "name" command. --- tools/hcitool.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8ec564d7..f6a98610 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -397,6 +397,61 @@ static void cmd_scan(int dev_id, int argc, char **argv) free(info); } +/* Remote name */ + +static struct option name_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *name_help = + "Usage:\n" + "\tname \n"; + +static void cmd_name(int dev_id, int argc, char **argv) +{ + bdaddr_t bdaddr; + char name[248]; + int opt, dd; + + for_each_opt(opt, name_options, NULL) { + switch(opt) { + default: + printf(name_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(name_help); + return; + } + + baswap(&bdaddr, strtoba(argv[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + printf("%s\n", name); + + close(dd); + +} + /* Info about remote device */ static struct option info_options[] = { @@ -771,6 +826,7 @@ struct { { "rev", cmd_rev, "Display revison information" }, { "inq", cmd_inq, "Inquire remote devices" }, { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, -- cgit From 6446efe312e0410efc4c45dc68f5d980755f0666 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 8 May 2002 17:00:05 +0000 Subject: Use hci_test_bit instead of (1<flags & (1 << HCI_UP)) { + if (hci_test_bit(HCI_UP, &di->flags)) { cmd_name(ctl, di->dev_id, NULL); cmd_class(ctl, di->dev_id, NULL); cmd_version(ctl, di->dev_id, NULL); diff --git a/tools/hcitool.c b/tools/hcitool.c index f6a98610..68d4aa7a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -78,7 +78,7 @@ static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) return -1; for (i=0; i < dl->dev_num; i++, dr++) { - if (dr->dev_opt & (1<dev_opt)) { if (!func || func(dr->dev_id, arg)) return dr->dev_id; } -- cgit From c1df5fbb4f48cfdd3cd4a566a0836889aa6e8458 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 8 May 2002 17:41:10 +0000 Subject: RSSI support. --- tools/hcitool.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 68d4aa7a..5ac90657 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -817,6 +817,91 @@ static void cmd_dc(int dev_id, int argc, char **argv) free(cr); } +/* Read RSSI */ + +static struct option rssi_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *rssi_help = + "Usage:\n" + "\trssi \n"; + +static void cmd_rssi(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_rssi_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, rssi_options, NULL) { + switch(opt) { + default: + printf(rssi_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(rssi_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_RSSI_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + printf("Can't read RSSI hci%d. %s(%d)\n", + dd, strerror(errno), errno); + exit(1); + } + + if (rp.status) { + printf("Read RSSI on hci%d returned (error) status 0x%2.2X\n", + dd, rp.status); + exit(1); + } + printf( "\tRSSI return value: %d\n", rp.rssi); + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -832,6 +917,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, { NULL, NULL, 0} }; -- cgit From 7ef138d4d8d5042f9feaae9fb3bb3a4a947d8582 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 13 May 2002 18:45:11 +0000 Subject: make file cleanup --- tools/Makefile.am | 8 +------ tools/Makefile.in | 67 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 28 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 53e3e21d..f8312834 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -9,10 +9,4 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -CLEANFILES = l2test.o l2test - - -all-local: l2test - -l2test: l2test.o - $(LINK) l2test.o $(LDFLAGS) $(LIBS) +noinst_PROGRAMS = l2test scotest diff --git a/tools/Makefile.in b/tools/Makefile.in index fae41912..9070c880 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -88,10 +88,10 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -CLEANFILES = l2test.o l2test +noinst_PROGRAMS = l2test scotest mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = -PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) @@ -108,6 +108,16 @@ l2ping_OBJECTS = l2ping.o l2ping_LDADD = $(LDADD) l2ping_DEPENDENCIES = l2ping_LDFLAGS = +l2test_SOURCES = l2test.c +l2test_OBJECTS = l2test.o +l2test_LDADD = $(LDADD) +l2test_DEPENDENCIES = +l2test_LDFLAGS = +scotest_SOURCES = scotest.c +scotest_OBJECTS = scotest.o +scotest_LDADD = $(LDADD) +scotest_DEPENDENCIES = +scotest_LDFLAGS = hciattach_SOURCES = hciattach.c hciattach_OBJECTS = hciattach.o hciattach_LDADD = $(LDADD) @@ -134,9 +144,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = gtar GZIP_ENV = --best DEP_FILES = .deps/hciattach.P .deps/hciconfig.P .deps/hcitool.P \ -.deps/l2ping.P -SOURCES = hcitool.c l2ping.c hciattach.c hciconfig.c -OBJECTS = hcitool.o l2ping.o hciattach.o hciconfig.o +.deps/l2ping.P .deps/l2test.P .deps/scotest.P +SOURCES = hcitool.c l2ping.c l2test.c scotest.c hciattach.c hciconfig.c +OBJECTS = hcitool.o l2ping.o l2test.o scotest.o hciattach.o hciconfig.o all: all-redirect .SUFFIXES: @@ -174,6 +184,15 @@ uninstall-binPROGRAMS: rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + mostlyclean-sbinPROGRAMS: clean-sbinPROGRAMS: @@ -223,6 +242,14 @@ l2ping: $(l2ping_OBJECTS) $(l2ping_DEPENDENCIES) @rm -f l2ping $(LINK) $(l2ping_LDFLAGS) $(l2ping_OBJECTS) $(l2ping_LDADD) $(LIBS) +l2test: $(l2test_OBJECTS) $(l2test_DEPENDENCIES) + @rm -f l2test + $(LINK) $(l2test_LDFLAGS) $(l2test_OBJECTS) $(l2test_LDADD) $(LIBS) + +scotest: $(scotest_OBJECTS) $(scotest_DEPENDENCIES) + @rm -f scotest + $(LINK) $(scotest_LDFLAGS) $(scotest_OBJECTS) $(scotest_LDADD) $(LIBS) + hciattach: $(hciattach_OBJECTS) $(hciattach_DEPENDENCIES) @rm -f hciattach $(LINK) $(hciattach_LDFLAGS) $(hciattach_OBJECTS) $(hciattach_LDADD) $(LIBS) @@ -370,7 +397,7 @@ install-am: all-am install: install-am uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS uninstall-man uninstall: uninstall-am -all-am: Makefile $(PROGRAMS) $(MANS) all-local +all-am: Makefile $(PROGRAMS) $(MANS) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install @@ -382,31 +409,32 @@ installdirs: mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: -mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-sbinPROGRAMS \ - mostlyclean-compile mostlyclean-tags mostlyclean-depend \ - mostlyclean-generic +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \ + mostlyclean-sbinPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic mostlyclean: mostlyclean-am -clean-am: clean-binPROGRAMS clean-sbinPROGRAMS clean-compile clean-tags \ - clean-depend clean-generic mostlyclean-am +clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-sbinPROGRAMS \ + clean-compile clean-tags clean-depend clean-generic \ + mostlyclean-am clean: clean-am -distclean-am: distclean-binPROGRAMS distclean-sbinPROGRAMS \ - distclean-compile distclean-tags distclean-depend \ - distclean-generic clean-am +distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \ + distclean-sbinPROGRAMS distclean-compile distclean-tags \ + distclean-depend distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-noinstPROGRAMS \ maintainer-clean-sbinPROGRAMS maintainer-clean-compile \ maintainer-clean-tags maintainer-clean-depend \ maintainer-clean-generic distclean-am @@ -417,6 +445,8 @@ maintainer-clean: maintainer-clean-am .PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \ maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ install-sbinPROGRAMS mostlyclean-compile distclean-compile \ @@ -426,16 +456,11 @@ clean-tags maintainer-clean-tags distdir mostlyclean-depend \ distclean-depend clean-depend maintainer-clean-depend info-am info \ dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-local all-redirect all-am all installdirs \ +uninstall-am uninstall all-redirect all-am all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean -all-local: l2test - -l2test: l2test.o - $(LINK) l2test.o $(LDFLAGS) $(LIBS) - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: -- cgit From 8f32a0237d9eae5ab56916424bb1e7580be28db1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 13 May 2002 18:55:25 +0000 Subject: usage clarification --- tools/hcitool.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 5ac90657..67cd7987 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -935,6 +935,9 @@ static void usage(void) for (i=0; command[i].cmd; i++) printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); + printf("\n" + "For more information on the usage of each command use:\n" + "\thcitool --help\n" ); } static struct option main_options[] = { -- cgit From c7057958d5fbf7fa82745b5ab75844723def24ab Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 17 May 2002 01:01:13 +0000 Subject: Fix "make dist". --- tools/Makefile.am | 2 ++ tools/Makefile.in | 2 ++ 2 files changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index f8312834..c1a82d7f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -10,3 +10,5 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 noinst_PROGRAMS = l2test scotest + +EXTRA_DIST = $(man_MANS) diff --git a/tools/Makefile.in b/tools/Makefile.in index 9070c880..794cfeca 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -89,6 +89,8 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 noinst_PROGRAMS = l2test scotest + +EXTRA_DIST = $(man_MANS) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) -- cgit From b9d072d8c187426e925356dc5fdc143f6a19d4bb Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 18 May 2002 00:50:26 +0000 Subject: Change connection packet type support. --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 67cd7987..7f7cf1de 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -878,6 +878,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; @@ -886,22 +887,101 @@ static void cmd_rssi(int dev_id, int argc, char **argv) rq.rlen = READ_RSSI_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { - printf("Can't read RSSI hci%d. %s(%d)\n", - dd, strerror(errno), errno); + perror("Read RSSI failed"); exit(1); } if (rp.status) { - printf("Read RSSI on hci%d returned (error) status 0x%2.2X\n", - dd, rp.status); + printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); exit(1); } - printf( "\tRSSI return value: %d\n", rp.rssi); + printf("\tRSSI return value: %d\n", rp.rssi); close(dd); free(cr); } +/* Set connection packet type */ + +static struct option cpt_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *cpt_help = + "Usage:\n" + "\tcpt \n"; + +static void cmd_cpt(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + set_conn_ptype_cp cp; + bdaddr_t bdaddr; + int opt, dd, ptype; + + for_each_opt(opt, cpt_options, NULL) { + switch(opt) { + default: + printf(cpt_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(cpt_help); + return; + } + + str2ba(argv[0], &bdaddr); + hci_strtoptype(argv[1], &ptype); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + cp.pkt_type = ptype; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; + rq.cparam = &cp; + rq.clen = SET_CONN_PTYPE_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("Packet type change failed"); + exit(1); + } + + close(dd); + free(cr); +} + + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -917,6 +997,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { NULL, NULL, 0} }; -- cgit From d8ab2999e595a6cf7e853c881d1716c7262fe74a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 23 May 2002 20:56:51 +0000 Subject: help output improvements --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 7f7cf1de..8ce64ed6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -273,7 +273,9 @@ static struct option inq_options[] = { static char *inq_help = "Usage:\n" - "\tinq [--length=N] [--numrsp=N] [--flush]\n"; + "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" + "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { -- cgit From e4108aa9ba79bc6e898fa1581e2c4a56a68ad10d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 23 May 2002 20:57:19 +0000 Subject: Build env cleanup. Remove auto generated files from CVS. Working 'make distcheck'. --- tools/Makefile.in | 468 ------------------------------------------------------ 1 file changed, 468 deletions(-) delete mode 100644 tools/Makefile.in (limited to 'tools') diff --git a/tools/Makefile.in b/tools/Makefile.in deleted file mode 100644 index 794cfeca..00000000 --- a/tools/Makefile.in +++ /dev/null @@ -1,468 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# -# $Id$ -# - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_alias = @build_alias@ -build_triplet = @build@ -host_alias = @host_alias@ -host_triplet = @host@ -target_alias = @target_alias@ -target_triplet = @target@ -AR = @AR@ -AWK = @AWK@ -CC = @CC@ -DISTRO = @DISTRO@ -GLIB = @GLIB@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LDFLAGS = @GLIB_LDFLAGS@ -LD = @LD@ -LEX = @LEX@ -MAKEINFO = @MAKEINFO@ -PACKAGE = @PACKAGE@ -PCMCIA = @PCMCIA@ -VERSION = @VERSION@ -YACC = @YACC@ - -mandir = $(prefix)/usr/share/man - -sbin_PROGRAMS = hciattach hciconfig -bin_PROGRAMS = hcitool l2ping - -man_MANS = hciattach.8 l2ping.8 - -noinst_PROGRAMS = l2test scotest - -EXTRA_DIST = $(man_MANS) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) - - -DEFS = @DEFS@ -I. -I$(srcdir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -hcitool_SOURCES = hcitool.c -hcitool_OBJECTS = hcitool.o -hcitool_LDADD = $(LDADD) -hcitool_DEPENDENCIES = -hcitool_LDFLAGS = -l2ping_SOURCES = l2ping.c -l2ping_OBJECTS = l2ping.o -l2ping_LDADD = $(LDADD) -l2ping_DEPENDENCIES = -l2ping_LDFLAGS = -l2test_SOURCES = l2test.c -l2test_OBJECTS = l2test.o -l2test_LDADD = $(LDADD) -l2test_DEPENDENCIES = -l2test_LDFLAGS = -scotest_SOURCES = scotest.c -scotest_OBJECTS = scotest.o -scotest_LDADD = $(LDADD) -scotest_DEPENDENCIES = -scotest_LDFLAGS = -hciattach_SOURCES = hciattach.c -hciattach_OBJECTS = hciattach.o -hciattach_LDADD = $(LDADD) -hciattach_DEPENDENCIES = -hciattach_LDFLAGS = -hciconfig_SOURCES = hciconfig.c -hciconfig_OBJECTS = hciconfig.o -hciconfig_LDADD = $(LDADD) -hciconfig_DEPENDENCIES = -hciconfig_LDFLAGS = -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -man8dir = $(mandir)/man8 -MANS = $(man_MANS) - -NROFF = nroff -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -DEP_FILES = .deps/hciattach.P .deps/hciconfig.P .deps/hcitool.P \ -.deps/l2ping.P .deps/l2test.P .deps/scotest.P -SOURCES = hcitool.c l2ping.c l2test.c scotest.c hciattach.c hciconfig.c -OBJECTS = hcitool.o l2ping.o l2test.o scotest.o hciattach.o hciconfig.o - -all: all-redirect -.SUFFIXES: -.SUFFIXES: .S .c .o .s -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -mostlyclean-binPROGRAMS: - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) - -distclean-binPROGRAMS: - -maintainer-clean-binPROGRAMS: - -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - list='$(bin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - done - -mostlyclean-noinstPROGRAMS: - -clean-noinstPROGRAMS: - -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) - -distclean-noinstPROGRAMS: - -maintainer-clean-noinstPROGRAMS: - -mostlyclean-sbinPROGRAMS: - -clean-sbinPROGRAMS: - -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) - -distclean-sbinPROGRAMS: - -maintainer-clean-sbinPROGRAMS: - -install-sbinPROGRAMS: $(sbin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(sbindir) - @list='$(sbin_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - else :; fi; \ - done - -uninstall-sbinPROGRAMS: - @$(NORMAL_UNINSTALL) - list='$(sbin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - done - -.s.o: - $(COMPILE) -c $< - -.S.o: - $(COMPILE) -c $< - -mostlyclean-compile: - -rm -f *.o core *.core - -clean-compile: - -distclean-compile: - -rm -f *.tab.c - -maintainer-clean-compile: - -hcitool: $(hcitool_OBJECTS) $(hcitool_DEPENDENCIES) - @rm -f hcitool - $(LINK) $(hcitool_LDFLAGS) $(hcitool_OBJECTS) $(hcitool_LDADD) $(LIBS) - -l2ping: $(l2ping_OBJECTS) $(l2ping_DEPENDENCIES) - @rm -f l2ping - $(LINK) $(l2ping_LDFLAGS) $(l2ping_OBJECTS) $(l2ping_LDADD) $(LIBS) - -l2test: $(l2test_OBJECTS) $(l2test_DEPENDENCIES) - @rm -f l2test - $(LINK) $(l2test_LDFLAGS) $(l2test_OBJECTS) $(l2test_LDADD) $(LIBS) - -scotest: $(scotest_OBJECTS) $(scotest_DEPENDENCIES) - @rm -f scotest - $(LINK) $(scotest_LDFLAGS) $(scotest_OBJECTS) $(scotest_LDADD) $(LIBS) - -hciattach: $(hciattach_OBJECTS) $(hciattach_DEPENDENCIES) - @rm -f hciattach - $(LINK) $(hciattach_LDFLAGS) $(hciattach_OBJECTS) $(hciattach_LDADD) $(LIBS) - -hciconfig: $(hciconfig_OBJECTS) $(hciconfig_DEPENDENCIES) - @rm -f hciconfig - $(LINK) $(hciconfig_LDFLAGS) $(hciconfig_OBJECTS) $(hciconfig_LDADD) $(LIBS) - -install-man8: - $(mkinstalldirs) $(DESTDIR)$(man8dir) - @list='$(man8_MANS)'; \ - l2='$(man_MANS)'; for i in $$l2; do \ - case "$$i" in \ - *.8*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ - done - -uninstall-man8: - @list='$(man8_MANS)'; \ - l2='$(man_MANS)'; for i in $$l2; do \ - case "$$i" in \ - *.8*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ - rm -f $(DESTDIR)$(man8dir)/$$inst; \ - done -install-man: $(MANS) - @$(NORMAL_INSTALL) - $(MAKE) $(AM_MAKEFLAGS) install-man8 -uninstall-man: - @$(NORMAL_UNINSTALL) - $(MAKE) $(AM_MAKEFLAGS) uninstall-man8 - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = tools - -distdir: $(DISTFILES) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(top_distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu tools/Makefile - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done - -DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) - --include $(DEP_FILES) - -mostlyclean-depend: - -clean-depend: - -distclean-depend: - -rm -rf .deps - -maintainer-clean-depend: - -%.o: %.c - @echo '$(COMPILE) -c $<'; \ - $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< - @-cp .deps/$(*F).pp .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm .deps/$(*F).pp - -%.lo: %.c - @echo '$(LTCOMPILE) -c $<'; \ - $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< - @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ - < .deps/$(*F).pp > .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm -f .deps/$(*F).pp -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: install-binPROGRAMS install-sbinPROGRAMS -install-exec: install-exec-am - -install-data-am: install-man -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS uninstall-man -uninstall: uninstall-am -all-am: Makefile $(PROGRAMS) $(MANS) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir) \ - $(DESTDIR)$(mandir)/man8 - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \ - mostlyclean-sbinPROGRAMS mostlyclean-compile \ - mostlyclean-tags mostlyclean-depend mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-sbinPROGRAMS \ - clean-compile clean-tags clean-depend clean-generic \ - mostlyclean-am - -clean: clean-am - -distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \ - distclean-sbinPROGRAMS distclean-compile distclean-tags \ - distclean-depend distclean-generic clean-am - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-binPROGRAMS \ - maintainer-clean-noinstPROGRAMS \ - maintainer-clean-sbinPROGRAMS maintainer-clean-compile \ - maintainer-clean-tags maintainer-clean-depend \ - maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ -maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ -mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ -clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ -mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \ -maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ -install-sbinPROGRAMS mostlyclean-compile distclean-compile \ -clean-compile maintainer-clean-compile install-man8 uninstall-man8 \ -install-man uninstall-man tags mostlyclean-tags distclean-tags \ -clean-tags maintainer-clean-tags distdir mostlyclean-depend \ -distclean-depend clean-depend maintainer-clean-depend info-am info \ -dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ -install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: -- cgit From 940d830204a87da484eec5e84f18281476c9a505 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 31 May 2002 17:14:39 +0000 Subject: -p print pid option --- tools/hciattach.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index a7f89e21..9668460c 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -647,30 +647,36 @@ extern char *optarg; int main(int argc, char *argv[]) { struct uart_t *u = NULL; - int detach, opt, i, n; + int detach, printpid, opt, i, n; int to = 5; + pid_t pid; struct sigaction sa; char dev[20]; detach = 1; + printpid = 0; - while ((opt=getopt(argc, argv, "nt:l")) != EOF) { + while ((opt=getopt(argc, argv, "npt:l")) != EOF) { switch(opt) { case 'n': detach = 0; break; - + + case 'p': + printpid = 1; + break; + case 't': to = atoi(optarg); break; - + case 'l': for (i = 0; uart[i].type; i++) { printf("%-10s0x%04x,0x%04x\n", uart[i].type, uart[i].m_id, uart[i].p_id); } exit(0); - + default: usage(); exit(1); @@ -747,7 +753,11 @@ int main(int argc, char *argv[]) alarm(0); if (detach) { - if (fork()) return 0; + if ((pid = fork())) { + if (printpid) + printf("%d\n", pid); + return 0; + } for (i=0; i<20; i++) if (i != n) close(i); } -- cgit From 8ee2371d4b948a541a71fce00e1cfde01ed364d8 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 16:48:50 +0000 Subject: Use library functions hci_for_each_dev and hci_get_route. Use new hci_inquiry function syntax. --- tools/hcitool.c | 125 +++++++++++++++----------------------------------------- 1 file changed, 33 insertions(+), 92 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8ce64ed6..c2ad6186 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -51,62 +51,13 @@ extern char *optarg; #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) -static int ctl; - static void usage(void); -static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) -{ - struct hci_dev_list_req *dl; - struct hci_dev_req *dr; - int i; - - dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); - if (!dl) { - perror("Can't allocate memory"); - return -1; - } - dl->dev_num = HCI_MAX_DEV; - dr = dl->dev_req; - - if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { - perror("Can't get device list"); - return -1; - } - - if (!dl->dev_num) - return -1; - - for (i=0; i < dl->dev_num; i++, dr++) { - if (hci_test_bit(flag, &dr->dev_opt)) { - if (!func || func(dr->dev_id, arg)) - return dr->dev_id; - } - } - return -1; -} - -static int other_bdaddr(int dev_id, long arg) -{ - struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) - return 0; - return bacmp((bdaddr_t *)arg, &di.bdaddr); -} - -static int get_route(bdaddr_t *bdaddr) -{ - if (bdaddr) - return for_each_dev(HCI_UP, other_bdaddr, (long) bdaddr); - else - return for_each_dev(HCI_UP, NULL, 0); -} - -static int dev_info(int dev_id, long arg) +static int dev_info(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; bdaddr_t bdaddr; - if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; baswap(&bdaddr, &di.bdaddr); @@ -114,14 +65,17 @@ static int dev_info(int dev_id, long arg) return 0; } -static int rev_info(int dev_id, long arg) +static int rev_info(int s, int dev_id, long arg) { struct hci_version ver; + int id = arg; int dd; struct hci_request rq; unsigned char buf[102]; + if (id != -1 && dev_id != id) + return 0; dd = hci_open_dev(dev_id); if (dd < 0) { @@ -162,12 +116,16 @@ static int rev_info(int dev_id, long arg) return 0; } -static int conn_list(int dev_id, long arg) +static int conn_list(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; + int id = arg; int i; + if (id != -1 && dev_id != id) + return 0; + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { perror("Can't allocate memory"); exit(1); @@ -176,7 +134,7 @@ static int conn_list(int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { perror("Can't get connection list"); exit(1); } @@ -193,7 +151,7 @@ static int conn_list(int dev_id, long arg) return 0; } -static int find_conn(int dev_id, long arg) +static int find_conn(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; @@ -207,7 +165,7 @@ static int find_conn(int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { perror("Can't get connection list"); exit(1); } @@ -258,7 +216,7 @@ static void cmd_dev(int dev_id, int argc, char **argv) } printf("Devices:\n"); - for_each_dev(HCI_UP, dev_info, 0); + hci_for_each_dev(HCI_UP, dev_info, 0); } /* Inquiry */ @@ -280,7 +238,7 @@ static char *inq_help = static void cmd_inq(int dev_id, int argc, char **argv) { int num_rsp, length, flags; - inquiry_info *info; + inquiry_info *info = NULL; bdaddr_t bdaddr; int i, opt; @@ -308,13 +266,9 @@ static void cmd_inq(int dev_id, int argc, char **argv) } } - if (dev_id < 0) - dev_id = get_route(NULL); - printf("Inquiring ...\n"); - info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); - - if (!info) { + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { perror("Inquiry failed."); exit(1); } @@ -346,7 +300,7 @@ static char *scan_help = static void cmd_scan(int dev_id, int argc, char **argv) { - inquiry_info *info; + inquiry_info *info = NULL; int num_rsp, length, flags; bdaddr_t bdaddr; char name[248]; @@ -376,13 +330,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } - if (dev_id < 0) - dev_id = get_route(NULL); - printf("Scanning ...\n"); - info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); - - if (!info) { + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { perror("Inquiry failed."); exit(1); } @@ -434,7 +384,7 @@ static void cmd_name(int dev_id, int argc, char **argv) baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -492,7 +442,7 @@ static void cmd_info(int dev_id, int argc, char **argv) baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -573,7 +523,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) } if (dev_id < 0) - dev_id = get_route(NULL); + dev_id = hci_get_route(NULL); errno = 0; ogf = strtol(argv[0], NULL, 16); @@ -648,11 +598,7 @@ static void cmd_rev(int dev_id, int argc, char **argv) return; } } - - if (dev_id < 0) - for_each_dev(HCI_UP, rev_info, 0); - else - rev_info(dev_id, 0); + hci_for_each_dev(HCI_UP, rev_info, dev_id); } /* Display active connections */ @@ -679,10 +625,7 @@ static void cmd_con(int dev_id, int argc, char **argv) } printf("Connections:\n"); - if (dev_id < 0) - for_each_dev(HCI_UP, conn_list, 0); - else - conn_list(dev_id, 0); + hci_for_each_dev(HCI_UP, conn_list, dev_id); } /* Create connection */ @@ -737,7 +680,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -789,7 +732,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -856,7 +799,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -941,7 +884,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) hci_strtoptype(argv[1], &ptype); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -1032,6 +975,7 @@ static struct option main_options[] = { int main(int argc, char **argv) { int opt, i, dev_id = -1; + bdaddr_t ba; while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { @@ -1055,9 +999,8 @@ int main(int argc, char **argv) exit(0); } - /* Open HCI socket */ - if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { - perror("Can't open HCI socket."); + if (dev_id != -1 && hci_devba(dev_id, &ba) < 0) { + perror("Device is not available"); exit(1); } @@ -1067,7 +1010,5 @@ int main(int argc, char **argv) command[i].func(dev_id, argc, argv); break; } - - close(ctl); return 0; } -- cgit From 002edf82ee25e3161bb00e6c976aefcb11062ba1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:33:43 +0000 Subject: use hci_devid --- tools/hcitool.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index c2ad6186..96348342 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -980,7 +980,11 @@ int main(int argc, char **argv) while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { case 'i': - dev_id = atoi(optarg + 3); + dev_id = hci_devid(optarg); + if (dev_id < 0) { + perror("Invalid device"); + exit(1); + } break; case 'h': -- cgit From 596c0840d5682ccae5f1805f92f32391608bfac8 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Jun 2002 00:24:30 +0000 Subject: scan command works again. --- tools/hcitool.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 96348342..ae03ee96 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -330,6 +330,14 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } + if (dev_id < 0) { + dev_id = hci_get_route(&bdaddr); + if (dev_id < 0) { + perror("Device is not available."); + exit(1); + } + } + printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { @@ -337,15 +345,22 @@ static void cmd_scan(int dev_id, int argc, char **argv) exit(1); } + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + free(info); + exit(1); + } + for (i = 0; i < num_rsp; i++) { - dd = hci_open_dev(dev_id); memset(name, 0, sizeof(name)); if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - close(dd); baswap(&bdaddr, &(info+i)->bdaddr); - printf("\t%s\t%s\n", batostr(&bdaddr), name); + printf("\t%s\t%s\n", batostr(&bdaddr), name); } + + close(dd); free(info); } -- cgit From cd7dd46bb4c182c1ea81c123eb1820d738ea03e6 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 25 Jun 2002 04:15:33 +0000 Subject: Page params commands --- tools/hciconfig.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1efdecca..9d52dcf3 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -488,6 +488,135 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) } } +void cmd_page_parms(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + unsigned int window, interval; + write_page_activity_cp cp; + + if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) { + printf("Invalid argument format\n"); + exit(1); + } + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_PAGE_ACTIVITY; + rq.cparam = &cp; + rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE; + + cp.window = htobs((uint16_t)window); + cp.interval = htobs((uint16_t)interval); + + if (window < 0x12 || window > 0x1000) + printf("Warning: page window out of range!\n"); + + if (interval < 0x12 || interval > 0x1000) + printf("Warning: page interval out of range!\n"); + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't set page parameters name on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint16_t window, interval; + read_page_activity_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_PAGE_ACTIVITY; + rq.rparam = &rp; + rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read page parameters on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read page parameters on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + + window = btohs(rp.window); + interval = btohs(rp.interval); + printf("\tPage interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", + interval, (float)interval * 0.625, window, (float)window * 0.625); + } +} + +void cmd_page_to(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + unsigned int timeout; + write_page_timeout_cp cp; + + if (sscanf(opt,"%4u", &timeout) != 1) { + printf("Invalid argument format\n"); + exit(1); + } + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_PAGE_TIMEOUT; + rq.cparam = &cp; + rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE; + + cp.timeout = htobs((uint16_t)timeout); + + if (timeout < 0x01 || timeout > 0xFFFF) + printf("Warning: page timeout out of range!\n"); + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't set page timeout on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint16_t timeout; + read_page_timeout_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_PAGE_TIMEOUT; + rq.rparam = &rp; + rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read page timeout on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read page timeout on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + + timeout = btohs(rp.timeout); + printf("\tPage timeout: %u slots (%.2f ms)\n", + timeout, (float)timeout * 0.625); + } +} + void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; @@ -559,6 +688,8 @@ struct { { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, { "inqparms",cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, + { "pageparms",cmd_page_parms, "[win:int]","Get/Set page scan window and interval" }, + { "ptimeo", cmd_page_to, "[to]", "Get/Set page timeout" }, { "aclmtu", cmd_aclmtu, "","Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "","Set SCO MTU and number of packets" }, { "version", cmd_version, 0, "Display version information" }, -- cgit From aaa64a3108d3bb8eba3e49f2b58d3909627bbca0 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 25 Jun 2002 04:36:09 +0000 Subject: Move revision command to hciconfig. --- tools/hciconfig.c | 57 ++++++++++++++++++++++++++++++++++++---- tools/hcitool.c | 77 ------------------------------------------------------- 2 files changed, 52 insertions(+), 82 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 9d52dcf3..093c3100 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -617,6 +617,52 @@ void cmd_page_to(int ctl, int hdev, char *opt) } } +static void cmd_revision(int ctl, int hdev, char *opt) +{ + struct hci_version ver; + struct hci_request rq; + unsigned char buf[102]; + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + return; + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + printf("Can't read version info hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + return; + } + + print_dev_hdr(&di); + switch (ver.manufacturer) { + case 0: + memset(&rq, 0, sizeof(rq)); + rq.ogf = 0x3f; + rq.ocf = 0x000f; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\n Can't read revision info. %s(%d)\n", + strerror(errno), errno); + return; + } + + printf("\t%s\n", buf + 1); + break; + + default: + printf("\tUnsuported manufacturer\n"); + break; + } + return; +} + void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; @@ -687,13 +733,14 @@ struct { { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, - { "inqparms",cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, - { "pageparms",cmd_page_parms, "[win:int]","Get/Set page scan window and interval" }, - { "ptimeo", cmd_page_to, "[to]", "Get/Set page timeout" }, + { "inqparms", cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, + { "pageparms", cmd_page_parms, "[win:int]","Get/Set page scan window and interval" }, + { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, { "aclmtu", cmd_aclmtu, "","Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "","Set SCO MTU and number of packets" }, - { "version", cmd_version, 0, "Display version information" }, - { "features", cmd_features, 0,"Display device features" }, + { "features", cmd_features, 0, "Display device features" }, + { "version", cmd_version, 0, "Display version information" }, + { "revision", cmd_revision, 0, "Display revision information" }, { NULL, NULL, 0} }; diff --git a/tools/hcitool.c b/tools/hcitool.c index ae03ee96..8eaa2cc2 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -65,57 +65,6 @@ static int dev_info(int s, int dev_id, long arg) return 0; } -static int rev_info(int s, int dev_id, long arg) -{ - struct hci_version ver; - int id = arg; - int dd; - - struct hci_request rq; - unsigned char buf[102]; - - if (id != -1 && dev_id != id) - return 0; - - dd = hci_open_dev(dev_id); - if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", dev_id, strerror(errno), errno); - return -1; - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - printf("Can't read version info hci%d. %s(%d)\n", - dev_id, strerror(errno), errno); - return -1; - } - - printf("hci%d:", dev_id); - switch (ver.manufacturer) { - case 0: - memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; - rq.ocf = 0x000f; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &buf; - rq.rlen = sizeof(buf); - - if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\n Can't read revision info. %s(%d)\n", - strerror(errno), errno); - return -1; - } - - printf("%s\n", buf + 1); - break; - default: - printf("\n Manufacturer not supported\n"); - break; - } - printf("\n"); - return 0; -} - static int conn_list(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; @@ -591,31 +540,6 @@ static void cmd_cmd(int dev_id, int argc, char **argv) return; } -/* Display revision info */ - -static struct option rev_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} -}; - -static char *rev_help = - "Usage:\n" - "\trev\n"; - -static void cmd_rev(int dev_id, int argc, char **argv) -{ - int opt; - - for_each_opt(opt, rev_options, NULL) { - switch(opt) { - default: - printf(rev_help); - return; - } - } - hci_for_each_dev(HCI_UP, rev_info, dev_id); -} - /* Display active connections */ static struct option con_options[] = { @@ -948,7 +872,6 @@ struct { char *doc; } command[] = { { "dev", cmd_dev, "Display local devices" }, - { "rev", cmd_rev, "Display revison information" }, { "inq", cmd_inq, "Inquire remote devices" }, { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, -- cgit From 8bf4e7762d7839c00dec331b32b8674190e98be7 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 25 Jun 2002 18:31:56 +0000 Subject: Command parsing fix. --- tools/hciconfig.c | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 093c3100..a247e29d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -716,32 +716,32 @@ struct { char *opt; char *doc; } command[] = { - { "up", cmd_up, 0, "Open and initialize HCI device" }, - { "down", cmd_down, 0, "Close HCI device" }, - { "reset", cmd_reset, 0, "Reset HCI device" }, - { "rstat", cmd_rstat, 0, "Reset statistic counters" }, - { "auth", cmd_auth, 0, "Enable Authentication" }, - { "noauth", cmd_auth, 0, "Disable Authentication" }, - { "encrypt",cmd_encrypt,0, "Enable Encryption" }, - { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, - { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, - { "noscan", cmd_scan, 0, "Disable scan" }, - { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, - { "pscan", cmd_scan, 0, "Enable Page scan" }, - { "ptype", cmd_ptype, "[type]", "Get/Set default packet type" }, - { "lm", cmd_lm, "[mode]", "Get/Set default link mode" }, - { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, - { "name", cmd_name, "[name]", "Get/Set local name" }, - { "class", cmd_class, "[class]", "Get/Set class of device" }, - { "inqparms", cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, - { "pageparms", cmd_page_parms, "[win:int]","Get/Set page scan window and interval" }, - { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, - { "aclmtu", cmd_aclmtu, "","Set ACL MTU and number of packets" }, - { "scomtu", cmd_scomtu, "","Set SCO MTU and number of packets" }, - { "features", cmd_features, 0, "Display device features" }, - { "version", cmd_version, 0, "Display version information" }, - { "revision", cmd_revision, 0, "Display revision information" }, - { NULL, NULL, 0} + { "up", cmd_up, 0, "Open and initialize HCI device" }, + { "down", cmd_down, 0, "Close HCI device" }, + { "reset", cmd_reset, 0, "Reset HCI device" }, + { "rstat", cmd_rstat, 0, "Reset statistic counters" }, + { "auth", cmd_auth, 0, "Enable Authentication" }, + { "noauth", cmd_auth, 0, "Disable Authentication" }, + { "encrypt", cmd_encrypt, 0, "Enable Encryption" }, + { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, + { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, + { "noscan", cmd_scan, 0, "Disable scan" }, + { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, + { "pscan", cmd_scan, 0, "Enable Page scan" }, + { "ptype", cmd_ptype, "[type]", "Get/Set default packet type" }, + { "lm", cmd_lm, "[mode]", "Get/Set default link mode" }, + { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, + { "name", cmd_name, "[name]", "Get/Set local name" }, + { "class", cmd_class, "[class]", "Get/Set class of device" }, + { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, + { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, + { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, + { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, + { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, + { "features", cmd_features, 0, "Display device features" }, + { "version", cmd_version, 0, "Display version information" }, + { "revision", cmd_revision, 0, "Display revision information" }, + { NULL, NULL, 0 } }; void usage(void) @@ -807,7 +807,7 @@ int main(int argc, char **argv, char **env) while (argc > 0) { for (i=0; command[i].cmd; i++) { - if (strncmp(command[i].cmd, *argv, 4)) + if (strncmp(command[i].cmd, *argv, 5)) continue; if (command[i].opt) { -- cgit From 1ab78899d1ca28e0ea56cb68c73c04b7128d233f Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 9 Jul 2002 18:54:46 +0000 Subject: Timeout can be 5 digits. --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index a247e29d..6f9dc4ca 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -570,7 +570,7 @@ void cmd_page_to(int ctl, int hdev, char *opt) unsigned int timeout; write_page_timeout_cp cp; - if (sscanf(opt,"%4u", &timeout) != 1) { + if (sscanf(opt,"%5u", &timeout) != 1) { printf("Invalid argument format\n"); exit(1); } -- cgit From eb23734ec801339282844c2548ec415303e36455 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 9 Jul 2002 19:10:01 +0000 Subject: Display device class in human readable format. --- tools/hciconfig.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 6f9dc4ca..baa1d97b 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -344,8 +344,157 @@ void cmd_name(int ctl, int hdev, char *opt) } } +/* + * see http://www.bluetooth.org/assigned-numbers/baseband.htm --- all + * strings are reproduced verbatim + */ +static char *get_minor_device_name(int major, int minor) +{ + switch(major) { + case 0:/* misc */ + return ""; + case 1:/* computer */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2:/* phone */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3:/* lan access */ + if (minor == 0) + return "Uncategorized"; + switch(minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4:/* audio/video */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5:/* peripheral */ + switch(minor) { + case 16: + return "Keyboard"; + case 32: + return "Pointing device"; + case 64: + return "Combo keyboard/pointing device"; + } + break; + case 6:/* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 63:/* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + void cmd_class(int ctl, int hdev, char *opt) { + static char *services[] = { "Positioning", + "Networking", + "Rendering", + "Capturing", + "Object Transfer", + "Audio", + "Telephony", + "Information" }; + static char *major_devices[] = { "Miscellaneous", + "Computer", + "Phone", + "LAN Access", + "Audio/Video", + "Peripheral", + "Imaging", + "Uncategorized" }; struct hci_request rq; int s; @@ -393,6 +542,25 @@ void cmd_class(int ctl, int hdev, char *opt) print_dev_hdr(&di); printf("\tClass: 0x%02x%02x%02x\n", rp.dev_class[2], rp.dev_class[1], rp.dev_class[0]); + printf("\tService Classes: "); + if (rp.dev_class[2]) { + int first = 1; + for(s=0; s < 8; s++) + if (rp.dev_class[2] & (2 << s)) { + if (!first) + printf(", "); + printf(services[s]); + first = 0; + } + } else + printf("Unspecified"); + printf("\n\tDevice Class: "); + if (rp.dev_class[1] > sizeof(major_devices)) + printf("Invalid Device Class!\n"); + else + printf("%s/%s\n", major_devices[rp.dev_class[1]], + get_minor_device_name(rp.dev_class[1], + rp.dev_class[0] / 4)); } } -- cgit From e60ae4dbe6877e5aec39e73db73acac63975fc85 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 12 Jul 2002 00:19:06 +0000 Subject: Minor fixes for dev class handling. --- tools/hciconfig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index baa1d97b..6ea30a5d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -545,8 +545,8 @@ void cmd_class(int ctl, int hdev, char *opt) printf("\tService Classes: "); if (rp.dev_class[2]) { int first = 1; - for(s=0; s < 8; s++) - if (rp.dev_class[2] & (2 << s)) { + for(s=0; s < sizeof(services); s++) + if (rp.dev_class[2] & (1 << s)) { if (!first) printf(", "); printf(services[s]); @@ -558,7 +558,7 @@ void cmd_class(int ctl, int hdev, char *opt) if (rp.dev_class[1] > sizeof(major_devices)) printf("Invalid Device Class!\n"); else - printf("%s/%s\n", major_devices[rp.dev_class[1]], + printf("%s, %s\n", major_devices[rp.dev_class[1]], get_minor_device_name(rp.dev_class[1], rp.dev_class[0] / 4)); } -- cgit From 70516886fef2e6c208d3e48332cc2c6c4b4d964c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 20 Jul 2002 18:53:27 +0000 Subject: Support for connectionless channels (datagram sockets). --- tools/l2test.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/l2test.c b/tools/l2test.c index 56adad96..985a7500 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -73,6 +73,7 @@ unsigned short psm = 10; int master = 0; int auth = 0; int encrypt = 0; +int socktype = SOCK_SEQPACKET; float tv2fl(struct timeval tv) { @@ -85,7 +86,7 @@ int do_connect(char *svr) struct l2cap_options opts; int s, opt; - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0 ) { + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); return -1; } @@ -141,7 +142,7 @@ void do_listen( void (*handler)(int sk) ) int s, s1, opt; bdaddr_t ba; - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0 ) { + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -154,8 +155,19 @@ void do_listen( void (*handler)(int sk) ) exit(1); } - if( listen(s, 10) ) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); exit(1); } @@ -173,20 +185,13 @@ void do_listen( void (*handler)(int sk) ) exit(1); } + if (socktype == SOCK_DGRAM) { + handler(s); + return; + } - /* Set link mode */ - opt = 0; - if (master) - opt |= L2CAP_LM_MASTER; - - if (auth) - opt |= L2CAP_LM_AUTH; - - if (encrypt) - opt |= L2CAP_LM_ENCRYPT; - - if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -228,7 +233,7 @@ void dump_mode(int s) { int len; - syslog(LOG_INFO,"Receiving ..."); + syslog(LOG_INFO, "Receiving ..."); while ((len = read(s, buf, data_size)) > 0) syslog(LOG_INFO, "Recevied %d bytes\n", len); } @@ -366,7 +371,8 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" - "\t[-A] request authentication\n" + "\t[-D] use connectionless channel (datagram)\n" + "\t[-E] request encryption\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); } @@ -381,7 +387,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAED")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -452,6 +458,10 @@ int main(int argc ,char *argv[]) encrypt = 1; break; + case 'D': + socktype = SOCK_DGRAM; + break; + default: usage(); exit(1); -- cgit From 89d41e2e6c81aa5c30f2fa699cc4654eb174627c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 23 Jul 2002 19:51:11 +0000 Subject: Don't exit from reconnect mode if connection was denied. --- tools/l2test.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/l2test.c b/tools/l2test.c index 985a7500..1fd20932 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -120,12 +120,14 @@ int do_connect(char *svr) rem_addr.l2_psm = htobs(psm); if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + close(s); return -1; } opt = sizeof(opts); if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + close(s); return -1; } @@ -305,11 +307,11 @@ void send_mode(int s) buf[i]=0x7f; seq = 0; - while(1){ - *(uint32_t *)buf = htobl(seq++); + while (1) { + *(uint32_t *) buf = htobl(seq++); *(uint16_t *)(buf+4) = htobs(data_size); - if( send(s, buf, data_size, 0) <= 0 ) { + if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); exit(1); } @@ -318,14 +320,9 @@ void send_mode(int s) void reconnect_mode(char *svr) { - while(1){ - int s; - if( (s = do_connect(svr)) < 0 ) - exit(1); - + while(1) { + int s = do_connect(svr); close(s); - - usleep(10); } } @@ -337,19 +334,20 @@ void connect_mode(char *svr) sleep(99999999); } -void multy_connect_mode(char *svr) +void multi_connect_mode(char *svr) { - while(1){ + while (1) { int i, s; - for(i=0; i<10; i++){ - if( fork() ) continue; + for (i=0; i<10; i++) { + if (fork()) continue; /* Child */ s = do_connect(svr); + usleep(500); close(s); exit(0); } - sleep(19); + sleep(2); } } @@ -517,7 +515,7 @@ int main(int argc ,char *argv[]) break; case MULTY: - multy_connect_mode(argv[optind]); + multi_connect_mode(argv[optind]); break; case CONNECT: -- cgit From 671854ad5a6f8b40adb397d30aa93ff66efa1376 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sun, 4 Aug 2002 22:13:31 +0000 Subject: BCSP inti support. --- tools/hciattach.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 9668460c..b24f33ab 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -228,6 +228,26 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) return 0; } +/* + * BCSP specific initialization + */ +static int bcsp(int fd, struct uart_t *u, struct termios *ti) +{ + ti->c_cflag &= ~CBAUD; + ti->c_cflag |= B115200 | CS8 | CLOCAL | PARENB; + ti->c_cflag &= ~(PARODD|CRTSCTS); + + ti->c_oflag = 0; /* turn off output processing */ + ti->c_lflag = 0; /* no local modes */ + + if (tcsetattr(fd, TCSANOW, ti) < 0) { + perror("Can't set port settings"); + return -1; + } + + return 0; +} + /* * CSR specific initialization * Inspired strongly by code in OpenBT and experimentations with Brainboxes @@ -525,30 +545,32 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } struct uart_t uart[] = { - { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, - { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, - { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, + + { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 0, bcsp }, /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ - { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, FLOW_CTL, NULL }, /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ - { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, csr }, + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, csr }, /* BrainBoxes PCMCIA card (BL620) */ - { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 460800, FLOW_CTL, csr }, + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 460800, FLOW_CTL, csr }, /* Silicon Wave kits */ - { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, swave }, + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, swave }, /* Sphinx Electronics PICO Card */ - { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, /* Inventel BlueBird Module */ - { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, /* COM One Platinium Bluetooth PC Card */ - { "comone", 0xffff, 0x0101, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 0, bcsp }, { NULL, 0 } }; -- cgit From 87c1d9f203e4ff13948ed8bf6802b21b7020d155 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 19 Aug 2002 16:51:48 +0000 Subject: RFCOMM test tool --- tools/Makefile.am | 2 +- tools/rctest.c | 470 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 471 insertions(+), 1 deletion(-) create mode 100644 tools/rctest.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index c1a82d7f..281be99e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -9,6 +9,6 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -noinst_PROGRAMS = l2test scotest +noinst_PROGRAMS = l2test scotest rctest EXTRA_DIST = $(man_MANS) diff --git a/tools/rctest.c b/tools/rctest.c new file mode 100644 index 00000000..3789fe8b --- /dev/null +++ b/tools/rctest.c @@ -0,0 +1,470 @@ +/* + RFCOMM test tool + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP, + CONNECT, + CRECV, + LSEND +}; + +unsigned char *buf; + +/* Default mtu */ +int imtu = 672; +int omtu = 0; + +/* Default data size */ +long data_size = 127; + +/* Default addr and port */ +bdaddr_t bdaddr; +unsigned short port = 10; + +int master = 0; +int auth = 0; +int encrypt = 0; +int socktype = SOCK_STREAM; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_rc rem_addr, loc_addr; + int s; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.rc_family = AF_BLUETOOTH; + loc_addr.rc_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.rc_family = AF_BLUETOOTH; + baswap(&rem_addr.rc_bdaddr, strtoba(svr)); + rem_addr.rc_port = htobs(port); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected"); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_rc loc_addr, rem_addr; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.rc_family = AF_BLUETOOTH; + loc_addr.rc_bdaddr = bdaddr; + loc_addr.rc_port = htobs(port); + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + +#if 0 + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_RFCOMM, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } +#endif + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection on port %d ...", port); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + baswap(&ba, &rem_addr.rc_bdaddr); + syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO, "Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO,"Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + uint32_t sq; + uint16_t l; + int i,r; + + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + + /* Check sequence */ + sq = btohl(*(uint32_t *)buf); + if (seq != sq) { + syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); + seq = sq; + } + seq++; + + /* Check length */ + l = btohs(*(uint16_t *)(buf+4)); + if (r != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + continue; + } + + /* Verify data */ + for (i=6; i < r; i++) { + if (buf[i] != 0x7f) + syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); + } + + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + } +} + +void send_mode(int s) +{ + uint32_t seq; + int i; + + syslog(LOG_INFO,"Sending ..."); + + for(i=6; i < data_size; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *) buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, data_size, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } +} + +void reconnect_mode(char *svr) +{ + while(1) { + int s = do_connect(svr); + close(s); + } +} + +void multi_connect_mode(char *svr) +{ + while (1) { + int i, s; + for (i=0; i<10; i++) { + if (fork()) continue; + + /* Child */ + s = do_connect(svr); + usleep(500); + close(s); + exit(0); + } + sleep(2); + } +} + +void usage(void) +{ + printf("l2test - L2CAP testing\n" + "Usage:\n"); + printf("\tl2test [options] [bdaddr]\n"); + printf("Modes:\n" + "\t-r listen and receive\n" + "\t-w listen and send\n" + "\t-d listen and dump incomming data\n" + "\t-s connect and send\n" + "\t-u connect and receive\n" + "\t-n connect and be silent\n" + "\t-c connect, disconnect, connect, ...\n" + "\t-m multiple connects\n"); + + printf("Options:\n" + "\t[-b bytes] [-S bdaddr] [-P port]\n" + "\t[-I imtu] [-O omtu]\n" + "\t[-D] use connectionless channel (datagram)\n" + "\t[-E] request encryption\n" + "\t[-E] request encryption\n" + "\t[-M] become master\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + int opt, mode, s, need_addr; + struct sigaction sa; + + mode = RECV; need_addr = 0; + + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + need_addr = 1; + break; + + case 'w': + mode = LSEND; + break; + + case 'u': + mode = CRECV; + need_addr = 1; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + need_addr = 1; + break; + + case 'n': + mode = CONNECT; + need_addr = 1; + break; + + case 'm': + mode = MULTY; + need_addr = 1; + break; + + case 'b': + data_size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + case 'P': + port = atoi(optarg); + break; + + case 'I': + imtu = atoi(optarg); + break; + + case 'O': + omtu = atoi(optarg); + break; + + case 'M': + master = 1; + break; + + case 'A': + auth = 1; + break; + + case 'E': + encrypt = 1; + break; + + default: + usage(); + exit(1); + } + } + + if (need_addr && !(argc - optind)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case CRECV: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + recv_mode(s); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + send_mode(s); + break; + + case LSEND: + do_listen(send_mode); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multi_connect_mode(argv[optind]); + break; + + case CONNECT: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + dump_mode(s); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} -- cgit From 04c8ddd5a5d720e75144755d071e2331c979d1ed Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 20 Aug 2002 04:39:54 +0000 Subject: Add 'bluetooth/' to includes --- tools/hciattach.c | 8 ++++---- tools/hciconfig.c | 6 +++--- tools/hcitool.c | 6 +++--- tools/l2ping.c | 4 ++-- tools/l2test.c | 4 ++-- tools/rctest.c | 4 ++-- tools/scotest.c | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index b24f33ab..ca81117b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -41,10 +41,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include struct uart_t { char *type; diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 6ea30a5d..3c213ba4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -39,9 +39,9 @@ #include #include -#include -#include -#include +#include +#include +#include extern int optind,opterr,optopt; extern char *optarg; diff --git a/tools/hcitool.c b/tools/hcitool.c index 8eaa2cc2..7d3772bb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -42,9 +42,9 @@ #include #include -#include -#include -#include +#include +#include +#include extern int optind,opterr,optopt; extern char *optarg; diff --git a/tools/l2ping.c b/tools/l2ping.c index 9bb8a4d6..310ba86b 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -47,8 +47,8 @@ #include #include -#include "bluetooth.h" -#include "l2cap.h" +#include +#include /* Defaults */ bdaddr_t bdaddr; diff --git a/tools/l2test.c b/tools/l2test.c index 1fd20932..b08b2d34 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -42,8 +42,8 @@ #include #include -#include -#include +#include +#include /* Test modes */ enum { diff --git a/tools/rctest.c b/tools/rctest.c index 3789fe8b..bcb3516c 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -40,8 +40,8 @@ #include #include -#include -#include +#include +#include /* Test modes */ enum { diff --git a/tools/scotest.c b/tools/scotest.c index 4b56d081..dcb1acdf 100644 --- a/tools/scotest.c +++ b/tools/scotest.c @@ -42,8 +42,8 @@ #include #include -#include -#include +#include +#include /* Test modes */ enum { -- cgit From 41577e502830106f479fd9a17e08a797d671256b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 20 Aug 2002 19:53:37 +0000 Subject: port -> channel --- tools/rctest.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/rctest.c b/tools/rctest.c index bcb3516c..24699b23 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -64,9 +64,9 @@ int omtu = 0; /* Default data size */ long data_size = 127; -/* Default addr and port */ +/* Default addr and channel */ bdaddr_t bdaddr; -unsigned short port = 10; +unsigned short channel = 10; int master = 0; int auth = 0; @@ -99,7 +99,7 @@ int do_connect(char *svr) memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.rc_family = AF_BLUETOOTH; baswap(&rem_addr.rc_bdaddr, strtoba(svr)); - rem_addr.rc_port = htobs(port); + rem_addr.rc_channel = htobs(channel); if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); @@ -124,7 +124,7 @@ void do_listen( void (*handler)(int sk) ) loc_addr.rc_family = AF_BLUETOOTH; loc_addr.rc_bdaddr = bdaddr; - loc_addr.rc_port = htobs(port); + loc_addr.rc_channel = htobs(channel); if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); @@ -153,7 +153,7 @@ void do_listen( void (*handler)(int sk) ) exit(1); } - syslog(LOG_INFO,"Waiting for connection on port %d ...", port); + syslog(LOG_INFO,"Waiting for connection on channel %d ...", channel); while(1) { opt = sizeof(rem_addr); @@ -308,7 +308,7 @@ void usage(void) "\t-m multiple connects\n"); printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P port]\n" + "\t[-b bytes] [-S bdaddr] [-P channel]\n" "\t[-I imtu] [-O omtu]\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-E] request encryption\n" @@ -374,7 +374,7 @@ int main(int argc ,char *argv[]) break; case 'P': - port = atoi(optarg); + channel = atoi(optarg); break; case 'I': -- cgit From d10423ecaa32884c2c382756d502f615349c400b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 10:06:55 +0000 Subject: use hci lib --- tools/hciconfig.c | 84 ++++++++++++------------------------------------------- tools/hcitool.c | 6 ++-- 2 files changed, 21 insertions(+), 69 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3c213ba4..bbc61d0e 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -299,48 +299,26 @@ void cmd_features(int ctl, int hdev, char *opt) void cmd_name(int ctl, int hdev, char *opt) { - struct hci_request rq; - int s; - if ((s = hci_open_dev(hdev)) < 0) { + int s = hci_open_dev(hdev); + if (s < 0) { printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - - memset(&rq, 0, sizeof(rq)); - if (opt) { - change_local_name_cp cp; - strcpy(cp.name, opt); - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_CHANGE_LOCAL_NAME; - rq.cparam = &cp; - rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; - - if (hci_send_req(s, &rq, 1000) < 0) { + if (hci_write_local_name(s, opt, 1000) < 0) { printf("Can't change local name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { - read_local_name_rp rp; - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LOCAL_NAME; - rq.rparam = &rp; - rq.rlen = READ_LOCAL_NAME_RP_SIZE; - - if (hci_send_req(s, &rq, 1000) < 0) { + char name[248]; + if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { printf("Can't read local name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - if (rp.status) { - printf("Read local name on hci%d returned status %d\n", hdev, rp.status); - exit(1); - } print_dev_hdr(&di); - printf("\tName: '%s'\n", rp.name); + printf("\tName: '%s'\n", name); } } @@ -495,58 +473,33 @@ void cmd_class(int ctl, int hdev, char *opt) "Peripheral", "Imaging", "Uncategorized" }; - struct hci_request rq; - int s; + int s = hci_open_dev(hdev); - if ((s = hci_open_dev(hdev)) < 0) { + if (s < 0) { printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - - memset(&rq, 0, sizeof(rq)); if (opt) { uint32_t cod = htobl(strtoul(opt, NULL, 16)); - write_class_of_dev_cp cp; - - memcpy(cp.dev_class, &cod, 3); - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CLASS_OF_DEV; - rq.cparam = &cp; - rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; - - if (hci_send_req(s, &rq, 1000) < 0) { + if (0 > hci_write_class_of_dev(s, cod, 1000)) { printf("Can't write local class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { - read_class_of_dev_rp rp; - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_CLASS_OF_DEV; - rq.rparam = &rp; - rq.rlen = READ_CLASS_OF_DEV_RP_SIZE; - - if (hci_send_req(s, &rq, 1000) < 0) { + uint8_t cls[3]; + if (0 > hci_read_class_of_dev(s, cls, 1000)) { printf("Can't read class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - - if (rp.status) { - printf("Read class of device on hci%d returned status %d\n", - hdev, rp.status); - exit(1); - } print_dev_hdr(&di); - printf("\tClass: 0x%02x%02x%02x\n", - rp.dev_class[2], rp.dev_class[1], rp.dev_class[0]); + printf("\tClass: 0x%02x%02x%02x\n", cls[2], cls[1], cls[0]); printf("\tService Classes: "); - if (rp.dev_class[2]) { + if (cls[2]) { int first = 1; for(s=0; s < sizeof(services); s++) - if (rp.dev_class[2] & (1 << s)) { + if (cls[2] & (1 << s)) { if (!first) printf(", "); printf(services[s]); @@ -555,12 +508,11 @@ void cmd_class(int ctl, int hdev, char *opt) } else printf("Unspecified"); printf("\n\tDevice Class: "); - if (rp.dev_class[1] > sizeof(major_devices)) + if (cls[1] > sizeof(major_devices)) printf("Invalid Device Class!\n"); else - printf("%s, %s\n", major_devices[rp.dev_class[1]], - get_minor_device_name(rp.dev_class[1], - rp.dev_class[0] / 4)); + printf("%s, %s\n", major_devices[cls[1]], + get_minor_device_name(cls[1], cls[0] / 4)); } } @@ -653,7 +605,7 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) interval = btohs(rp.interval); printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", interval, (float)interval * 0.625, window, (float)window * 0.625); - } + } } void cmd_page_parms(int ctl, int hdev, char *opt) diff --git a/tools/hcitool.c b/tools/hcitool.c index 7d3772bb..34a9f5a4 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -303,7 +303,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); baswap(&bdaddr, &(info+i)->bdaddr); printf("\t%s\t%s\n", batostr(&bdaddr), name); @@ -361,7 +361,7 @@ static void cmd_name(int dev_id, int argc, char **argv) exit(1); } - if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("%s\n", name); close(dd); @@ -428,7 +428,7 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { -- cgit From 2d21a950915b17c9bc284a0bd703fd58ba8ac760 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 1 Sep 2002 10:49:22 +0000 Subject: Cleanup --- tools/rctest.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/rctest.c b/tools/rctest.c index 24699b23..af34b3f7 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -294,9 +294,9 @@ void multi_connect_mode(char *svr) void usage(void) { - printf("l2test - L2CAP testing\n" + printf("rctest - RFCOMM testing\n" "Usage:\n"); - printf("\tl2test [options] [bdaddr]\n"); + printf("\trctest [options] [bdaddr]\n"); printf("Modes:\n" "\t-r listen and receive\n" "\t-w listen and send\n" @@ -310,7 +310,6 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P channel]\n" "\t[-I imtu] [-O omtu]\n" - "\t[-D] use connectionless channel (datagram)\n" "\t[-E] request encryption\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); @@ -418,7 +417,7 @@ int main(int argc ,char *argv[]) sa.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &sa, NULL); - openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); + openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0); switch( mode ){ case RECV: -- cgit From 74ec9c1b4330e9faf5e922e1b1821e4d658fd02e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 6 Sep 2002 17:35:26 +0000 Subject: rfcomm needs different error detection code. --- tools/rctest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/rctest.c b/tools/rctest.c index af34b3f7..a3eefd6f 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -212,7 +212,7 @@ void recv_mode(int s) strerror(errno), errno); return; } - +#if 0 /* Check sequence */ sq = btohl(*(uint32_t *)buf); if (seq != sq) { @@ -233,7 +233,7 @@ void recv_mode(int s) if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); } - +#endif total += r; } gettimeofday(&tv_end,NULL); -- cgit From f93bdd3e8438c165bc3ba98dc1730d2701f98bfc Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 9 Sep 2002 16:27:39 +0000 Subject: BCSP fixes --- tools/hciattach.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index ca81117b..cee27e46 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -77,6 +77,8 @@ static int uart_speed(int s) return B460800; case 921600: return B921600; + case 1000000: + return B1000000; default: return B57600; } @@ -233,18 +235,88 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) */ static int bcsp(int fd, struct uart_t *u, struct termios *ti) { - ti->c_cflag &= ~CBAUD; - ti->c_cflag |= B115200 | CS8 | CLOCAL | PARENB; - ti->c_cflag &= ~(PARODD|CRTSCTS); + unsigned char byte, bcsph[4], bcspp[4], + bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}, + bcsp_sync_resp_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xac,0xaf,0xef,0xee,0xc0}, + bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}, + bcsp_conf_resp_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xde,0xad,0xd0,0xd0,0xc0}, + bcspsync[4] = {0xda, 0xdc, 0xed, 0xed}, + bcspsyncresp[4] = {0xac,0xaf,0xef,0xee}, + bcspconf[4] = {0xad,0xef,0xac,0xed}, + bcspconfresp[4] = {0xde,0xad,0xd0,0xd0}; + int sync_sent = 0; + + if (set_speed(fd, ti, u->speed) < 0) { + perror("Can't set default baud rate"); + return -1; + } - ti->c_oflag = 0; /* turn off output processing */ - ti->c_lflag = 0; /* no local modes */ + ti->c_cflag |= PARENB; + ti->c_cflag &= ~(PARODD); if (tcsetattr(fd, TCSANOW, ti) < 0) { perror("Can't set port settings"); return -1; } + /* State = shy */ + + while (1) { + do { + read(fd, &byte, 1); + } while(byte != 0xC0); + + do { + read(fd, &bcsph[0], 1); + } while(bcsph[0] == 0xC0); + + read(fd, &bcsph[1], 3); + if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) + continue; + if (bcsph[1] != 0x41 || bcsph[2] != 0x00) + continue; + + read(fd, &bcspp, 4); + if (!memcmp(bcspp, bcspsync, 4)) { + write(fd, &bcsp_sync_resp_pkt,10); + if (!sync_sent) { + write(fd, &bcsp_sync_pkt, 10); /* muzzled = false */ + sync_sent = 1; + } + } else if (!memcmp(bcspp, bcspsyncresp, 4)) + break; + } + + /* State = curious */ + + write(fd, &bcsp_conf_pkt, 10); + while (1) { + do { + read(fd, &byte, 1); + } while(byte != 0xC0); + + do { + read(fd, &bcsph[0], 1); + } while(bcsph[0] == 0xC0); + + read(fd, &bcsph[1], 3); + if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) + continue; + + if (bcsph[1] != 0x41 || bcsph[2] != 0x00) + continue; + + read(fd, &bcspp, 4); + if (!memcmp(bcspp, bcspsync, 4)) + write(fd, &bcsp_sync_resp_pkt, 10); + else if (!memcmp(bcspp, bcspconf, 4)) + write(fd, &bcsp_conf_resp_pkt, 10); + else if (!memcmp(bcspp, bcspconfresp, 4)) + break; + } + + /* State = garrulous */ + return 0; } @@ -763,7 +835,7 @@ int main(int argc, char *argv[]) sa.sa_handler = sig_alarm; sigaction(SIGALRM, &sa, NULL); - /* 5 seconds should be enought for intialization */ + /* 5 seconds should be enough for intialization */ alarm(to); n = init_uart(dev, u); -- cgit From 068ed1258ab388bfa6d554da9376375ecc673686 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 12 Sep 2002 02:00:37 +0000 Subject: channel must be uint8 --- tools/rctest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/rctest.c b/tools/rctest.c index a3eefd6f..388195a7 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -66,7 +66,7 @@ long data_size = 127; /* Default addr and channel */ bdaddr_t bdaddr; -unsigned short channel = 10; +uint8_t channel = 10; int master = 0; int auth = 0; @@ -99,7 +99,7 @@ int do_connect(char *svr) memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.rc_family = AF_BLUETOOTH; baswap(&rem_addr.rc_bdaddr, strtoba(svr)); - rem_addr.rc_channel = htobs(channel); + rem_addr.rc_channel = channel; if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); @@ -124,7 +124,7 @@ void do_listen( void (*handler)(int sk) ) loc_addr.rc_family = AF_BLUETOOTH; loc_addr.rc_bdaddr = bdaddr; - loc_addr.rc_channel = htobs(channel); + loc_addr.rc_channel = channel; if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); -- cgit From 8f511c20f7f6b0b59316bdb84ff444ccbc918242 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sun, 15 Sep 2002 17:13:40 +0000 Subject: get link quality support --- tools/hcitool.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 34a9f5a4..730605db 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -785,6 +785,91 @@ static void cmd_rssi(int dev_id, int argc, char **argv) free(cr); } +/* Get Link Quality */ + +static struct option link_quality_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *link_quality_help = + "Usage:\n" + "\tlq \n"; + +static void cmd_link_quality(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + get_link_quality_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, link_quality_options, NULL) { + switch(opt) { + default: + printf(link_quality_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(link_quality_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_GET_LINK_QUALITY; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = GET_LINK_QUALITY_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI get_link_quality request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + printf("Link quality: %d\n", rp.link_quality); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -865,7 +950,6 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } - struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -882,6 +966,7 @@ struct { { "dc", cmd_dc, "Disconnect from remote device" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_link_quality, "Display link quality" }, { NULL, NULL, 0} }; -- cgit From 2af38a90ac802ab706ed984b3105ada22d6f060d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 26 Sep 2002 05:13:23 +0000 Subject: BCSP initialization improvements --- tools/hciattach.c | 134 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 25 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index cee27e46..78deb53b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -230,21 +230,67 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) return 0; } +static int read_check(int fd, void *buf, int count) +{ + int res; + + do{ + res = read(fd, buf, count); + if (res != -1) { + buf += res; count -= res; + } + } while (count && (errno == 0 || errno == EINTR)); + + if (count) + return -1; + + return 0; +} + /* * BCSP specific initialization */ +int serial_fd; + +static void bcsp_tshy_sig_alarm(int sig) +{ + static int retries=0; + unsigned char bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}; + + if (retries < 10) { + retries++; + write(serial_fd, &bcsp_sync_pkt, 10); + alarm(1); + return; + } + fprintf(stderr, "BCSP initialization timed out\n"); + exit(1); +} + +static void bcsp_tconf_sig_alarm(int sig) +{ + static int retries=0; + unsigned char bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}; + if (retries < 10){ + retries++; + write(serial_fd, &bcsp_conf_pkt, 10); + alarm(1); + return; + } + fprintf(stderr, "BCSP initialization timed out\n"); + exit(1); +} + static int bcsp(int fd, struct uart_t *u, struct termios *ti) { unsigned char byte, bcsph[4], bcspp[4], - bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}, bcsp_sync_resp_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xac,0xaf,0xef,0xee,0xc0}, - bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}, bcsp_conf_resp_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xde,0xad,0xd0,0xd0,0xc0}, - bcspsync[4] = {0xda, 0xdc, 0xed, 0xed}, + bcspsync[4] = {0xda, 0xdc, 0xed, 0xed}, bcspsyncresp[4] = {0xac,0xaf,0xef,0xee}, - bcspconf[4] = {0xad,0xef,0xac,0xed}, + bcspconf[4] = {0xad,0xef,0xac,0xed}, bcspconfresp[4] = {0xde,0xad,0xd0,0xd0}; - int sync_sent = 0; + struct sigaction sa; if (set_speed(fd, ti, u->speed) < 0) { perror("Can't set default baud rate"); @@ -259,54 +305,92 @@ static int bcsp(int fd, struct uart_t *u, struct termios *ti) return -1; } + alarm(0); + + serial_fd = fd; + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = bcsp_tshy_sig_alarm; + sigaction(SIGALRM, &sa, NULL); + /* State = shy */ + bcsp_tshy_sig_alarm(0); while (1) { do { - read(fd, &byte, 1); - } while(byte != 0xC0); + if (read_check(fd, &byte, 1) == -1){ + perror("Failed to read"); + return -1; + } + } while (byte != 0xC0); do { - read(fd, &bcsph[0], 1); - } while(bcsph[0] == 0xC0); + if ( read_check(fd, &bcsph[0], 1) == -1){ + perror("Failed to read"); + return -1; + } + + } while (bcsph[0] == 0xC0); + + if ( read_check(fd, &bcsph[1], 3) == -1){ + perror("Failed to read"); + return -1; + } - read(fd, &bcsph[1], 3); if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) - continue; + continue; if (bcsph[1] != 0x41 || bcsph[2] != 0x00) - continue; - - read(fd, &bcspp, 4); + continue; + + if (read_check(fd, &bcspp, 4) == -1){ + perror("Failed to read"); + return -1; + } + if (!memcmp(bcspp, bcspsync, 4)) { write(fd, &bcsp_sync_resp_pkt,10); - if (!sync_sent) { - write(fd, &bcsp_sync_pkt, 10); /* muzzled = false */ - sync_sent = 1; - } } else if (!memcmp(bcspp, bcspsyncresp, 4)) break; } /* State = curious */ - write(fd, &bcsp_conf_pkt, 10); + alarm(0); + sa.sa_handler = bcsp_tconf_sig_alarm; + sigaction(SIGALRM, &sa, NULL); + alarm(1); + while (1) { do { - read(fd, &byte, 1); - } while(byte != 0xC0); + if (read_check(fd, &byte, 1) == -1){ + perror("Failed to read"); + return -1; + } + } while (byte != 0xC0); do { - read(fd, &bcsph[0], 1); - } while(bcsph[0] == 0xC0); + if (read_check(fd, &bcsph[0], 1) == -1){ + perror("Failed to read"); + return -1; + } + } while (bcsph[0] == 0xC0); - read(fd, &bcsph[1], 3); + if (read_check(fd, &bcsph[1], 3) == -1){ + perror("Failed to read"); + return -1; + } + if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) continue; if (bcsph[1] != 0x41 || bcsph[2] != 0x00) continue; - read(fd, &bcspp, 4); + if (read_check(fd, &bcspp, 4) == -1){ + perror("Failed to read"); + return -1; + } + if (!memcmp(bcspp, bcspsync, 4)) write(fd, &bcsp_sync_resp_pkt, 10); else if (!memcmp(bcspp, bcspconf, 4)) -- cgit From ee48a96c55129102d78383e461f785ca5fd005ef Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 7 Oct 2002 05:54:34 +0000 Subject: cleanup. --- tools/rctest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/rctest.c b/tools/rctest.c index 388195a7..0584a6a9 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -202,9 +202,9 @@ void recv_mode(int s) gettimeofday(&tv_beg,NULL); total = 0; while (total < data_size) { - uint32_t sq; - uint16_t l; - int i,r; + //uint32_t sq; + //uint16_t l; + int r; if ((r = recv(s, buf, data_size, 0)) <= 0) { if (r < 0) -- cgit From 8c6e7af8ac997ce101009569e3bdaee231e8fb12 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 7 Oct 2002 05:55:21 +0000 Subject: Add for get/set link supervision timeout. --- tools/hcitool.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 730605db..ec6f007a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -886,6 +886,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) struct hci_conn_info_req *cr; struct hci_request rq; set_conn_ptype_cp cp; + evt_conn_ptype_changed rp; bdaddr_t bdaddr; int opt, dd, ptype; @@ -936,10 +937,13 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; rq.clen = SET_CONN_PTYPE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE; + rq.event = EVT_CONN_PTYPE_CHANGED; if (hci_send_req(dd, &rq, 100) < 0) { perror("Packet type change failed"); @@ -950,6 +954,113 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } +/* Get/Set Link Supervision Timeout */ + +static struct option link_supervision_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *link_supervision_help = + "Usage:\n" + "\tlst [new value in slots]\n"; + +static void cmd_link_sup_to(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_link_supervision_timeout_rp rp; + write_link_supervision_timeout_cp cp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, link_supervision_options, NULL) { + switch(opt) { + default: + printf(link_supervision_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(link_supervision_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (argc == 1) { + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read_link_supervision_timeout request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_link_supervision_timeout failed (0x%2.2X)\n", + rp.status); + exit(1); + } + if (rp.link_sup_to) + printf("Link supervision timeout: %u slots (%.2f msec)\n", + rp.link_sup_to, (float)rp.link_sup_to * 0.625); + else + printf("Link supervision timeout never expires\n"); + } + else { + cp.handle = cr->conn_info->handle; + cp.link_sup_to = strtol(argv[1], NULL, 10); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cp; + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI write_link_supervision_timeout request failed"); + exit(1); + } + } + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -967,6 +1078,7 @@ struct { { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_link_quality, "Display link quality" }, + { "lst", cmd_link_sup_to, "Set/display link supervision timeout" }, { NULL, NULL, 0} }; -- cgit From 342bdf14bfe6340a8fcf6b6a412685a94ad843b5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2002 18:56:06 +0000 Subject: Add ppporc program --- tools/Makefile.am | 2 +- tools/ppporc.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 tools/ppporc.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 281be99e..b4049c32 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -9,6 +9,6 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -noinst_PROGRAMS = l2test scotest rctest +noinst_PROGRAMS = ppporc l2test scotest rctest EXTRA_DIST = $(man_MANS) diff --git a/tools/ppporc.c b/tools/ppporc.c new file mode 100644 index 00000000..514ceb65 --- /dev/null +++ b/tools/ppporc.c @@ -0,0 +1,282 @@ +/* + * + * PPP over Bluetooth RFCOMM + * + * Copyright (C) 2002 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +extern int optind, opterr, optopt; +extern char *optarg; + + +/* IO cancelation */ +static volatile sig_atomic_t __io_canceled; + +static inline void io_init(void) +{ + __io_canceled = 0; +} + +static inline void io_cancel(void) +{ + __io_canceled = 1; +} + + +/* Signal functions */ +static void sig_hup(int sig) +{ + return; +} + +static void sig_term(int sig) +{ + syslog(LOG_INFO, "Closing RFCOMM channel"); + io_cancel(); +} + + +/* Read exactly len bytes (Signal safe)*/ +static inline int read_n(int fd, char *buf, int len) +{ + register int t = 0, w; + + while (!__io_canceled && len > 0) { + if ((w = read(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; + buf += w; + t += w; + } + + return t; +} + + +/* Write exactly len bytes (Signal safe)*/ +static inline int write_n(int fd, char *buf, int len) +{ + register int t = 0, w; + + while (!__io_canceled && len > 0) { + if ((w = write(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; + buf += w; + t += w; + } + + return t; +} + + +/* Create the RFCOMM connection */ +static int create_connection(bdaddr_t *bdaddr, uint8_t channel) +{ + struct sockaddr_rc remote_addr, local_addr; + int fd, err; + + if ((fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) + return fd; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.rc_family = AF_BLUETOOTH; + bacpy(&local_addr.rc_bdaddr, BDADDR_ANY); + if ((err = bind(fd, (struct sockaddr *)&local_addr, sizeof(local_addr))) < 0) { + close(fd); + return err; + } + + memset(&remote_addr, 0, sizeof(remote_addr)); + remote_addr.rc_family = AF_BLUETOOTH; + bacpy(&remote_addr.rc_bdaddr, bdaddr); + remote_addr.rc_channel = channel; + if ((err = connect(fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr))) < 0) { + close(fd); + return err; + } + + syslog(LOG_INFO, "RFCOMM channel %d connected", channel); + + return fd; +} + + +/* Process the data from socket and pseudo tty */ +static int process_data(int fd) +{ + struct pollfd p[2]; + char buf[1024]; + int err, r; + + p[0].fd = 0; + p[0].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; + + p[1].fd = fd; + p[1].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; + + err = 0; + + while (!__io_canceled) { + p[0].revents = 0; + p[1].revents = 0; + + err = poll(p, 2, -1); + if (err < 0) + break; + + err = 0; + + if (p[0].revents) { + if (p[0].revents & (POLLERR | POLLHUP | POLLNVAL)) + break; + r = read(0, buf, sizeof(buf)); + if (r < 0) { + if (errno != EINTR && errno != EAGAIN) { + err = r; + break; + } + } + + err = write_n(fd, buf, r); + if (err < 0) + break; + } + + if (p[1].revents) { + if (p[1].revents & (POLLERR | POLLHUP | POLLNVAL)) + break; + r = read(fd, buf, sizeof(buf)); + if (r < 0) { + if (errno != EINTR && errno != EAGAIN) { + err = r; + break; + } + } + + err = write_n(1, buf, r); + if (err < 0) + break; + } + } + + return err; +} + + +static void usage(void) +{ + printf("Usage:\tppporc [channel]\n"); +} + + +int main(int argc, char** argv) +{ + struct sigaction sa; + int fd, err, opt; + + bdaddr_t bdaddr; + uint8_t channel; + + + /* Parse command line options */ + while ((opt = getopt(argc, argv, "h")) != EOF) { + switch(opt) { + case 'h': + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + + switch (argc) { + case 1: + str2ba(argv[0], &bdaddr); + channel = 1; + break; + case 2: + str2ba(argv[0], &bdaddr); + channel = atoi(argv[1]); + break; + default: + usage(); + exit(0); + } + + + /* Initialize syslog */ + openlog("ppporc", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); + syslog(LOG_INFO, "PPP over RFCOMM"); + + + /* Initialize signals */ + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + + syslog(LOG_INFO, "Connecting to %s", argv[0]); + + if ((fd = create_connection(&bdaddr, channel)) < 0) { + syslog(LOG_ERR, "Can't connect to remote device (%s)", strerror(errno)); + return fd; + } + + err = process_data(fd); + + close(fd); + + return err; +} -- cgit From b5edb3c0a92674b27a95f7968e18bb51150c52f6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2002 20:46:47 +0000 Subject: Move testing programs from tools directory into the test directory --- tools/Makefile.am | 2 +- tools/l2test.c | 530 ------------------------------------------------------ tools/rctest.c | 469 ----------------------------------------------- tools/scotest.c | 358 ------------------------------------ 4 files changed, 1 insertion(+), 1358 deletions(-) delete mode 100644 tools/l2test.c delete mode 100644 tools/rctest.c delete mode 100644 tools/scotest.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index b4049c32..9ff29c14 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -9,6 +9,6 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -noinst_PROGRAMS = ppporc l2test scotest rctest +noinst_PROGRAMS = ppporc EXTRA_DIST = $(man_MANS) diff --git a/tools/l2test.c b/tools/l2test.c deleted file mode 100644 index b08b2d34..00000000 --- a/tools/l2test.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* Test modes */ -enum { - SEND, - RECV, - RECONNECT, - MULTY, - DUMP, - CONNECT, - CRECV, - LSEND -}; - -unsigned char *buf; - -/* Default mtu */ -int imtu = 672; -int omtu = 0; - -/* Default data size */ -long data_size = 672; - -/* Default addr and psm */ -bdaddr_t bdaddr; -unsigned short psm = 10; - -int master = 0; -int auth = 0; -int encrypt = 0; -int socktype = SOCK_SEQPACKET; - -float tv2fl(struct timeval tv) -{ - return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); -} - -int do_connect(char *svr) -{ - struct sockaddr_l2 rem_addr, loc_addr; - struct l2cap_options opts; - int s, opt; - - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - return -1; - } - - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.l2_family = AF_BLUETOOTH; - loc_addr.l2_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - /* Get default options */ - opt = sizeof(opts); - if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { - syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); - return -1; - } - - /* Set new options */ - opts.omtu = omtu; - opts.imtu = imtu; - if( setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0 ) { - syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); - return -1; - } - - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.l2_family = AF_BLUETOOTH; - baswap(&rem_addr.l2_bdaddr, strtoba(svr)); - rem_addr.l2_psm = htobs(psm); - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); - close(s); - return -1; - } - - opt = sizeof(opts); - if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ - syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); - close(s); - return -1; - } - - syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d]\n", - opts.imtu, opts.omtu, opts.flush_to); - - return s; -} - -void do_listen( void (*handler)(int sk) ) -{ - struct sockaddr_l2 loc_addr, rem_addr; - struct l2cap_options opts; - int s, s1, opt; - bdaddr_t ba; - - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - loc_addr.l2_family = AF_BLUETOOTH; - loc_addr.l2_bdaddr = bdaddr; - loc_addr.l2_psm = htobs(psm); - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - /* Set link mode */ - opt = 0; - if (master) - opt |= L2CAP_LM_MASTER; - - if (auth) - opt |= L2CAP_LM_AUTH; - - if (encrypt) - opt |= L2CAP_LM_ENCRYPT; - - if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); - exit(1); - } - - /* Get default options */ - opt = sizeof(opts); - if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); - exit(1); - } - - /* Set new options */ - opts.imtu = imtu; - if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); - exit(1); - } - - if (socktype == SOCK_DGRAM) { - handler(s); - return; - } - - if( listen(s, 10) ) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - syslog(LOG_INFO,"Waiting for connection on psm %d ...", psm); - - while(1) { - opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); - exit(1); - } - if( fork() ) { - /* Parent */ - close(s1); - continue; - } - /* Child */ - - close(s); - - opt = sizeof(opts); - if( getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { - syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); - exit(1); - } - - baswap(&ba, &rem_addr.l2_bdaddr); - syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", - batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); - - handler(s1); - - syslog(LOG_INFO, "Disconnect\n"); - exit(0); - } -} - -void dump_mode(int s) -{ - int len; - - syslog(LOG_INFO, "Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); -} - -void recv_mode(int s) -{ - struct timeval tv_beg,tv_end,tv_diff; - long total; - uint32_t seq; - - syslog(LOG_INFO,"Receiving ..."); - - seq = 0; - while (1) { - gettimeofday(&tv_beg,NULL); - total = 0; - while (total < data_size) { - uint32_t sq; - uint16_t l; - int i,r; - - if ((r = recv(s, buf, data_size, 0)) <= 0) { - if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); - return; - } - - /* Check sequence */ - sq = btohl(*(uint32_t *)buf); - if (seq != sq) { - syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); - seq = sq; - } - seq++; - - /* Check length */ - l = btohs(*(uint16_t *)(buf+4)); - if (r != l) { - syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); - continue; - } - - /* Verify data */ - for (i=6; i < r; i++) { - if (buf[i] != 0x7f) - syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); - } - - total += r; - } - gettimeofday(&tv_end,NULL); - - timersub(&tv_end,&tv_beg,&tv_diff); - - syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, - tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); - } -} - -void send_mode(int s) -{ - uint32_t seq; - int i; - - syslog(LOG_INFO,"Sending ..."); - - for(i=6; i < data_size; i++) - buf[i]=0x7f; - - seq = 0; - while (1) { - *(uint32_t *) buf = htobl(seq++); - *(uint16_t *)(buf+4) = htobs(data_size); - - if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); - exit(1); - } - } -} - -void reconnect_mode(char *svr) -{ - while(1) { - int s = do_connect(svr); - close(s); - } -} - -void connect_mode(char *svr) -{ - int s; - if ((s = do_connect(svr)) < 0) - exit(1); - sleep(99999999); -} - -void multi_connect_mode(char *svr) -{ - while (1) { - int i, s; - for (i=0; i<10; i++) { - if (fork()) continue; - - /* Child */ - s = do_connect(svr); - usleep(500); - close(s); - exit(0); - } - sleep(2); - } -} - -void usage(void) -{ - printf("l2test - L2CAP testing\n" - "Usage:\n"); - printf("\tl2test [options] [bdaddr]\n"); - printf("Modes:\n" - "\t-r listen and receive\n" - "\t-w listen and send\n" - "\t-d listen and dump incomming data\n" - "\t-s connect and send\n" - "\t-u connect and receive\n" - "\t-n connect and be silent\n" - "\t-c connect, disconnect, connect, ...\n" - "\t-m multiple connects\n"); - - printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P psm]\n" - "\t[-I imtu] [-O omtu]\n" - "\t[-D] use connectionless channel (datagram)\n" - "\t[-E] request encryption\n" - "\t[-E] request encryption\n" - "\t[-M] become master\n"); -} - -extern int optind,opterr,optopt; -extern char *optarg; - -int main(int argc ,char *argv[]) -{ - int opt, mode, s, need_addr; - struct sigaction sa; - - mode = RECV; need_addr = 0; - - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAED")) != EOF) { - switch(opt) { - case 'r': - mode = RECV; - break; - - case 's': - mode = SEND; - need_addr = 1; - break; - - case 'w': - mode = LSEND; - break; - - case 'u': - mode = CRECV; - need_addr = 1; - break; - - case 'd': - mode = DUMP; - break; - - case 'c': - mode = RECONNECT; - need_addr = 1; - break; - - case 'n': - mode = CONNECT; - need_addr = 1; - break; - - case 'm': - mode = MULTY; - need_addr = 1; - break; - - case 'b': - data_size = atoi(optarg); - break; - - case 'S': - baswap(&bdaddr, strtoba(optarg)); - break; - - case 'P': - psm = atoi(optarg); - break; - - case 'I': - imtu = atoi(optarg); - break; - - case 'O': - omtu = atoi(optarg); - break; - - case 'M': - master = 1; - break; - - case 'A': - auth = 1; - break; - - case 'E': - encrypt = 1; - break; - - case 'D': - socktype = SOCK_DGRAM; - break; - - default: - usage(); - exit(1); - } - } - - if (need_addr && !(argc - optind)) { - usage(); - exit(1); - } - - if (!(buf = malloc(data_size))) { - perror("Can't allocate data buffer"); - exit(1); - } - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - sa.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &sa, NULL); - - openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); - - switch( mode ){ - case RECV: - do_listen(recv_mode); - break; - - case CRECV: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - recv_mode(s); - break; - - case DUMP: - do_listen(dump_mode); - break; - - case SEND: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - send_mode(s); - break; - - case LSEND: - do_listen(send_mode); - break; - - case RECONNECT: - reconnect_mode(argv[optind]); - break; - - case MULTY: - multi_connect_mode(argv[optind]); - break; - - case CONNECT: - connect_mode(argv[optind]); - break; - } - syslog(LOG_INFO, "Exit"); - - closelog(); - - return 0; -} diff --git a/tools/rctest.c b/tools/rctest.c deleted file mode 100644 index 0584a6a9..00000000 --- a/tools/rctest.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - RFCOMM test tool - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* Test modes */ -enum { - SEND, - RECV, - RECONNECT, - MULTY, - DUMP, - CONNECT, - CRECV, - LSEND -}; - -unsigned char *buf; - -/* Default mtu */ -int imtu = 672; -int omtu = 0; - -/* Default data size */ -long data_size = 127; - -/* Default addr and channel */ -bdaddr_t bdaddr; -uint8_t channel = 10; - -int master = 0; -int auth = 0; -int encrypt = 0; -int socktype = SOCK_STREAM; - -float tv2fl(struct timeval tv) -{ - return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); -} - -int do_connect(char *svr) -{ - struct sockaddr_rc rem_addr, loc_addr; - int s; - - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - return -1; - } - - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.rc_family = AF_BLUETOOTH; - loc_addr.rc_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.rc_family = AF_BLUETOOTH; - baswap(&rem_addr.rc_bdaddr, strtoba(svr)); - rem_addr.rc_channel = channel; - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); - close(s); - return -1; - } - - syslog(LOG_INFO, "Connected"); - - return s; -} - -void do_listen( void (*handler)(int sk) ) -{ - struct sockaddr_rc loc_addr, rem_addr; - int s, s1, opt; - bdaddr_t ba; - - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - loc_addr.rc_family = AF_BLUETOOTH; - loc_addr.rc_bdaddr = bdaddr; - loc_addr.rc_channel = channel; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - -#if 0 - /* Set link mode */ - opt = 0; - if (master) - opt |= L2CAP_LM_MASTER; - - if (auth) - opt |= L2CAP_LM_AUTH; - - if (encrypt) - opt |= L2CAP_LM_ENCRYPT; - - if (setsockopt(s, SOL_RFCOMM, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); - exit(1); - } -#endif - - if( listen(s, 10) ) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - syslog(LOG_INFO,"Waiting for connection on channel %d ...", channel); - - while(1) { - opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); - exit(1); - } - if( fork() ) { - /* Parent */ - close(s1); - continue; - } - /* Child */ - - close(s); - - baswap(&ba, &rem_addr.rc_bdaddr); - syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); - - handler(s1); - - syslog(LOG_INFO, "Disconnect\n"); - exit(0); - } -} - -void dump_mode(int s) -{ - int len; - - syslog(LOG_INFO, "Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); -} - -void recv_mode(int s) -{ - struct timeval tv_beg,tv_end,tv_diff; - long total; - uint32_t seq; - - syslog(LOG_INFO,"Receiving ..."); - - seq = 0; - while (1) { - gettimeofday(&tv_beg,NULL); - total = 0; - while (total < data_size) { - //uint32_t sq; - //uint16_t l; - int r; - - if ((r = recv(s, buf, data_size, 0)) <= 0) { - if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); - return; - } -#if 0 - /* Check sequence */ - sq = btohl(*(uint32_t *)buf); - if (seq != sq) { - syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); - seq = sq; - } - seq++; - - /* Check length */ - l = btohs(*(uint16_t *)(buf+4)); - if (r != l) { - syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); - continue; - } - - /* Verify data */ - for (i=6; i < r; i++) { - if (buf[i] != 0x7f) - syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); - } -#endif - total += r; - } - gettimeofday(&tv_end,NULL); - - timersub(&tv_end,&tv_beg,&tv_diff); - - syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, - tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); - } -} - -void send_mode(int s) -{ - uint32_t seq; - int i; - - syslog(LOG_INFO,"Sending ..."); - - for(i=6; i < data_size; i++) - buf[i]=0x7f; - - seq = 0; - while (1) { - *(uint32_t *) buf = htobl(seq++); - *(uint16_t *)(buf+4) = htobs(data_size); - - if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); - exit(1); - } - } -} - -void reconnect_mode(char *svr) -{ - while(1) { - int s = do_connect(svr); - close(s); - } -} - -void multi_connect_mode(char *svr) -{ - while (1) { - int i, s; - for (i=0; i<10; i++) { - if (fork()) continue; - - /* Child */ - s = do_connect(svr); - usleep(500); - close(s); - exit(0); - } - sleep(2); - } -} - -void usage(void) -{ - printf("rctest - RFCOMM testing\n" - "Usage:\n"); - printf("\trctest [options] [bdaddr]\n"); - printf("Modes:\n" - "\t-r listen and receive\n" - "\t-w listen and send\n" - "\t-d listen and dump incomming data\n" - "\t-s connect and send\n" - "\t-u connect and receive\n" - "\t-n connect and be silent\n" - "\t-c connect, disconnect, connect, ...\n" - "\t-m multiple connects\n"); - - printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P channel]\n" - "\t[-I imtu] [-O omtu]\n" - "\t[-E] request encryption\n" - "\t[-E] request encryption\n" - "\t[-M] become master\n"); -} - -extern int optind,opterr,optopt; -extern char *optarg; - -int main(int argc ,char *argv[]) -{ - int opt, mode, s, need_addr; - struct sigaction sa; - - mode = RECV; need_addr = 0; - - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { - switch(opt) { - case 'r': - mode = RECV; - break; - - case 's': - mode = SEND; - need_addr = 1; - break; - - case 'w': - mode = LSEND; - break; - - case 'u': - mode = CRECV; - need_addr = 1; - break; - - case 'd': - mode = DUMP; - break; - - case 'c': - mode = RECONNECT; - need_addr = 1; - break; - - case 'n': - mode = CONNECT; - need_addr = 1; - break; - - case 'm': - mode = MULTY; - need_addr = 1; - break; - - case 'b': - data_size = atoi(optarg); - break; - - case 'S': - baswap(&bdaddr, strtoba(optarg)); - break; - - case 'P': - channel = atoi(optarg); - break; - - case 'I': - imtu = atoi(optarg); - break; - - case 'O': - omtu = atoi(optarg); - break; - - case 'M': - master = 1; - break; - - case 'A': - auth = 1; - break; - - case 'E': - encrypt = 1; - break; - - default: - usage(); - exit(1); - } - } - - if (need_addr && !(argc - optind)) { - usage(); - exit(1); - } - - if (!(buf = malloc(data_size))) { - perror("Can't allocate data buffer"); - exit(1); - } - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - sa.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &sa, NULL); - - openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0); - - switch( mode ){ - case RECV: - do_listen(recv_mode); - break; - - case CRECV: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - recv_mode(s); - break; - - case DUMP: - do_listen(dump_mode); - break; - - case SEND: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - send_mode(s); - break; - - case LSEND: - do_listen(send_mode); - break; - - case RECONNECT: - reconnect_mode(argv[optind]); - break; - - case MULTY: - multi_connect_mode(argv[optind]); - break; - - case CONNECT: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - dump_mode(s); - break; - } - syslog(LOG_INFO, "Exit"); - - closelog(); - - return 0; -} diff --git a/tools/scotest.c b/tools/scotest.c deleted file mode 100644 index dcb1acdf..00000000 --- a/tools/scotest.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* Test modes */ -enum { - SEND, - RECV, - RECONNECT, - MULTY, - DUMP -}; - -unsigned char *buf; - -/* Default data size */ -long data_size = 672; - -bdaddr_t bdaddr; - -float tv2fl(struct timeval tv) -{ - return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); -} - -int do_connect(char *svr) -{ - struct sockaddr_sco rem_addr, loc_addr; - int s; - - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - return -1; - } - - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.sco_family = AF_BLUETOOTH; - loc_addr.sco_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.sco_family = AF_BLUETOOTH; - baswap(&rem_addr.sco_bdaddr, strtoba(svr)); - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); - return -1; - } - - syslog(LOG_INFO, "Connected\n"); - - return s; -} - -void do_listen( void (*handler)(int sk) ) -{ - struct sockaddr_sco loc_addr, rem_addr; - int s, s1, opt; - bdaddr_t ba; - - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - loc_addr.sco_family = AF_BLUETOOTH; - loc_addr.sco_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - if( listen(s, 10) ) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - syslog(LOG_INFO,"Waiting for connection ..."); - - while(1) { - opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); - exit(1); - } - if( fork() ) { - /* Parent */ - close(s1); - continue; - } - /* Child */ - - close(s); - - baswap(&ba, &rem_addr.sco_bdaddr); - syslog(LOG_INFO, "Connect from %s\n", batostr(&ba)); - - handler(s1); - - syslog(LOG_INFO, "Disconnect\n"); - exit(0); - } -} - -void dump_mode(int s) -{ - int len; - - syslog(LOG_INFO,"Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); -} - -void recv_mode(int s) -{ - struct timeval tv_beg,tv_end,tv_diff; - long total; - uint32_t seq; - - syslog(LOG_INFO, "Receiving ..."); - - seq = 0; - while (1) { - gettimeofday(&tv_beg,NULL); - total = 0; - while (total < data_size) { - int r; - if ((r = recv(s, buf, data_size, 0)) <= 0) { - if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); - return; - } - total += r; - } - gettimeofday(&tv_end,NULL); - - timersub(&tv_end,&tv_beg,&tv_diff); - - syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb",total, - tv2fl(tv_diff) / 60.0, - (float)( total / tv2fl(tv_diff) ) / 1024.0 ); - } -} - -void send_mode(char *svr) -{ - struct sco_options so; - uint32_t seq; - int s, i, opt; - - if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", - strerror(errno), errno); - exit(1); - } - - opt = sizeof(so); - if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { - syslog(LOG_ERR, "Can't get SCO options. %s(%d)", - strerror(errno), errno); - exit(1); - } - - - syslog(LOG_INFO,"Sending ..."); - - for (i=6; i < so.mtu; i++) - buf[i]=0x7f; - - seq = 0; - while (1) { - *(uint32_t *)buf = htobl(seq++); - *(uint16_t *)(buf+4) = htobs(data_size); - - if (send(s, buf, so.mtu, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", - strerror(errno), errno); - exit(1); - } - usleep(1); - } -} - -void reconnect_mode(char *svr) -{ - while(1){ - int s; - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); - exit(1); - } - close(s); - - sleep(5); - } -} - -void multy_connect_mode(char *svr) -{ - while(1){ - int i, s; - for(i=0; i<10; i++){ - if( fork() ) continue; - - /* Child */ - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); - } - close(s); - exit(0); - } - sleep(19); - } -} - -void usage(void) -{ - printf("scotest - SCO testing\n" - "Usage:\n"); - printf("\tscotest [-b bytes] [bd_addr]\n"); - printf("Modes:\n" - "\t-d dump (server)\n" - "\t-c reconnect (client)\n" - "\t-m multiple connects (client)\n" - "\t-r receive (server)\n" - "\t-s send (client)\n"); -} - -extern int optind,opterr,optopt; -extern char *optarg; - -int main(int argc ,char *argv[]) -{ - struct sigaction sa; - int opt, mode = RECV; - - while ((opt=getopt(argc,argv,"rdscmb:")) != EOF) { - switch(opt) { - case 'r': - mode = RECV; - break; - - case 's': - mode = SEND; - break; - - case 'd': - mode = DUMP; - break; - - case 'c': - mode = RECONNECT; - break; - - case 'm': - mode = MULTY; - break; - - case 'b': - data_size = atoi(optarg); - break; - - default: - usage(); - exit(1); - } - } - - if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { - usage(); - exit(1); - } - - if (!(buf = malloc(data_size))) { - perror("Can't allocate data buffer"); - exit(1); - } - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - sa.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &sa, NULL); - - openlog("scotest", LOG_PERROR | LOG_PID, LOG_LOCAL0); - - switch( mode ){ - case RECV: - do_listen(recv_mode); - break; - - case DUMP: - do_listen(dump_mode); - break; - - case SEND: - send_mode(argv[optind]); - break; - - case RECONNECT: - reconnect_mode(argv[optind]); - break; - - case MULTY: - multy_connect_mode(argv[optind]); - break; - } - syslog(LOG_INFO, "Exit"); - - closelog(); - - return 0; -} -- cgit From 878f8c349c5df588e512fbc0e76dfa7baf4b26db Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Nov 2002 18:58:24 +0000 Subject: Add check for (!opt) in cmd_aclmtu() and cmd_scomtu() --- tools/hciconfig.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index bbc61d0e..65512a09 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -259,7 +259,10 @@ void cmd_aclmtu(int ctl, int hdev, char *opt) { struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; - + + if (!opt) + return; + if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; @@ -277,7 +280,10 @@ void cmd_scomtu(int ctl, int hdev, char *opt) { struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; - + + if (!opt) + return; + if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; -- cgit From 951e7b0747a9bd29be7cf1fb886dd7a207cce1dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Nov 2002 01:44:53 +0000 Subject: Add new manpages and update the old ones --- tools/Makefile.am | 2 +- tools/hciattach.8 | 3 + tools/hciconfig.8 | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/hcitool.1 | 145 +++++++++++++++++++++++++++++++++++++ tools/l2ping.1 | 49 +++++++++++++ tools/l2ping.8 | 49 ------------- 6 files changed, 410 insertions(+), 50 deletions(-) create mode 100644 tools/hciconfig.8 create mode 100644 tools/hcitool.1 create mode 100644 tools/l2ping.1 delete mode 100644 tools/l2ping.8 (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 9ff29c14..0513c83b 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -7,7 +7,7 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping -man_MANS = hciattach.8 l2ping.8 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 noinst_PROGRAMS = ppporc diff --git a/tools/hciattach.8 b/tools/hciattach.8 index b327336b..812c40dc 100644 --- a/tools/hciattach.8 +++ b/tools/hciattach.8 @@ -59,6 +59,9 @@ BrainBoxes PCMCIA card (BL620) .TP swave Silicon Wave kits +.TP +bcsp +Serial adapters using CSR chips with BCSP serial protocol .RE Supported IDs are (manufacturer id, product id) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 new file mode 100644 index 00000000..bf13c2bd --- /dev/null +++ b/tools/hciconfig.8 @@ -0,0 +1,212 @@ +.TH HCICONFIG 1 "Nov 11 2002" BlueZ "Linux System Administration" +.SH NAME +hciconfig \- configure Bluetooth devices +.SH SYNOPSIS +.B hciconfig -h +.br +.B hciconfig [-a] +.br +.B hciconfig [-a] [command [command parameters]] + +.SH DESCRIPTION +.LP +.B +hciconfig +is used to configure Bluetooth devices. is the name of a Bluetooth +device installed in the system. If is not given, +.B +hciconfig +prints name and basic information about all the Bluetooth devices installed in +the system. If is given but no command is given, +it prints basic information on device only. Basic information is +interface type, BD address, ACL MTU, SCO MTU, flags (up, init, running, raw, +page scan enabled, inquiry scan enabled, inquiry, authentication enabled, +encryption enabled). +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands +.TP +.BI -a +Other than the basic info, print features, packet type, link policy, link mode, +name, class, version. +.SH COMMANDS +.TP +.BI up +Open and initialize HCI device +.TP +.BI down +Close HCI device +.TP +.BI reset +Reset HCI device +.TP +.BI rstat +Reset statistic counters +.TP +.BI auth +Enable authentication +.TP +.BI noauth +Disable authentication +.TP +.BI encrypt +Enable encryption +.TP +.BI noencrypt +Disable encryption +.TP +.BI piscan +Enable page and inquiry scan +.TP +.BI noscan +Disable page and inquiry scan +.TP +.BI iscan +Enable inquiry scan, disable page scan +.TP +.BI pscan +Enable page scan, disable inquiry scan +.TP +.BI ptype " [type]" +With no +.I +type +, displays the current packet types. Otherwise, all the packet types specified +by +.I +type +are set. +.I +type +is a comma-separated list of packet types, where the possible packet types are +.BR DM1 , +.BR DM3 , +.BR DM5 , +.BR DH1 , +.BR DH3 , +.BR DH5 , +.BR HV1 , +.BR HV2 , +.BR HV3 . +.TP +.BI name " [name]" +With no +.IR name , +prints local name. Otherwise, sets local name to +.IR name . +.TP +.BI class " [class]" +With no +.IR class , +prints class of device. Otherwise, sets class of device to +.IR class . +.I +class +is a 24-bit hex number describing the class of device, as specified in section +1.2 of the Bluetooth Assigned Numers document. +.TP +.BI inqparms " [win:int]" +With no +.IR win:int , +prints inquiry scan window and interval. Otherwise, sets inquiry scan window +to +.I win +slots and inquiry scan interval to +.I int +slots. +.TP +.BI pageparms " [win:int]" +With no +.IR win:int , +prints page scan window and interval. Otherwise, sets page scan window to +.I +win +slots and page scan interval to +.I +int +slots. +.TP +.BI pageto " [to]" +With no +.IR to , +prints page timeout. Otherwise, sets page timeout +to +.I +to +slots. +.TP +.BI aclmtu " " +Sets ACL MTU to +to +.I +mtu +bytes and ACL buffer size to +.I +pkt +packets. +.TP +.BI scomtu " " +Sets SCO MTU to +to +.I mtu +bytes and SCO buffer size to +.I pkt +packets. +.TP +.BI features +Display device features +.TP +.BI version +Display version information +.TP +.BI revision +Display revision information +.TP +.BI lm " [mode]" +With no +.I +mode +, prints link mode. +.B +MASTER +or +.B +SLAVE +mean, respectively, to ask to become master or to remain slave when a +connection request comes in. The additional keyword +.B +ACCEPT +means that baseband connections will be accepted even if there are no +listening +.I AF_BLUETOOTH +sockets. +.I mode +is +.B +NONE +or a comma-separated list of keywords, where possible keywords are +.B +MASTER +and +.B "ACCEPT" . +.B +NONE +sets link policy to the default behaviour of remaining slave and not accepting +baseband connections when there are no listening +.I AF_BLUETOOTH +sockets. If +.B +MASTER +is present, the device will ask to become master if a connection request comes +in. If +.B +ACCEPT +is present, the device will accept baseband connections even when there are no +listening +.I AF_BLUETOOTH +sockets +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Fabrizio Gennari diff --git a/tools/hcitool.1 b/tools/hcitool.1 new file mode 100644 index 00000000..49b5e715 --- /dev/null +++ b/tools/hcitool.1 @@ -0,0 +1,145 @@ +.TH HCITOOL 1 "Nov 12 2002" BlueZ "Linux System Administration" +.SH NAME +hcitool \- configure Bluetooth connections +.SH SYNOPSIS +.B hcitool [-h] +.br +.B hcitool [-i ] [command [command parameters]] + +.SH DESCRIPTION +.LP +.B +hcitool +is used to configure Bluetooth connections and send some special command to +Bluetooth devices. If no +.B +command +is given, or if the option +.B +-h +is used, +.B +hcitool +prints some usage information and exits. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands +.TP +.BI -i " " +The command is applied to device +.I +hciX +, which must be the name of an installed Bluetooth device. If not specified, +the command will be sent to the first available Bluetooth device. +.SH COMMANDS +.TP +.BI dev +Display local devices +.TP +.BI inq +Inquire remote devices. For each discovered device, Bluetooth device address, +clock offset and class are printed. +.TP +.BI scan +Inquire remote devices. For each discovered device, device name is printed. +.TP +.BI name " " +Print device name of remote device with Bluetooth address +.IR bdaddr . +.TP +.BI info " " +Print device name, version and supported features of remote device with +Bluetooth address +.IR bdaddr . +.TP +.BI cmd " [parameters]" +Submit an arbitrary HCI command to local device. +.IR ogf , +.IR ocf +and +.IR parameters +are hexadecimal bytes +.TP +.BI con +Display active baseband connections +.TP +.BI cc " [--role=m|s] [--pkt-type=] " +Create baseband connection to remote device with Bluetooth address +.IR bdaddr . +Option +.I +--pkt-type +specifies a list of allowed packet types. +.I + +is a comma-separated list of packet types, where the possible packet types are +.BR DM1 , +.BR DM3 , +.BR DM5 , +.BR DH1 , +.BR DH3 , +.BR DH5 , +.BR HV1 , +.BR HV2 , +.BR HV3 . +Default is to allow all packet types. Option +.I +--role +can have value +.I +m +(do not allow role switch, stay master) or +.I +s +(allow role switch, become slave if the peer asks to become master). Default is +.IR m . +.TP +.BI dc " " +Delete baseband connection from remote device with Bluetooth address +.IR bdaddr . +.TP +.BI cpt " " +Change packet types for baseband connection to device with Bluetooth address +.IR bdaddr . +.I +packet types +is a comma-separated list of packet types, where the possible packet types are +.BR DM1 , +.BR DM3 , +.BR DM5 , +.BR DH1 , +.BR DH3 , +.BR DH5 , +.BR HV1 , +.BR HV2 , +.BR HV3 . +.TP +.BI rssi " " +Display received signal strength information for the connection to the device +with Bluetooth address +.IR bdaddr . +.TP +.BI lq " " +Display link quality for the connection to the device with Bluetooth address +.IR bdaddr . +.TP +.BI lst " [value]" +With no +.IR value , +displays link supervision timeout for the connection to the device with Bluetooth address +.IR bdaddr . +If +.I +value +is given, sets the link supervision timeout for that connection to +.I +value +slots, or to infinite if +.I +value +is 0. +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Fabrizio Gennari diff --git a/tools/l2ping.1 b/tools/l2ping.1 new file mode 100644 index 00000000..186e5056 --- /dev/null +++ b/tools/l2ping.1 @@ -0,0 +1,49 @@ +.TH L2PING 1 "Jan 22 2002" BlueZ "Linux System Administration" +.SH NAME +l2ping \- Send L2CAP echo request and receive answer +.SH SYNOPSIS +.B l2ping +[ +.I -S source addr +] [ +.I -s size +] [ +.I -c count +] [ +.I -f +] < +.I bd_addr +> +.SH DESCRIPTION +.LP +L2ping sends a L2CAP echo request to the Bluetooth MAC address +.B bd_addr +given in dotted hex notation. +.SH OPTIONS +.TP +.I -S source addr +Select address to be used as source address for the request. +.TP +.I -s size +The +.B size +of the data packets to be sent. +.TP +.I -c count +Send +.B count +number of packets then exit. +.TP +.I -f +Kind of flood ping. Use with care! It reduces the delay time between packets +to 0. +.TP +.I bd_addr +The Bluetooth MAC address to be pinged in dotted hex notation like +.B 01:02:03:ab:cd:ef +or +.B 01:EF:cd:aB:02:03 +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Nils Faerber diff --git a/tools/l2ping.8 b/tools/l2ping.8 deleted file mode 100644 index 41becdba..00000000 --- a/tools/l2ping.8 +++ /dev/null @@ -1,49 +0,0 @@ -.TH L2PING 8 "Jan 22 2002" BlueZ "Linux System Administration" -.SH NAME -l2ping \- Send L2CAP echo request and receive answer -.SH SYNOPSIS -.B l2ping -[ -.I -S source addr -] [ -.I -s size -] [ -.I -c count -] [ -.I -f -] < -.I bd_addr -> -.SH DESCRIPTION -.LP -L2ping sends a L2CAP echo request to the Bluetooth MAC address -.B bd_addr -given in dotted hex notation. -.SH OPTIONS -.TP -.I -S source addr -Select address to be used as source address for the request. -.TP -.I -s size -The -.B size -of the data packets to be sent. -.TP -.I -c count -Send -.B count -number of packets then exit. -.TP -.I -f -Kind of flood ping. Use with care! It reduces the delay time between packets -to 0. -.TP -.I bd_addr -The Bluetooth MAC address to be pinged in dotted hex notation like -.B 01:02:03:ab:cd:ef -or -.B 01:EF:cd:aB:02:03 -.SH AUTHORS -Written by Maxim Krasnyansky -.PP -man page by Nils Faerber -- cgit From 30a4cfe6010a27030f8b89115e5362f01888ec93 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Dec 2002 14:18:03 +0000 Subject: Support for voice setting --- tools/hciconfig.8 | 9 +++++++++ tools/hciconfig.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index bf13c2bd..96b503ae 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -106,6 +106,15 @@ class is a 24-bit hex number describing the class of device, as specified in section 1.2 of the Bluetooth Assigned Numers document. .TP +.BI voice " [voice]" +With no +.IR voice , +prints voice setting. Otherwise, sets voice setting to +.IR voice . +.I +voice +is a 16-bit hex number describing the voice setting. +.TP .BI inqparms " [win:int]" With no .IR win:int , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 65512a09..45d9a23d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -522,6 +522,47 @@ void cmd_class(int ctl, int hdev, char *opt) } } +void cmd_voice(int ctl, int hdev, char *opt) +{ + static char *icf[] = { "Linear", "u-Law", "A-Law", "Reserved" }; + static char *idf[] = { "1's complement", "2's complement", "Sign-Magnitude", "Reserved" }; + static char *iss[] = { "8 bit", "16 bit" }; + static char *acf[] = { "CVSD", "u-Law", "A-Law", "Reserved" }; + int s = hci_open_dev(hdev); + + if (s < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + if (opt) { + uint16_t vs = htobl(strtoul(opt, NULL, 16)); + if (0 > hci_write_voice_setting(s, vs, 1000)) { + printf("Can't write voice setting on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint16_t vs; + uint8_t ic; + if (0 > hci_read_voice_setting(s, &vs, 1000)) { + printf("Can't read voice setting on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + ic = (vs & 0x0300) >> 8; + print_dev_hdr(&di); + printf("\tVoice setting: 0x%04x%s\n", vs, + ((vs & 0x03fc) == 0x0060) ? " (Default Condition)" : ""); + printf("\tInput Coding: %s\n", icf[ic]); + printf("\tInput Data Format: %s\n", idf[(vs & 0xc0) >> 6]); + if (!ic) { + printf("\tInput Sample Size: %s\n", iss[(vs & 0x20) >> 5]); + printf("\t# of bits padding at MSB: %d\n", (vs & 0x1c) >> 2); + } + printf("\tAir Coding Format: %s\n", acf[vs & 0x03]); + } +} + void cmd_version(int ctl, int hdev, char *opt) { struct hci_version ver; @@ -859,6 +900,7 @@ struct { { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, + { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, -- cgit From 85f1b67672730596df37adc362f490c17ff6d4f3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Dec 2002 05:31:24 +0000 Subject: Support for voice setting --- tools/hcisecfilter.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index bee16df1..8cd47420 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -62,6 +62,7 @@ int main(void) hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); + hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); printf("OGF_HOST_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); -- cgit From d77d3f848c60d692cc9029ccf9a15b06f0704e90 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 20 Dec 2002 11:06:35 +0000 Subject: Make the info command reusing an existing connection handle --- tools/hcitool.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index ec6f007a..dd289b04 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -386,7 +386,8 @@ static void cmd_info(int dev_id, int argc, char **argv) char name[248]; unsigned char features[8]; struct hci_version version; - int opt, dd; + struct hci_conn_info_req *cr; + int opt, dd, cc = 0; for_each_opt(opt, info_options, NULL) { switch(opt) { @@ -403,14 +404,19 @@ static void cmd_info(int dev_id, int argc, char **argv) return; } - baswap(&bdaddr, strtoba(argv[0])); + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); - if (dev_id < 0) { - fprintf(stderr, "Device is not available.\n"); - exit(1); - } + cc = 1; + } + + if (dev_id < 0) { + fprintf(stderr, "Device is not available or not connected.\n"); + exit(1); } printf("Requesting information ...\n"); @@ -421,13 +427,29 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - printf("\tBD Address: %s\n", argv[0]); + if (cc) { + if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + perror("Can't create connection"); + close(dd); + exit(1); + } + } else { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; - if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { - close(dd); - exit(1); + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + handle = cr->conn_info->handle; } + printf("\tBD Address: %s\n", argv[0]); + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); @@ -444,7 +466,8 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 3)); } - hci_disconnect(dd, handle, 0x13, 10000); + if (cc) + hci_disconnect(dd, handle, 0x13, 10000); close(dd); } -- cgit From 3e8471f6fc3e46a168ebb1bdfacdfb182c746f59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Jan 2003 17:52:56 +0000 Subject: Support for switch role command --- tools/hcitool.1 | 6 ++ tools/hcitool.c | 215 +++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 155 insertions(+), 66 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index 49b5e715..fa51efce 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -99,6 +99,12 @@ s Delete baseband connection from remote device with Bluetooth address .IR bdaddr . .TP +.BI sr " " +Switch role for the baseband connection from the remote device to +.BR master +or +.BR slave . +.TP .BI cpt " " Change packet types for baseband connection to device with Bluetooth address .IR bdaddr . diff --git a/tools/hcitool.c b/tools/hcitool.c index dd289b04..00c84b05 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -59,7 +59,7 @@ static int dev_info(int s, int dev_id, long arg) bdaddr_t bdaddr; if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; - + baswap(&bdaddr, &di.bdaddr); printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); return 0; @@ -171,18 +171,18 @@ static void cmd_dev(int dev_id, int argc, char **argv) /* Inquiry */ static struct option inq_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, {0, 0, 0, 0} }; static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" - "\t [--numrsp=N] specify maximum number of inquiry responses\n" - "\t [--flush] flush the inquiry cache\n"; + "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { @@ -200,7 +200,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) case 'l': length = atoi(optarg); break; - + case 'n': num_rsp = atoi(optarg); break; @@ -236,10 +236,10 @@ static void cmd_inq(int dev_id, int argc, char **argv) /* Device scanning */ static struct option scan_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, {0, 0, 0, 0} }; @@ -356,7 +356,7 @@ static void cmd_name(int dev_id, int argc, char **argv) } dd = hci_open_dev(dev_id); - if (dd < 0) { + if (dd < 0) { perror("HCI device open failed"); exit(1); } @@ -371,7 +371,7 @@ static void cmd_name(int dev_id, int argc, char **argv) /* Info about remote device */ static struct option info_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -475,7 +475,7 @@ static void cmd_info(int dev_id, int argc, char **argv) /* Send arbitrary HCI commands */ static struct option cmd_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -492,7 +492,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) hci_event_hdr *hdr; int i, opt, len, dd; uint16_t ocf; - uint8_t ogf; + uint8_t ogf; for_each_opt(opt, cmd_options, NULL) { switch(opt) { @@ -566,7 +566,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) /* Display active connections */ static struct option con_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -593,9 +593,9 @@ static void cmd_con(int dev_id, int argc, char **argv) /* Create connection */ static struct option cc_options[] = { - {"help", 0,0, 'h'}, - {"role", 1,0, 'r'}, - {"ptype", 1,0, 'p'}, + {"help", 0,0, 'h'}, + {"role", 1,0, 'r'}, + {"ptype", 1,0, 'p'}, {0, 0, 0, 0} }; @@ -621,7 +621,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) case 'p': hci_strtoptype(optarg, &ptype); break; - + case 'r': role = optarg[0] == 'm' ? 0 : 1; break; @@ -662,7 +662,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) /* Close connection */ static struct option dc_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -707,16 +707,16 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); - exit(1); - } + exit(1); + } hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); @@ -724,10 +724,92 @@ static void cmd_dc(int dev_id, int argc, char **argv) free(cr); } +/* Role switch */ + +static struct option sr_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *sr_help = + "Usage:\n" + "\tsr \n"; + +static void cmd_sr(int dev_id, int argc, char **argv) +{ + struct hci_request rq; + switch_role_cp cp; + evt_role_change rp; + int opt, dd; + + for_each_opt(opt, sr_options, NULL) { + switch(opt) { + default: + printf(sr_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(sr_help); + return; + } + + str2ba(argv[0], &cp.bdaddr); + switch (argv[1][0]) { + case 'm': + cp.role = 0; + break; + case 's': + cp.role = 1; + break; + default: + cp.role = atoi(argv[1]); + break; + } + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &cp.bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_SWITCH_ROLE; + rq.cparam = &cp; + rq.clen = SWITCH_ROLE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_ROLE_CHANGE_SIZE; + rq.event = EVT_ROLE_CHANGE; + + if (hci_send_req(dd, &rq, 300) < 0) { + perror("Switch role request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "Switch role cmd failed (0x%2.2X)\n", rp.status); + exit(1); + } + + close(dd); +} + /* Read RSSI */ static struct option rssi_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -738,7 +820,7 @@ static char *rssi_help = static void cmd_rssi(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; read_rssi_rp rp; bdaddr_t bdaddr; int opt, dd; @@ -776,7 +858,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -786,13 +868,13 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = READ_RSSI_RP_SIZE; - + rq.rlen = READ_RSSI_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("Read RSSI failed"); exit(1); @@ -803,7 +885,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } printf("\tRSSI return value: %d\n", rp.rssi); - + close(dd); free(cr); } @@ -811,7 +893,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) /* Get Link Quality */ static struct option link_quality_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -822,7 +904,7 @@ static char *link_quality_help = static void cmd_link_quality(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; get_link_quality_rp rp; bdaddr_t bdaddr; int opt, dd; @@ -860,7 +942,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -868,7 +950,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_GET_LINK_QUALITY; @@ -888,7 +970,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) exit(1); } printf("Link quality: %d\n", rp.link_quality); - + close(dd); free(cr); } @@ -896,7 +978,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) /* Set connection packet type */ static struct option cpt_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -908,7 +990,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; - set_conn_ptype_cp cp; + set_conn_ptype_cp cp; evt_conn_ptype_changed rp; bdaddr_t bdaddr; int opt, dd, ptype; @@ -947,7 +1029,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -955,19 +1037,19 @@ static void cmd_cpt(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + cp.handle = cr->conn_info->handle; cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_PTYPE; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; rq.clen = SET_CONN_PTYPE_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE; rq.event = EVT_CONN_PTYPE_CHANGED; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("Packet type change failed"); exit(1); @@ -980,7 +1062,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) /* Get/Set Link Supervision Timeout */ static struct option link_supervision_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -991,7 +1073,7 @@ static char *link_supervision_help = static void cmd_link_sup_to(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; read_link_supervision_timeout_rp rp; write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; @@ -1030,7 +1112,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1038,16 +1120,16 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + if (argc == 1) { memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; - + rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); @@ -1069,11 +1151,11 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cp.link_sup_to = strtol(argv[1], NULL, 10); memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cp; - rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; - + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); @@ -1098,6 +1180,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_link_quality, "Display link quality" }, @@ -1125,8 +1208,8 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, + {"help", 0,0, 'h'}, + {"device", 1,0, 'i'}, {0, 0, 0, 0} }; -- cgit From f03489827214efb7e5314e61b57278eec173b786 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 28 Jan 2003 01:55:08 +0000 Subject: Added OGF_PARAM_STATUS --- tools/hcisecfilter.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 8cd47420..13dee183 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -77,4 +77,14 @@ int main(void) printf("OGF_INFO_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + // OGF_INFO_PARAM + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); + hci_set_bit(OCF_RESET_FAILED_CONTACT_COUNTER, ocf_mask); + hci_set_bit(OCF_GET_LINK_QUALITY, ocf_mask); + hci_set_bit(OCF_READ_RSSI, ocf_mask); + + printf("OGF_STATUS_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); } -- cgit From 227df09e733b7ad5421903d4e48d36860d14327f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 4 Feb 2003 15:49:49 +0000 Subject: fix typo --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 45d9a23d..0c8437f3 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -824,7 +824,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) break; default: - printf("\tUnsuported manufacturer\n"); + printf("\tUnsupported manufacturer\n"); break; } return; -- cgit From aaa780de16b91375ba63bdf4929bc5b7a2a0c8f6 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Sat, 8 Feb 2003 12:08:55 +0000 Subject: typos --- tools/hciattach.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 78deb53b..f30ae033 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -796,10 +796,10 @@ int init_uart(char *dev, struct uart_t *u) return -1; } - /* Set TTY to N_HCI line discpline */ + /* Set TTY to N_HCI line discipline */ i = N_HCI; if (ioctl(fd, TIOCSETD, &i) < 0) { - perror("Can't set line disc"); + perror("Can't set line discipline"); return -1; } @@ -890,7 +890,7 @@ int main(int argc, char *argv[]) } if (!u) { - fprintf(stderr, "Unknow device type or id\n"); + fprintf(stderr, "Unknown device type or id\n"); exit(1); } @@ -910,7 +910,7 @@ int main(int argc, char *argv[]) } if (!u) { - fprintf(stderr, "Unknow device type or id\n"); + fprintf(stderr, "Unknown device type or id\n"); exit(1); } @@ -919,12 +919,12 @@ int main(int argc, char *argv[]) sa.sa_handler = sig_alarm; sigaction(SIGALRM, &sa, NULL); - /* 5 seconds should be enough for intialization */ + /* 5 seconds should be enough for initialization */ alarm(to); n = init_uart(dev, u); if (n < 0) { - perror("Can't init device"); + perror("Can't initialize device"); exit(1); } -- cgit From 427f4bbc07f40706dd5e3c5500f14c63a160c979 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 12 Feb 2003 12:34:16 +0000 Subject: describe optional arguments --- tools/hciattach.8 | 13 +++++++++++-- tools/hciattach.c | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.8 b/tools/hciattach.8 index 812c40dc..0dadec99 100644 --- a/tools/hciattach.8 +++ b/tools/hciattach.8 @@ -3,7 +3,7 @@ hciattach \- attach serial devices via UART HCI to BlueZ stack .SH SYNOPSIS .B hciattach -< +[ -n ] [ -p ] [ -t timeout ] < .I tty > < .I type @@ -20,6 +20,15 @@ Hciattach is used to attach a serial UART to the Bluetooth stack as HCI transport interface. .SH OPTIONS .TP +.BI -n +Don't detach from controlling terminal. +.TP +.BI -p +Print the PID when detaching. +.TP +.BI -t timeout +Specify an initialization timeout. (Default is 5 seconds.) +.TP .I This specifies the serial device to attach. A leading .B /dev @@ -102,4 +111,4 @@ instead. .SH AUTHORS Written by Maxim Krasnyansky .PP -man page by Nils Faerber +Manual page by Nils Faerber diff --git a/tools/hciattach.c b/tools/hciattach.c index f30ae033..b6aa7376 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -815,7 +815,7 @@ static void usage(void) { printf("hciattach - HCI UART driver initialization utility\n"); printf("Usage:\n"); - printf("\thciattach [speed] [flow]\n"); + printf("\thciattach [-n] [-p] [-t timeout] [speed] [flow]\n"); printf("\thciattach -l\n"); } -- cgit From d436459deed7ec8a472f6d27c4f0e3539aa482ef Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 12 Feb 2003 13:34:55 +0000 Subject: bugfix --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 0c8437f3..ed8fdcd2 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -486,7 +486,7 @@ void cmd_class(int ctl, int hdev, char *opt) exit(1); } if (opt) { - uint32_t cod = htobl(strtoul(opt, NULL, 16)); + uint32_t cod = strtoul(opt, NULL, 16); if (0 > hci_write_class_of_dev(s, cod, 1000)) { printf("Can't write local class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); -- cgit From 047f07b46aa8afabe5ebd67fa02365c92a4ff224 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 12 Feb 2003 13:46:00 +0000 Subject: add support for texas module --- tools/hciattach.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index b6aa7376..0131dcb6 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -230,14 +230,74 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) return 0; } +static int texas(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[10]; + unsigned char resp[100]; /* Response */ + int n; + + memset(resp,'\0', 100); + + /* Switch to default Texas baudrate*/ + if (set_speed(fd, ti, 115200) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + /* It is possible to get software version with manufacturer specific + HCI command HCI_VS_TI_Version_Number. But the only thing you get more + is if this is point-to-point or point-to-multipoint module */ + + /* Get Manufacturer and LMP version */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x01; + cmd[2] = 0x10; + cmd[3] = 0x00; + + do { + n = write(fd, cmd, 4); + if (n < 0) { + perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)"); + return -1; + } + if (n < 4) { + fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n); + return -1; + } + + /* Read reply. */ + if (read_hci_event(fd, resp, 100) < 0) { + perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)"); + return -1; + } + + /* Wait for command complete event for our Opcode */ + } while (resp[4] != cmd[1] && resp[5] != cmd[2]); + + /* Verify manufacturer */ + if ((resp[11] & 0xFF) != 0x0d) + fprintf(stderr,"WARNING : module's manufacturer is not Texas Instrument\n"); + + /* Print LMP version */ + fprintf(stderr, "Texas module LMP version : 0x%02x\n", resp[10] & 0xFF); + + /* Print LMP subversion */ + fprintf(stderr, "Texas module LMP sub-version : 0x%02x%02x\n", resp[14] & 0xFF, resp[13] & 0xFF); + + nanosleep(&tm, NULL); + return 0; +} + static int read_check(int fd, void *buf, int count) { int res; - do{ + do { res = read(fd, buf, count); if (res != -1) { - buf += res; count -= res; + buf += res; + count -= res; } } while (count && (errno == 0 || errno == EINTR)); @@ -704,6 +764,7 @@ struct uart_t uart[] = { { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, + { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, texas}, { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 0, bcsp }, -- cgit From ae072dcf83d8124e45a0bf5ca69c3699e2a4b8fe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 Feb 2003 15:53:40 +0000 Subject: Fix the voice command for big endian machines --- tools/hciconfig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ed8fdcd2..9f80f4c4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -535,7 +535,7 @@ void cmd_voice(int ctl, int hdev, char *opt) exit(1); } if (opt) { - uint16_t vs = htobl(strtoul(opt, NULL, 16)); + uint16_t vs = htobs(strtoul(opt, NULL, 16)); if (0 > hci_write_voice_setting(s, vs, 1000)) { printf("Can't write voice setting on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -549,6 +549,7 @@ void cmd_voice(int ctl, int hdev, char *opt) hdev, strerror(errno), errno); exit(1); } + vs = htobs(vs); ic = (vs & 0x0300) >> 8; print_dev_hdr(&di); printf("\tVoice setting: 0x%04x%s\n", vs, -- cgit From eeb3109cedd192d95abe9b103d78d10685ba4004 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 Mar 2003 22:55:41 +0000 Subject: Display CSR firmware with revision command --- tools/hciconfig.c | 79 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 9f80f4c4..bae20770 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -785,11 +785,66 @@ void cmd_page_to(int ctl, int hdev, char *opt) } } -static void cmd_revision(int ctl, int hdev, char *opt) +static void print_rev_ericsson(int dd) { - struct hci_version ver; struct hci_request rq; unsigned char buf[102]; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = 0x3f; + rq.ocf = 0x000f; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\n Can't read revision info. %s(%d)\n", strerror(errno), errno); + return; + } + + printf("\t%s\n", buf + 1); +} + +static struct { + char *str; + uint16_t rev; +} csr_map[] = { + { "HCI 11.2 (bc01b)", 114 }, + { "HCI 11.3 (bc01b)", 115 }, + { "HCI 12.1 (bc01b)", 119 }, + { "HCI 12.3 (bc01b)", 134 }, + { "HCI 12.7 (bc01b)", 188 }, + { "HCI 12.8 (bc01b)", 218 }, + { "HCI 12.9 (bc01b)", 283 }, + { "HCI 13.10 (bc01b)", 309 }, + { "HCI 13.11 (bc01b)", 351 }, + { "HCI 16.4 (bc01b)", 523 }, + { "HCI 14.3 (bc02x)", 272 }, + { "HCI 14.6 (bc02x)", 336 }, + { "HCI 14.7 (bc02x)", 373 }, + { "HCI 14.8 (bc02x)", 487 }, + { "HCI 15.3 (bc02x)", 443 }, + { "HCI 16.4 (bc02x)", 525 }, + { NULL } +}; + +static void print_rev_csr(uint16_t rev) +{ + int i; + + for (i = 0; csr_map[i].str; i++) + if (csr_map[i].rev == rev) { + printf("\t%s\n", csr_map[i].str); + return; + } + + printf("\tUnknown firmware\n"); +} + +static void cmd_revision(int ctl, int hdev, char *opt) +{ + struct hci_version ver; int dd; dd = hci_open_dev(hdev); @@ -807,23 +862,11 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_dev_hdr(&di); switch (ver.manufacturer) { case 0: - memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; - rq.ocf = 0x000f; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &buf; - rq.rlen = sizeof(buf); - - if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\n Can't read revision info. %s(%d)\n", - strerror(errno), errno); - return; - } - - printf("\t%s\n", buf + 1); + print_rev_ericsson(dd); + break; + case 10: + print_rev_csr(ver.hci_rev); break; - default: printf("\tUnsupported manufacturer\n"); break; -- cgit From a8b6c0b9d190457f40f30147fe70ef0f8467a60b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 17 Mar 2003 09:06:19 +0000 Subject: Flush the serial buffer before quit in BCSP initialization --- tools/hciattach.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 0131dcb6..6959a006 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -323,6 +323,7 @@ static void bcsp_tshy_sig_alarm(int sig) alarm(1); return; } + tcflush(serial_fd, TCIOFLUSH); fprintf(stderr, "BCSP initialization timed out\n"); exit(1); } @@ -337,6 +338,7 @@ static void bcsp_tconf_sig_alarm(int sig) alarm(1); return; } + tcflush(serial_fd, TCIOFLUSH); fprintf(stderr, "BCSP initialization timed out\n"); exit(1); } -- cgit From 55682f4240f0854ea60d53314fc0c471d1e146b2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 19 Mar 2003 21:17:46 +0000 Subject: Add 921600 bps for Ericsson modules --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 6959a006..15a9d367 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -173,6 +173,9 @@ static int ericsson(int fd, struct uart_t *u, struct termios *ti) case 460800: cmd[4] = 0x00; break; + case 921600: + cmd[4] = 0x20; + break; default: cmd[4] = 0x03; u->speed = 57600; -- cgit From 40fbc58cb2874081e624d2658282f90f29525624 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 5 Apr 2003 14:13:04 +0000 Subject: Support for initial baud rate and sending of a break --- tools/hciattach.c | 128 +++++++++++++++++++++++++----------------------------- 1 file changed, 58 insertions(+), 70 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 15a9d367..7b8c20a0 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -51,6 +51,7 @@ struct uart_t { int m_id; int p_id; int proto; + int start_speed; int speed; int flags; int (*init) (int fd, struct uart_t *u, struct termios *ti); @@ -79,6 +80,8 @@ static int uart_speed(int s) return B921600; case 1000000: return B1000000; + case 1152000: + return B1152000; default: return B57600; } @@ -149,12 +152,6 @@ static int ericsson(int fd, struct uart_t *u, struct termios *ti) struct timespec tm = {0, 50000}; char cmd[10]; - /* Switch to default Ericsson baudrate*/ - if (set_speed(fd, ti, 57600) < 0) { - perror("Can't set default baud rate"); - return -1; - } - cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x09; cmd[2] = 0xfc; @@ -199,12 +196,6 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) struct timespec tm = {0, 50000}; char cmd[10]; - /* Switch to default Digi baudrate*/ - if (set_speed(fd, ti, 9600) < 0) { - perror("Can't set default baud rate"); - return -1; - } - /* DigiAnswer set baud rate command */ cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x07; @@ -242,12 +233,6 @@ static int texas(int fd, struct uart_t *u, struct termios *ti) memset(resp,'\0', 100); - /* Switch to default Texas baudrate*/ - if (set_speed(fd, ti, 115200) < 0) { - perror("Can't set default baud rate"); - return -1; - } - /* It is possible to get software version with manufacturer specific HCI command HCI_VS_TI_Version_Number. But the only thing you get more is if this is point-to-point or point-to-multipoint module */ @@ -484,12 +469,6 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) static int csr_seq = 0; /* Sequence number of command */ int divisor; - /* Switch to default CSR baudrate */ - if (set_speed(fd, ti, 115200) < 0) { - perror("Can't set default baud rate"); - return -1; - } - /* It seems that if we set the CSR UART speed straight away, it * won't work, the CSR UART gets into a state where we can't talk * to it anymore. @@ -596,6 +575,19 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) } #endif + if (u->speed > 1500000) { + fprintf(stderr, "Speed %d too high. Remaining at %d baud\n", + u->speed, u->start_speed); + u->speed = u->start_speed; + } else if (u->speed != 57600 && uart_speed(u->speed) == B57600) { + /* Unknown speed. Why oh why can't we just pass an int to the kernel? */ + fprintf(stderr, "Speed %d unrecognised. Remaining at %d baud\n", + u->speed, u->start_speed); + u->speed = u->start_speed; + } + if (u->speed == u->start_speed) + return 0; + /* Now, create the command that will set the UART speed */ /* CSR BCC header */ cmd[5] = 0x02; /* type = SET-REQ */ @@ -604,30 +596,8 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) cmd[10] = (csr_seq >> 8) & 0xFF;/* - msB */ csr_seq++; - switch (u->speed) { - case 9600: - divisor = 0x0027; - break; - /* Various speeds ommited */ - case 57600: - divisor = 0x00EC; - break; - case 115200: - divisor = 0x01D8; - break; - /* For Brainbox Pcmcia cards */ - case 460800: - divisor = 0x075F; - break; - case 921600: - divisor = 0x0EBF; - break; - default: - /* Safe default */ - divisor = 0x01D8; - u->speed = 115200; - break; - } + divisor = (u->speed*64+7812)/15625; + /* No parity, one stop bit -> divisor |= 0x0000; */ cmd[15] = (divisor) & 0xFF; /* divider */ cmd[16] = (divisor >> 8) & 0xFF; /* - msB */ @@ -665,12 +635,6 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) char cmd[10], rsp[100]; int r; - /* Switch to default Silicon Wave baudrate*/ - if (set_speed(fd, ti, 115200) < 0) { - perror("Can't set default baud rate"); - return -1; - } - // Silicon Wave set baud rate command // see HCI Vendor Specific Interface from Silicon Wave // first send a "param access set" command to set the @@ -766,33 +730,33 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } struct uart_t uart[] = { - { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, - { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, - { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, - { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, texas}, + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, digi }, + { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, texas}, - { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 0, bcsp }, + { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ - { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ - { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, csr }, + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, /* BrainBoxes PCMCIA card (BL620) */ - { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 460800, FLOW_CTL, csr }, + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 115200, 460800, FLOW_CTL, csr }, /* Silicon Wave kits */ - { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, swave }, + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, /* Sphinx Electronics PICO Card */ - { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* Inventel BlueBird Module */ - { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* COM One Platinium Bluetooth PC Card */ - { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 0, bcsp }, + { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, { NULL, 0 } }; @@ -818,7 +782,7 @@ struct uart_t * get_by_type(char *type) } /* Initialize UART driver */ -int init_uart(char *dev, struct uart_t *u) +int init_uart(char *dev, struct uart_t *u, int send_break) { struct termios ti; int fd, i; @@ -849,8 +813,17 @@ int init_uart(char *dev, struct uart_t *u) return -1; } + /* Set initial baudrate */ + if (set_speed(fd, &ti, u->start_speed) < 0) { + perror("Can't set initial baud rate"); + return -1; + } + tcflush(fd, TCIOFLUSH); + if (send_break) + tcsendbreak(fd, 0); + if (u->init && u->init(fd, u, &ti) < 0) return -1; @@ -881,7 +854,7 @@ static void usage(void) { printf("hciattach - HCI UART driver initialization utility\n"); printf("Usage:\n"); - printf("\thciattach [-n] [-p] [-t timeout] [speed] [flow]\n"); + printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow]\n"); printf("\thciattach -l\n"); } @@ -893,6 +866,8 @@ int main(int argc, char *argv[]) struct uart_t *u = NULL; int detach, printpid, opt, i, n; int to = 5; + int start_speed = 0; + int send_break = 0; pid_t pid; struct sigaction sa; char dev[20]; @@ -900,8 +875,12 @@ int main(int argc, char *argv[]) detach = 1; printpid = 0; - while ((opt=getopt(argc, argv, "npt:l")) != EOF) { + while ((opt=getopt(argc, argv, "bnpt:s:l")) != EOF) { switch(opt) { + case 'b': + send_break = 1; + break; + case 'n': detach = 0; break; @@ -914,6 +893,10 @@ int main(int argc, char *argv[]) to = atoi(optarg); break; + case 's': + start_speed = atoi(optarg); + break; + case 'l': for (i = 0; uart[i].type; i++) { printf("%-10s0x%04x,0x%04x\n", uart[i].type, @@ -980,6 +963,11 @@ int main(int argc, char *argv[]) exit(1); } + /* If user specified a starting speed, use that instead of + the hardware's default */ + if (start_speed) + u->start_speed = start_speed; + memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = sig_alarm; @@ -988,7 +976,7 @@ int main(int argc, char *argv[]) /* 5 seconds should be enough for initialization */ alarm(to); - n = init_uart(dev, u); + n = init_uart(dev, u, send_break); if (n < 0) { perror("Can't initialize device"); exit(1); -- cgit From 1c341784341174627ca3d8a76a4a2ca3bde2713b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 8 Apr 2003 00:12:02 +0000 Subject: start_speed -> init_speed --- tools/hciattach.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 7b8c20a0..54980ded 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -51,7 +51,7 @@ struct uart_t { int m_id; int p_id; int proto; - int start_speed; + int init_speed; int speed; int flags; int (*init) (int fd, struct uart_t *u, struct termios *ti); @@ -577,15 +577,15 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) if (u->speed > 1500000) { fprintf(stderr, "Speed %d too high. Remaining at %d baud\n", - u->speed, u->start_speed); - u->speed = u->start_speed; + u->speed, u->init_speed); + u->speed = u->init_speed; } else if (u->speed != 57600 && uart_speed(u->speed) == B57600) { /* Unknown speed. Why oh why can't we just pass an int to the kernel? */ fprintf(stderr, "Speed %d unrecognised. Remaining at %d baud\n", - u->speed, u->start_speed); - u->speed = u->start_speed; + u->speed, u->init_speed); + u->speed = u->init_speed; } - if (u->speed == u->start_speed) + if (u->speed == u->init_speed) return 0; /* Now, create the command that will set the UART speed */ @@ -814,7 +814,7 @@ int init_uart(char *dev, struct uart_t *u, int send_break) } /* Set initial baudrate */ - if (set_speed(fd, &ti, u->start_speed) < 0) { + if (set_speed(fd, &ti, u->init_speed) < 0) { perror("Can't set initial baud rate"); return -1; } @@ -866,7 +866,7 @@ int main(int argc, char *argv[]) struct uart_t *u = NULL; int detach, printpid, opt, i, n; int to = 5; - int start_speed = 0; + int init_speed = 0; int send_break = 0; pid_t pid; struct sigaction sa; @@ -894,7 +894,7 @@ int main(int argc, char *argv[]) break; case 's': - start_speed = atoi(optarg); + init_speed = atoi(optarg); break; case 'l': @@ -963,10 +963,10 @@ int main(int argc, char *argv[]) exit(1); } - /* If user specified a starting speed, use that instead of + /* If user specified a initial speed, use that instead of the hardware's default */ - if (start_speed) - u->start_speed = start_speed; + if (init_speed) + u->init_speed = init_speed; memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; -- cgit From 723681ffa3035a55fe3a293add7e26da0e7296bd Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 8 Apr 2003 13:34:39 +0000 Subject: use constants; report errors --- tools/hcitool.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 00c84b05..f2ffb891 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -428,7 +428,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (cc) { - if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -467,7 +467,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (cc) - hci_disconnect(dd, handle, 0x13, 10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); close(dd); } @@ -655,7 +655,8 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); + if (0 > hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000)) + perror("Can't create connection"); hci_close_dev(dd); } @@ -718,7 +719,8 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); + if (0 > hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100)) + perror("Disconnect failed"); close(dd); free(cr); -- cgit From 424f2b1bb5f34a89adc279c216bdf1f032dffa8d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 8 Apr 2003 14:51:17 +0000 Subject: Cleanup --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index f2ffb891..04d756eb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -655,7 +655,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (0 > hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000)) + if (hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000) < 0) perror("Can't create connection"); hci_close_dev(dd); } @@ -719,7 +719,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (0 > hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100)) + if (hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100) < 0) perror("Disconnect failed"); close(dd); -- cgit From d68d01e1d2aecd2326cbc7dc0a8ec77ce30a1b02 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 May 2003 14:20:23 +0000 Subject: Display AVM firmware version with 'revision' command --- tools/hciconfig.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index bae20770..87de4b3f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -842,6 +842,11 @@ static void print_rev_csr(uint16_t rev) printf("\tUnknown firmware\n"); } +static void print_rev_avm(uint16_t rev) +{ + printf("\tFirmware 3.%d.%d\n", rev >> 8, rev & 0xff); +} + static void cmd_revision(int ctl, int hdev, char *opt) { struct hci_version ver; @@ -867,6 +872,9 @@ static void cmd_revision(int ctl, int hdev, char *opt) case 10: print_rev_csr(ver.hci_rev); break; + case 31: + print_rev_avm(ver.hci_rev); + break; default: printf("\tUnsupported manufacturer\n"); break; -- cgit From 0ce9154a53a990998d0030a78e544ef8e8285352 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 May 2003 16:41:48 +0000 Subject: Support for TDK, IBM and Socket cards --- tools/hciattach.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 54980ded..05230d3c 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -758,7 +758,13 @@ struct uart_t uart[] = { /* COM One Platinium Bluetooth PC Card */ { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, - { NULL, 0 } + /* TDK Bluetooth PC Card and IBM Bluetooth PC Card II */ + { "tdk", 0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + + /* Socket Bluetooth CF Card (Rev G) */ + { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, + + { NULL, 0 } }; struct uart_t * get_by_id(int m_id, int p_id) -- cgit From 1181a51f587089189aeb8df20567ed45f350d88e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Jun 2003 16:42:44 +0000 Subject: Typo --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 87de4b3f..538e03bc 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -844,7 +844,7 @@ static void print_rev_csr(uint16_t rev) static void print_rev_avm(uint16_t rev) { - printf("\tFirmware 3.%d.%d\n", rev >> 8, rev & 0xff); + printf("\tFirmware 03.%d.%d\n", rev >> 8, rev & 0xff); } static void cmd_revision(int ctl, int hdev, char *opt) -- cgit From e7490562668965f3433aa4270b88ce55bfa9e1e3 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 18 Jun 2003 09:52:01 +0000 Subject: ... --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 04d756eb..a8f79f6d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -282,7 +282,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { - perror("Device is not available."); + perror("Device is not available"); exit(1); } } @@ -290,7 +290,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { - perror("Inquiry failed."); + perror("Inquiry failed"); exit(1); } -- cgit From 26d5498a00afec5ed676ef84ce1e7b94557ff46c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jun 2003 11:56:55 +0000 Subject: Add command for reading transmit power level --- tools/hcitool.1 | 9 +++ tools/hcitool.c | 170 +++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 139 insertions(+), 40 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index fa51efce..dd92e351 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -130,6 +130,15 @@ with Bluetooth address Display link quality for the connection to the device with Bluetooth address .IR bdaddr . .TP +.BI tpl " [type]" +Display transmit power level for the connection to the device with Bluetooth address +.IR bdaddr . +The type can be +.BR 0 +for the current transmit power level (which is default) or +.BR 1 +for the maximum transmit power level. +.TP .BI lst " [value]" With no .IR value , diff --git a/tools/hcitool.c b/tools/hcitool.c index a8f79f6d..88c53266 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -37,9 +37,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -786,7 +786,7 @@ static void cmd_sr(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_POLICY; rq.ocf = OCF_SWITCH_ROLE; rq.cparam = &cp; @@ -869,7 +869,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; @@ -886,24 +886,24 @@ static void cmd_rssi(int dev_id, int argc, char **argv) printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); exit(1); } - printf("\tRSSI return value: %d\n", rp.rssi); + printf("RSSI return value: %d\n", rp.rssi); close(dd); free(cr); } -/* Get Link Quality */ +/* Get link quality */ -static struct option link_quality_options[] = { +static struct option lq_options[] = { {"help", 0,0, 'h'}, {0, 0, 0, 0} }; -static char *link_quality_help = +static char *lq_help = "Usage:\n" "\tlq \n"; -static void cmd_link_quality(int dev_id, int argc, char **argv) +static void cmd_lq(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; @@ -911,10 +911,10 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) bdaddr_t bdaddr; int opt, dd; - for_each_opt(opt, link_quality_options, NULL) { + for_each_opt(opt, lq_options, NULL) { switch(opt) { default: - printf(link_quality_help); + printf(lq_help); return; } } @@ -922,7 +922,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) argv += optind; if (argc < 1) { - printf(link_quality_help); + printf(lq_help); return; } @@ -953,13 +953,13 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_GET_LINK_QUALITY; + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_GET_LINK_QUALITY; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = GET_LINK_QUALITY_RP_SIZE; + rq.rlen = GET_LINK_QUALITY_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI get_link_quality request failed"); @@ -977,6 +977,95 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) free(cr); } +/* Get transmit power level */ + +static struct option tpl_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *tpl_help = + "Usage:\n" + "\ttpl [type]\n"; + +static void cmd_tpl(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_transmit_power_level_cp cp; + read_transmit_power_level_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, tpl_options, NULL) { + switch(opt) { + default: + printf(tpl_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(tpl_help); + return; + } + + str2ba(argv[0], &bdaddr); + cp.type = (argc > 1) ? atoi(argv[1]) : 0; + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + cp.handle = cr->conn_info->handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; + rq.rparam = &rp; + rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read transmit power level request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_transmit_power_level cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + printf("%s transmit power level: %d\n", + (cp.type == 0) ? "Current" : "Maximum", rp.level); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -1043,7 +1132,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cp.handle = cr->conn_info->handle; cp.pkt_type = ptype; - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; @@ -1061,18 +1150,18 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } -/* Get/Set Link Supervision Timeout */ +/* Get/Set link supervision timeout */ -static struct option link_supervision_options[] = { +static struct option lst_options[] = { {"help", 0,0, 'h'}, {0, 0, 0, 0} }; -static char *link_supervision_help = +static char *lst_help = "Usage:\n" "\tlst [new value in slots]\n"; -static void cmd_link_sup_to(int dev_id, int argc, char **argv) +static void cmd_lst(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; @@ -1081,10 +1170,10 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) bdaddr_t bdaddr; int opt, dd; - for_each_opt(opt, link_supervision_options, NULL) { + for_each_opt(opt, lst_options, NULL) { switch(opt) { default: - printf(link_supervision_help); + printf(lst_help); return; } } @@ -1092,7 +1181,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) argv += optind; if (argc < 1) { - printf(link_supervision_help); + printf(lst_help); return; } @@ -1124,7 +1213,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) } if (argc == 1) { - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cr->conn_info->handle; @@ -1152,7 +1241,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cp.handle = cr->conn_info->handle; cp.link_sup_to = strtol(argv[1], NULL, 10); - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cp; @@ -1173,20 +1262,21 @@ struct { void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, "Display local devices" }, - { "inq", cmd_inq, "Inquire remote devices" }, - { "scan", cmd_scan, "Scan for remote devices" }, - { "name", cmd_name, "Get name from remote device" }, - { "info", cmd_info, "Get information from remote device" }, - { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, - { "con", cmd_con, "Display active connections" }, - { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, - { "sr", cmd_sr, "Switch master/slave role" }, - { "cpt", cmd_cpt, "Change connection packet type" }, - { "rssi", cmd_rssi, "Display connection RSSI" }, - { "lq", cmd_link_quality, "Display link quality" }, - { "lst", cmd_link_sup_to, "Set/display link supervision timeout" }, + { "dev", cmd_dev, "Display local devices" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, + { "cpt", cmd_cpt, "Change connection packet type" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_lq, "Display link quality" }, + { "tpl", cmd_tpl, "Display transmit power level" }, + { "lst", cmd_lst, "Set/display link supervision timeout" }, { NULL, NULL, 0} }; -- cgit From 529a4a6e9be63df61d41a82787adae204822a6e7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 27 Jun 2003 10:49:13 +0000 Subject: Support for reading transmit power level --- tools/hcisecfilter.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 13dee183..2ff5c48a 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -63,6 +63,7 @@ int main(void) hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); + hci_set_bit(OCF_READ_TRANSMIT_POWER_LEVEL, ocf_mask); printf("OGF_HOST_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); -- cgit From 49ceef7a27ee6112148f5ef5fe37f1ee6f1f44ea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 2 Jul 2003 22:27:41 +0000 Subject: New code for CSR specific revision information --- tools/Makefile.am | 2 + tools/csr.c | 347 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 35 ++++++ tools/hciconfig.c | 126 +++++++++----------- 4 files changed, 442 insertions(+), 68 deletions(-) create mode 100644 tools/csr.c create mode 100644 tools/csr.h (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 0513c83b..180c0cc1 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -7,6 +7,8 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping +hciconfig_SOURCES = hciconfig.c csr.h csr.c + man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 noinst_PROGRAMS = ppporc diff --git a/tools/csr.c b/tools/csr.c new file mode 100644 index 00000000..e2069cd7 --- /dev/null +++ b/tools/csr.c @@ -0,0 +1,347 @@ +/* + * + * CSR BlueCore specific functions + * + * Copyright (C) 2003 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + + +static struct { + uint16_t id; + char *str; +} csr_map[] = { + { 111, "HCI 11.0" }, + { 112, "HCI 11.1" }, + { 114, "HCI 11.2" }, + { 115, "HCI 11.3" }, + { 117, "HCI 12.0" }, + { 119, "HCI 12.1" }, + { 133, "HCI 12.2" }, + { 134, "HCI 12.3" }, + { 162, "HCI 12.4" }, + { 165, "HCI 12.5" }, + { 169, "HCI 12.6" }, + { 188, "HCI 12.7" }, + { 218, "HCI 12.8" }, + { 283, "HCI 12.9" }, + { 203, "HCI 13.2" }, + { 204, "HCI 13.2" }, + { 210, "HCI 13.3" }, + { 211, "HCI 13.3" }, + { 213, "HCI 13.4" }, + { 214, "HCI 13.4" }, + { 225, "HCI 13.5" }, + { 226, "HCI 13.5" }, + { 237, "HCI 13.6" }, + { 238, "HCI 13.6" }, + { 242, "HCI 14.0" }, + { 243, "HCI 14.0" }, + { 244, "HCI 14.0" }, + { 245, "HCI 14.0" }, + { 254, "HCI 13.7" }, + { 255, "HCI 13.7" }, + { 264, "HCI 14.1" }, + { 265, "HCI 14.1" }, + { 267, "HCI 14.2" }, + { 268, "HCI 14.2" }, + { 272, "HCI 14.3" }, + { 273, "HCI 14.3" }, + { 274, "HCI 13.8" }, + { 275, "HCI 13.8" }, + { 286, "HCI 13.9" }, + { 287, "HCI 13.9" }, + { 309, "HCI 13.10" }, + { 310, "HCI 13.10" }, + { 313, "HCI 14.4" }, + { 314, "HCI 14.4" }, + { 323, "HCI 14.5" }, + { 324, "HCI 14.5" }, + { 336, "HCI 14.6" }, + { 337, "HCI 14.6" }, + { 351, "HCI 13.11" }, + { 352, "HCI 13.11" }, + { 362, "HCI 15.0" }, + { 363, "HCI 15.0" }, + { 364, "HCI 15.0" }, + { 365, "HCI 15.0" }, + { 373, "HCI 14.7" }, + { 374, "HCI 14.7" }, + { 379, "HCI 15.1" }, + { 380, "HCI 15.1" }, + { 381, "HCI 15.1" }, + { 382, "HCI 15.1" }, + { 392, "HCI 15.2" }, + { 393, "HCI 15.2" }, + { 394, "HCI 15.2" }, + { 395, "HCI 15.2" }, + { 436, "HCI 16.0" }, + { 437, "HCI 16.0" }, + { 438, "HCI 16.0" }, + { 439, "HCI 16.0" }, + { 443, "HCI 15.3" }, + { 444, "HCI 15.3" }, + { 465, "HCI 16.1" }, + { 466, "HCI 16.1" }, + { 467, "HCI 16.1" }, + { 468, "HCI 16.1" }, + { 487, "HCI 14.8" }, + { 488, "HCI 14.8" }, + { 492, "HCI 16.2" }, + { 493, "HCI 16.2" }, + { 495, "HCI 16.2" }, + { 496, "HCI 16.2" }, + { 502, "HCI 16.1.1" }, + { 503, "HCI 16.1.1" }, + { 504, "HCI 16.1.1" }, + { 505, "HCI 16.1.1" }, + { 506, "HCI 16.1.2" }, + { 507, "HCI 16.1.2" }, + { 508, "HCI 16.1.2" }, + { 509, "HCI 16.1.2" }, + { 516, "HCI 16.3" }, + { 517, "HCI 16.3" }, + { 518, "HCI 16.3" }, + { 519, "HCI 16.3" }, + { 523, "HCI 16.4" }, + { 524, "HCI 16.4" }, + { 525, "HCI 16.4" }, + { 526, "HCI 16.4" }, + { 553, "HCI 15.3" }, + { 554, "HCI 15.3" }, + { 562, "HCI 16.5" }, + { 563, "HCI 16.5" }, + { 564, "HCI 16.5" }, + { 565, "HCI 16.5" }, + { 593, "HCI 17.0" }, + { 594, "HCI 17.0" }, + { 595, "HCI 17.0" }, + { 599, "HCI 17.0" }, + { 600, "HCI 17.0" }, + { 608, "HCI 13.10.1" }, + { 609, "HCI 13.10.1" }, + { 613, "HCI 17.1" }, + { 614, "HCI 17.1" }, + { 615, "HCI 17.1" }, + { 616, "HCI 17.1" }, + { 618, "HCI 17.1" }, + { 624, "HCI 17.2" }, + { 625, "HCI 17.2" }, + { 626, "HCI 17.2" }, + { 627, "HCI 17.2" }, + { 637, "HCI 16.6" }, + { 638, "HCI 16.6" }, + { 639, "HCI 16.6" }, + { 640, "HCI 16.6" }, + { 642, "HCI 13.10.2" }, + { 643, "HCI 13.10.2" }, + { 644, "HCI 13.10.3" }, + { 645, "HCI 13.10.3" }, + { 668, "HCI 13.10.4" }, + { 669, "HCI 13.10.4" }, + { 681, "HCI 16.7" }, + { 682, "HCI 16.7" }, + { 683, "HCI 16.7" }, + { 684, "HCI 16.7" }, + { 704, "HCI 16.8" }, + { 718, "HCI 16.4.1" }, + { 719, "HCI 16.4.1" }, + { 720, "HCI 16.4.1" }, + { 721, "HCI 16.4.1" }, + { 722, "HCI 16.7.1" }, + { 723, "HCI 16.7.1" }, + { 724, "HCI 16.7.1" }, + { 725, "HCI 16.7.1" }, + { 731, "HCI 16.7.2" }, + { 732, "HCI 16.7.2" }, + { 733, "HCI 16.7.2" }, + { 734, "HCI 16.7.2" }, + { 735, "HCI 16.4.2" }, + { 736, "HCI 16.4.2" }, + { 737, "HCI 16.4.2" }, + { 738, "HCI 16.4.2" }, + { 750, "HCI 16.7.3" }, + { 751, "HCI 16.7.3" }, + { 752, "HCI 16.7.3" }, + { 753, "HCI 16.7.3" }, + { 760, "HCI 16.7.4" }, + { 761, "HCI 16.7.4" }, + { 762, "HCI 16.7.4" }, + { 763, "HCI 16.7.4" }, + { 770, "HCI 16.9" }, + { 771, "HCI 16.9" }, + { 772, "HCI 16.9" }, + { 773, "HCI 16.9" }, + { 774, "HCI 17.3" }, + { 775, "HCI 17.3" }, + { 776, "HCI 17.3" }, + { 777, "HCI 17.3" }, + { 781, "HCI 16.7.5" }, + { 786, "HCI 16.10" }, + { 787, "HCI 16.10" }, + { 788, "HCI 16.10" }, + { 789, "HCI 16.10" }, + { 791, "HCI 16.4.3" }, + { 792, "HCI 16.4.3" }, + { 793, "HCI 16.4.3" }, + { 794, "HCI 16.4.3" }, + { 798, "HCI 16.11" }, + { 799, "HCI 16.11" }, + { 800, "HCI 16.11" }, + { 801, "HCI 16.11" }, + { 806, "HCI 16.7.5" }, + { 807, "HCI 16.12" }, + { 808, "HCI 16.12" }, + { 809, "HCI 16.12" }, + { 810, "HCI 16.12" }, + { 817, "HCI 16.13" }, + { 818, "HCI 16.13" }, + { 819, "HCI 16.13" }, + { 820, "HCI 16.13" }, + { 823, "HCI 13.10.5" }, + { 824, "HCI 13.10.5" }, + { 826, "HCI 16.14" }, + { 827, "HCI 16.14" }, + { 828, "HCI 16.14" }, + { 829, "HCI 16.14" }, + { 843, "HCI 17.3.1" }, + { 856, "HCI 17.3.2" }, + { 857, "HCI 17.3.2" }, + { 858, "HCI 17.3.2" }, + { 0, } +}; + +char *csr_buildidtostr(uint16_t id) +{ + static char str[12]; + int i; + + for (i = 0; csr_map[i].id; i++) + if (csr_map[i].id == id) + return csr_map[i].str; + + snprintf(str, 11, "Build %d", id); + return str; +} + +char *csr_chipvertostr(uint16_t ver, uint16_t rev) +{ + switch (ver) { + case 0x00: + return "BlueCore01a"; + case 0x01: + if (rev == 0x64) + return "BlueCore01b (ES)"; + else + return "BlueCore01b"; + case 0x02: + if (rev == 0x89) + return "BlueCore02 (ES2)"; + else + return "BlueCore02"; + default: + return "Unknown"; + } +} + +int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value) +{ + unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) + return -1; + + *value = rp[11] + (rp[12] << 8); + + return 0; +} + +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value) +{ + unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, + pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) + return -1; + + *value = rp[17] + (rp[18] << 8); + + return 0; +} diff --git a/tools/csr.h b/tools/csr.h new file mode 100644 index 00000000..254f108e --- /dev/null +++ b/tools/csr.h @@ -0,0 +1,35 @@ +/* + * + * CSR BlueCore specific functions + * + * Copyright (C) 2003 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define CSR_VARID_BUILDID 0x2819 +#define CSR_VARID_CHIPVER 0x281a +#define CSR_VARID_CHIPREV 0x281b +#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c + +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab + +char *csr_buildidtostr(uint16_t id); +char *csr_chipvertostr(uint16_t ver, uint16_t rev); + +int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 538e03bc..aa3d9ab4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -43,6 +43,8 @@ #include #include +#include "csr.h" + extern int optind,opterr,optopt; extern char *optarg; @@ -268,7 +270,7 @@ void cmd_aclmtu(int ctl, int hdev, char *opt) *((uint16_t *)&dr.dev_opt + 1) = mtu; *((uint16_t *)&dr.dev_opt + 0) = mpkt; - + if (ioctl(ctl, HCISETACLMTU, (unsigned long)&dr) < 0) { printf("Can't set ACL mtu on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -608,21 +610,21 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) printf("Invalid argument format\n"); exit(1); } - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_INQ_ACTIVITY; rq.cparam = &cp; rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; - + cp.window = htobs((uint16_t)window); cp.interval = htobs((uint16_t)interval); - + if (window < 0x12 || window > 0x1000) printf("Warning: inquiry window out of range!\n"); - + if (interval < 0x12 || interval > 0x1000) printf("Warning: inquiry interval out of range!\n"); - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't set inquiry parameters name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -631,12 +633,12 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) } else { uint16_t window, interval; read_inq_activity_rp rp; - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_INQ_ACTIVITY; rq.rparam = &rp; rq.rlen = READ_INQ_ACTIVITY_RP_SIZE; - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't read inquiry parameters on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -648,7 +650,7 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) exit(1); } print_dev_hdr(&di); - + window = btohs(rp.window); interval = btohs(rp.interval); printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", @@ -675,21 +677,21 @@ void cmd_page_parms(int ctl, int hdev, char *opt) printf("Invalid argument format\n"); exit(1); } - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_PAGE_ACTIVITY; rq.cparam = &cp; rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE; - + cp.window = htobs((uint16_t)window); cp.interval = htobs((uint16_t)interval); - + if (window < 0x12 || window > 0x1000) printf("Warning: page window out of range!\n"); - + if (interval < 0x12 || interval > 0x1000) printf("Warning: page interval out of range!\n"); - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't set page parameters name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -698,12 +700,12 @@ void cmd_page_parms(int ctl, int hdev, char *opt) } else { uint16_t window, interval; read_page_activity_rp rp; - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_PAGE_ACTIVITY; rq.rparam = &rp; rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE; - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't read page parameters on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -715,12 +717,12 @@ void cmd_page_parms(int ctl, int hdev, char *opt) exit(1); } print_dev_hdr(&di); - + window = btohs(rp.window); interval = btohs(rp.interval); printf("\tPage interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", interval, (float)interval * 0.625, window, (float)window * 0.625); - } + } } void cmd_page_to(int ctl, int hdev, char *opt) @@ -742,17 +744,17 @@ void cmd_page_to(int ctl, int hdev, char *opt) printf("Invalid argument format\n"); exit(1); } - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_PAGE_TIMEOUT; rq.cparam = &cp; rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE; - + cp.timeout = htobs((uint16_t)timeout); - + if (timeout < 0x01 || timeout > 0xFFFF) printf("Warning: page timeout out of range!\n"); - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't set page timeout on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -761,12 +763,12 @@ void cmd_page_to(int ctl, int hdev, char *opt) } else { uint16_t timeout; read_page_timeout_rp rp; - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_PAGE_TIMEOUT; rq.rparam = &rp; rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE; - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't read page timeout on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -782,7 +784,7 @@ void cmd_page_to(int ctl, int hdev, char *opt) timeout = btohs(rp.timeout); printf("\tPage timeout: %u slots (%.2f ms)\n", timeout, (float)timeout * 0.625); - } + } } static void print_rev_ericsson(int dd) @@ -791,12 +793,12 @@ static void print_rev_ericsson(int dd) unsigned char buf[102]; memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; - rq.ocf = 0x000f; + rq.ogf = 0x3f; + rq.ocf = 0x000f; rq.cparam = NULL; - rq.clen = 0; + rq.clen = 0; rq.rparam = &buf; - rq.rlen = sizeof(buf); + rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 1000) < 0) { printf("\n Can't read revision info. %s(%d)\n", strerror(errno), errno); @@ -806,40 +808,28 @@ static void print_rev_ericsson(int dd) printf("\t%s\n", buf + 1); } -static struct { - char *str; - uint16_t rev; -} csr_map[] = { - { "HCI 11.2 (bc01b)", 114 }, - { "HCI 11.3 (bc01b)", 115 }, - { "HCI 12.1 (bc01b)", 119 }, - { "HCI 12.3 (bc01b)", 134 }, - { "HCI 12.7 (bc01b)", 188 }, - { "HCI 12.8 (bc01b)", 218 }, - { "HCI 12.9 (bc01b)", 283 }, - { "HCI 13.10 (bc01b)", 309 }, - { "HCI 13.11 (bc01b)", 351 }, - { "HCI 16.4 (bc01b)", 523 }, - { "HCI 14.3 (bc02x)", 272 }, - { "HCI 14.6 (bc02x)", 336 }, - { "HCI 14.7 (bc02x)", 373 }, - { "HCI 14.8 (bc02x)", 487 }, - { "HCI 15.3 (bc02x)", 443 }, - { "HCI 16.4 (bc02x)", 525 }, - { NULL } -}; - -static void print_rev_csr(uint16_t rev) +static void print_rev_csr(int dd, uint16_t rev) { - int i; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco; - for (i = 0; csr_map[i].str; i++) - if (csr_map[i].rev == rev) { - printf("\t%s\n", csr_map[i].str); - return; - } + if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { + printf("\t%s\n", csr_buildidtostr(rev)); + return; + } + + printf("\t%s\n", csr_buildidtostr(buildid)); + + if (!csr_read_varid_uint16(dd, 1, CSR_VARID_CHIPVER, &chipver)) { + if (csr_read_varid_uint16(dd, 2, CSR_VARID_CHIPREV, &chiprev) < 0) + chiprev = 0; + printf("\tChip version: %s\n", csr_chipvertostr(chipver, chiprev)); + } + + if (!csr_read_varid_uint16(dd, 3, CSR_VARID_MAX_CRYPT_KEY_LENGTH, &maxkeylen)) + printf("\tMax key size: %d bit\n", maxkeylen * 8); - printf("\tUnknown firmware\n"); + if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) + printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); } static void print_rev_avm(uint16_t rev) @@ -870,7 +860,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_rev_ericsson(dd); break; case 10: - print_rev_csr(ver.hci_rev); + print_rev_csr(dd, ver.hci_rev); break; case 31: print_rev_avm(ver.hci_rev); @@ -890,13 +880,13 @@ void print_dev_hdr(struct hci_dev_info *di) if (hdr == di->dev_id) return; hdr = di->dev_id; - + baswap(&bdaddr, &di->bdaddr); printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", - batostr(&bdaddr), di->acl_mtu, di->acl_pkts, - di->sco_mtu, di->sco_pkts); + batostr(&bdaddr), di->acl_mtu, di->acl_pkts, + di->sco_mtu, di->sco_pkts); } void print_dev_info(int ctl, struct hci_dev_info *di) @@ -908,10 +898,10 @@ void print_dev_info(int ctl, struct hci_dev_info *di) printf("\t%s\n", hci_dflagstostr(di->flags) ); printf("\tRX bytes:%d acl:%d sco:%d events:%d errors:%d\n", - st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx); + st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx); printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n", - st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); + st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); if (all) { print_dev_features(di, 0); @@ -925,7 +915,7 @@ void print_dev_info(int ctl, struct hci_dev_info *di) cmd_version(ctl, di->dev_id, NULL); } } - + printf("\n"); } @@ -1033,7 +1023,7 @@ int main(int argc, char **argv, char **env) if (command[i].opt) { argc--; argv++; } - + command[i].func(ctl, di.dev_id, *argv); cmd = 1; break; -- cgit From 6b410af5c3e83f36ed8b5a620f1ab3029a271058 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Jul 2003 17:34:34 +0000 Subject: Kill usage of strtoba() and batostr() --- tools/hciconfig.c | 6 +++--- tools/hcitool.c | 29 +++++++++++++++-------------- tools/l2ping.c | 9 +++++---- 3 files changed, 23 insertions(+), 21 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index aa3d9ab4..c1df2815 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -875,17 +875,17 @@ static void cmd_revision(int ctl, int hdev, char *opt) void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; - bdaddr_t bdaddr; + char addr[18]; if (hdr == di->dev_id) return; hdr = di->dev_id; - baswap(&bdaddr, &di->bdaddr); + ba2str(&di->bdaddr, addr); printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", - batostr(&bdaddr), di->acl_mtu, di->acl_pkts, + addr, di->acl_mtu, di->acl_pkts, di->sco_mtu, di->sco_pkts); } diff --git a/tools/hcitool.c b/tools/hcitool.c index 88c53266..59235270 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -56,12 +56,13 @@ static void usage(void); static int dev_info(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; - bdaddr_t bdaddr; + char addr[18]; + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; - baswap(&bdaddr, &di.bdaddr); - printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); + ba2str(&di.bdaddr, addr); + printf("\t%s\t%s\n", di.name, addr); return 0; } @@ -89,12 +90,12 @@ static int conn_list(int s, int dev_id, long arg) } for (i=0; i < cl->conn_num; i++, ci++) { - bdaddr_t bdaddr; - baswap(&bdaddr, &ci->bdaddr); + char addr[18]; + ba2str(&ci->bdaddr, addr); printf("\t%s %s %s handle %d state %d lm %s\n", ci->out ? "<" : ">", ci->type == ACL_LINK ? "ACL" : "SCO", - batostr(&bdaddr), ci->handle, ci->state, + addr, ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } return 0; @@ -188,7 +189,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) { int num_rsp, length, flags; inquiry_info *info = NULL; - bdaddr_t bdaddr; + char addr[18]; int i, opt; length = 8; /* ~10 seconds */ @@ -223,9 +224,9 @@ static void cmd_inq(int dev_id, int argc, char **argv) } for (i = 0; i < num_rsp; i++) { - baswap(&bdaddr, &(info+i)->bdaddr); + ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", - batostr(&bdaddr), (info+i)->clock_offset, + addr, (info+i)->clock_offset, (info+i)->dev_class[2], (info+i)->dev_class[1], (info+i)->dev_class[0]); @@ -251,7 +252,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - bdaddr_t bdaddr; + char addr[18]; char name[248]; int i, opt, dd; @@ -280,7 +281,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (dev_id < 0) { - dev_id = hci_get_route(&bdaddr); + dev_id = hci_get_route(NULL); if (dev_id < 0) { perror("Device is not available"); exit(1); @@ -305,8 +306,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) memset(name, 0, sizeof(name)); if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - baswap(&bdaddr, &(info+i)->bdaddr); - printf("\t%s\t%s\n", batostr(&bdaddr), name); + ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); } close(dd); @@ -345,7 +346,7 @@ static void cmd_name(int dev_id, int argc, char **argv) return; } - baswap(&bdaddr, strtoba(argv[0])); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); diff --git a/tools/l2ping.c b/tools/l2ping.c index 310ba86b..d5d7748b 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -77,6 +77,7 @@ static void ping(char *svr) struct sockaddr_l2 addr; struct sigaction sa; char buf[2048]; + char str[18]; int s, i, opt, lost; uint8_t id; @@ -97,7 +98,7 @@ static void ping(char *svr) exit(1); } - baswap(&addr.l2_bdaddr, strtoba(svr)); + str2ba(svr, &addr.l2_bdaddr); if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Can't connect."); exit(1); @@ -109,9 +110,9 @@ static void ping(char *svr) perror("Can't get local address."); exit(1); } - baswap(&bdaddr, &addr.l2_bdaddr); + ba2str(&addr.l2_bdaddr, str); - printf("Ping: %s from %s (data size %d) ...\n", svr, batostr(&bdaddr), size); + printf("Ping: %s from %s (data size %d) ...\n", svr, str, size); /* Initialize buffer */ for(i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) @@ -231,7 +232,7 @@ int main(int argc, char *argv[]) break; case 'S': - baswap(&bdaddr, strtoba(optarg)); + str2ba(optarg, &bdaddr); break; default: -- cgit From 4e2dd78121a7c16836a1e28b6f545e4dd9c2d596 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 27 Aug 2003 09:55:43 +0000 Subject: Support for 3Com card version 3.0 --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 05230d3c..5e33c97e 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -764,6 +764,9 @@ struct uart_t uart[] = { /* Socket Bluetooth CF Card (Rev G) */ { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, + /* 3Com Bluetooth Card (Version 3.0) */ + { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + { NULL, 0 } }; -- cgit From 68e6756b899d040b14062baaa1ae9ae0e14f3b02 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Sep 2003 21:40:13 +0000 Subject: Correct decoding class of device --- tools/hciconfig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index c1df2815..c241b7d5 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -516,11 +516,11 @@ void cmd_class(int ctl, int hdev, char *opt) } else printf("Unspecified"); printf("\n\tDevice Class: "); - if (cls[1] > sizeof(major_devices)) + if ((cls[1] & 0x1f) > sizeof(major_devices)) printf("Invalid Device Class!\n"); else - printf("%s, %s\n", major_devices[cls[1]], - get_minor_device_name(cls[1], cls[0] / 4)); + printf("%s, %s\n", major_devices[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); } } -- cgit From cebcc0af94a87b9e416bad4fe9567dcd1315b4cc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 6 Nov 2003 11:20:24 +0000 Subject: Fix minor class decoding of the peripheral major class --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index c241b7d5..9787fe79 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -443,7 +443,7 @@ static char *get_minor_device_name(int major, int minor) return "Keyboard"; case 32: return "Pointing device"; - case 64: + case 48: return "Combo keyboard/pointing device"; } break; -- cgit From 61011fc68193ff2f1b75a69a83323a41ca6fe5fd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 16 Nov 2003 12:51:32 +0000 Subject: Use Ericsson revision command for ST Microelectronics devices --- tools/hciconfig.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 9787fe79..e2acba83 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -857,6 +857,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_dev_hdr(&di); switch (ver.manufacturer) { case 0: + case 48: print_rev_ericsson(dd); break; case 10: -- cgit From bfe1cc41a50bda9420bf0ca43b0caabe12955eef Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 17 Nov 2003 15:30:14 +0000 Subject: add iac command --- tools/hciconfig.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index e2acba83..932ec4e7 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -137,6 +137,50 @@ void cmd_scan(int ctl, int hdev, char *opt) } } +void cmd_iac(int ctl, int hdev, char *opt) +{ + int s = hci_open_dev(hdev); + + if (s < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + if (opt) { + int l = strtoul(opt, 0, 16); + uint8_t lap[3]; + if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + if (hci_write_current_iac_lap(s, 1, lap, 1000) < 0) { + printf("Failed to set IAC on hci%d: %s\n", hdev, strerror(errno)); + exit(1); + } + } else { + uint8_t lap[3 * MAX_IAC_LAP]; + int i, j; + uint8_t n; + if (hci_read_current_iac_lap(s, &n, lap, 1000) < 0) { + printf("Failed to read IAC from hci%d: %s\n", hdev, strerror(errno)); + exit(1); + } + print_dev_hdr(&di); + printf("\tIAC: "); + for (i = 0; i < n; i++) { + printf("0x"); + for (j = 3; j--; ) + printf("%02x", lap[j + 3*i]); + if (i < n-1) + printf(", "); + } + printf("\n"); + } + close(s); +} + void cmd_auth(int ctl, int hdev, char *opt) { struct hci_dev_req dr; @@ -913,6 +957,7 @@ void print_dev_info(int ctl, struct hci_dev_info *di) if (hci_test_bit(HCI_UP, &di->flags)) { cmd_name(ctl, di->dev_id, NULL); cmd_class(ctl, di->dev_id, NULL); + cmd_iac(ctl, di->dev_id, NULL); cmd_version(ctl, di->dev_id, NULL); } } @@ -952,6 +997,7 @@ struct { { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, { "revision", cmd_revision, 0, "Display revision information" }, + { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { NULL, NULL, 0 } }; -- cgit From d877c418537d529a9c693f23b59ca8b61e089e43 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 08:16:21 +0000 Subject: Add ST Microelectronics specific initialization --- tools/hciattach.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 5e33c97e..799e338d 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -150,7 +150,7 @@ static int read_hci_event(int fd, unsigned char* buf, int size) static int ericsson(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 50000}; - char cmd[10]; + char cmd[5]; cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x09; @@ -194,7 +194,7 @@ static int ericsson(int fd, struct uart_t *u, struct termios *ti) static int digi(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 50000}; - char cmd[10]; + char cmd[5]; /* DigiAnswer set baud rate command */ cmd[0] = HCI_COMMAND_PKT; @@ -227,7 +227,7 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) static int texas(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 50000}; - char cmd[10]; + char cmd[4]; unsigned char resp[100]; /* Response */ int n; @@ -241,7 +241,7 @@ static int texas(int fd, struct uart_t *u, struct termios *ti) cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x01; cmd[2] = 0x10; - cmd[3] = 0x00; + cmd[3] = 0x00; do { n = write(fd, cmd, 4); @@ -632,7 +632,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) static int swave(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 500000}; - char cmd[10], rsp[100]; + char cmd[9], rsp[100]; int r; // Silicon Wave set baud rate command @@ -671,7 +671,7 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } /* Send initialization command */ - if (write(fd, cmd, 10) != 5) { + if (write(fd, cmd, 9) != 9) { perror("Failed to write init command"); return -1; } @@ -729,6 +729,61 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) return 0; } +/* + * ST Microelectronics specific initialization + * Marcel Holtmann + */ +static int st(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[5]; + + /* ST Microelectronics set baud rate command */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x46; // OCF = Hci_Cmd_ST_Set_Uart_Baud_Rate + cmd[2] = 0xfc; // OGF = Vendor specific + cmd[3] = 0x01; + + switch (u->speed) { + case 9600: + cmd[4] = 0x09; + break; + case 19200: + cmd[4] = 0x0b; + break; + case 38400: + cmd[4] = 0x0d; + break; + case 57600: + cmd[4] = 0x0e; + break; + case 115200: + cmd[4] = 0x10; + break; + case 230400: + cmd[4] = 0x12; + break; + case 460800: + cmd[4] = 0x13; + break; + case 921600: + cmd[4] = 0x14; + break; + default: + cmd[4] = 0x10; + u->speed = 57600; + break; + } + + /* Send initialization command */ + if (write(fd, cmd, 5) != 5) { + perror("Failed to write init command"); + return -1; + } + nanosleep(&tm, NULL); + return 0; +} + struct uart_t uart[] = { { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, @@ -749,6 +804,9 @@ struct uart_t uart[] = { /* Silicon Wave kits */ { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, + /* ST Microelectronics minikits based on STLC2410/STLC2415 */ + { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, st }, + /* Sphinx Electronics PICO Card */ { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, -- cgit From 7fbea8e4421d04d23747ad4dbcc31aa2d10e0c74 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 11:38:31 +0000 Subject: Display all 8 bytes of the features --- tools/hciconfig.c | 10 +++++++--- tools/hcitool.c | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 932ec4e7..ee7afb75 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -97,13 +97,17 @@ void print_link_mode(struct hci_dev_info *di) void print_dev_features(struct hci_dev_info *di, int format) { if (!format) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", di->features[0], di->features[1], - di->features[2], di->features[3] ); + di->features[2], di->features[3], + di->features[4], di->features[5], + di->features[6], di->features[7] ); } else { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", di->features[0], di->features[1], di->features[2], di->features[3], + di->features[4], di->features[5], + di->features[6], di->features[7], lmp_featurestostr(di->features, "\t\t", 3)); } } diff --git a/tools/hcitool.c b/tools/hcitool.c index 59235270..cd546735 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -462,8 +462,9 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7], lmp_featurestostr(features, "\t\t", 3)); } -- cgit From 8246c9b6086d525ca83a05da5c8ed370662a69e1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 14:31:29 +0000 Subject: Update iac command and add entry to the manpage --- tools/hciconfig.8 | 6 ++++++ tools/hciconfig.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 96b503ae..aac5e98a 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -115,6 +115,12 @@ prints voice setting. Otherwise, sets voice setting to voice is a 16-bit hex number describing the voice setting. .TP +.BI iac " [iac]" +With no +.IR iac , +prints the current IAC setting. Otherwise, sets the IAC to +.IR iac . +.TP .BI inqparms " [win:int]" With no .IR win:int , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ee7afb75..b51fcc7e 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -356,6 +356,7 @@ void cmd_features(int ctl, int hdev, char *opt) void cmd_name(int ctl, int hdev, char *opt) { int s = hci_open_dev(hdev); + if (s < 0) { printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); @@ -993,6 +994,7 @@ struct { { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, + { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, @@ -1001,7 +1003,6 @@ struct { { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, { "revision", cmd_revision, 0, "Display revision information" }, - { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { NULL, NULL, 0 } }; -- cgit From d0008d9f3d92b9b38cc3a53687fa391f7adbe9c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 14:36:31 +0000 Subject: Don't read the IAC with a default call --- tools/hciconfig.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index b51fcc7e..92292a20 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -962,7 +962,6 @@ void print_dev_info(int ctl, struct hci_dev_info *di) if (hci_test_bit(HCI_UP, &di->flags)) { cmd_name(ctl, di->dev_id, NULL); cmd_class(ctl, di->dev_id, NULL); - cmd_iac(ctl, di->dev_id, NULL); cmd_version(ctl, di->dev_id, NULL); } } -- cgit From 8793e6002250dde7f85ab89410ad96aebf2dbb76 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 16 Dec 2003 18:45:07 +0000 Subject: Increase number of inquiry responses --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index cd546735..f8125f43 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -193,7 +193,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) int i, opt; length = 8; /* ~10 seconds */ - num_rsp = 10; + num_rsp = 100; flags = 0; for_each_opt(opt, inq_options, NULL) { @@ -257,7 +257,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int i, opt, dd; length = 8; /* ~10 seconds */ - num_rsp = 10; + num_rsp = 100; flags = 0; for_each_opt(opt, scan_options, NULL) { -- cgit From 16e217b4b13b828a9bb6c372d544deafa0e01f24 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Dec 2003 16:08:25 +0000 Subject: Fix automatic connection creation for the info command --- tools/hcitool.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index f8125f43..0194b650 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -410,10 +410,8 @@ static void cmd_info(int dev_id, int argc, char **argv) if (dev_id < 0) dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); - if (dev_id < 0) { + if (dev_id < 0) dev_id = hci_get_route(&bdaddr); - cc = 1; - } if (dev_id < 0) { fprintf(stderr, "Device is not available or not connected.\n"); @@ -428,26 +426,24 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - if (cc) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't get connection info"); + close(dd); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); } - } else { - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; - - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - perror("Get connection info failed"); - exit(1); - } - + cc = 1; + } else handle = cr->conn_info->handle; - } printf("\tBD Address: %s\n", argv[0]); -- cgit From 2cabb56f7528c9756617dbae8a73d9878bfa9b59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Feb 2004 23:25:53 +0000 Subject: Fix endian problem with hci_create_connection() --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 0194b650..675d829e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -436,7 +436,7 @@ static void cmd_info(int dev_id, int argc, char **argv) bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, htobs(HCI_DM1 | HCI_DH1), 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -653,7 +653,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 1000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From 1118351ad3803d4508a146762775a9ee1e05c09c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Feb 2004 18:05:38 +0000 Subject: Replace unprintable characters for device name --- tools/hciconfig.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 92292a20..651e1438 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -369,11 +370,15 @@ void cmd_name(int ctl, int hdev, char *opt) } } else { char name[248]; + int i; if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { printf("Can't read local name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } + for (i = 0; i < 248 && name[i]; i++) + if (!isprint(name[i])) + name[i] = '.'; print_dev_hdr(&di); printf("\tName: '%s'\n", name); } -- cgit From f3be9c15792728861db02c8b0a3692903a30552b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Feb 2004 23:20:50 +0000 Subject: Add command for authentication request --- tools/hcitool.1 | 4 +++ tools/hcitool.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index dd92e351..bb52e1ba 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -154,6 +154,10 @@ slots, or to infinite if .I value is 0. +.TP +.BI auth " " +Request authentication for the device with Bluetooth address +.IR bdaddr . .SH AUTHORS Written by Maxim Krasnyansky .PP diff --git a/tools/hcitool.c b/tools/hcitool.c index 675d829e..3a4a59ef 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1255,6 +1255,88 @@ static void cmd_lst(int dev_id, int argc, char **argv) free(cr); } +/* Request authentication */ + +static struct option auth_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *auth_help = + "Usage:\n" + "\tauth \n"; + +static void cmd_auth(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + auth_requested_cp cp; + evt_auth_complete rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, auth_options, NULL) { + switch(opt) { + default: + printf(auth_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(auth_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; + rq.cparam = &cp; + rq.clen = AUTH_REQUESTED_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_AUTH_COMPLETE_SIZE; + rq.event = EVT_AUTH_COMPLETE; + + if (hci_send_req(dd, &rq, 25000) < 0) { + perror("HCI authentication request failed"); + exit(1); + } + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1268,14 +1350,15 @@ struct { { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, { "sr", cmd_sr, "Switch master/slave role" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, - { NULL, NULL, 0} + { "auth", cmd_auth, "Request authentication" }, + { NULL, NULL, 0 } }; static void usage(void) -- cgit From 136fe53de38de79eda487f3c5c690cab45b1767a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Mar 2004 17:38:39 +0000 Subject: Display revision information for Broadcom devices --- tools/hciconfig.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 651e1438..39804e45 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -886,6 +886,11 @@ static void print_rev_csr(int dd, uint16_t rev) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); } +static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) +{ + printf("\tFirmware %d.%d.%03d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); +} + static void print_rev_avm(uint16_t rev) { printf("\tFirmware 03.%d.%d\n", rev >> 8, rev & 0xff); @@ -917,6 +922,9 @@ static void cmd_revision(int ctl, int hdev, char *opt) case 10: print_rev_csr(dd, ver.hci_rev); break; + case 15: + print_rev_broadcom(ver.hci_rev, ver.lmp_subver); + break; case 31: print_rev_avm(ver.hci_rev); break; -- cgit From 4352b6d63fb5eb038e5f678ae143f97662b7db3b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Mar 2004 21:25:22 +0000 Subject: Add support for setting connection encryption --- tools/hcitool.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 98 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 3a4a59ef..8fd7b83d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -146,7 +146,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) /* Display local devices */ static struct option dev_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -265,7 +265,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) case 'l': length = atoi(optarg); break; - + case 'n': num_rsp = atoi(optarg); break; @@ -317,7 +317,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) /* Remote name */ static struct option name_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -699,7 +699,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -849,7 +849,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -866,7 +866,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; @@ -933,7 +933,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -958,7 +958,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) rq.clen = 2; rq.rparam = &rp; rq.rlen = GET_LINK_QUALITY_RP_SIZE; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI get_link_quality request failed"); exit(1); @@ -1020,7 +1020,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1046,7 +1046,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; rq.rparam = &rp; rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI read transmit power level request failed"); exit(1); @@ -1109,7 +1109,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1192,7 +1192,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1234,8 +1234,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) rp.link_sup_to, (float)rp.link_sup_to * 0.625); else printf("Link supervision timeout never expires\n"); - } - else { + } else { cp.handle = cr->conn_info->handle; cp.link_sup_to = strtol(argv[1], NULL, 10); @@ -1337,7 +1336,90 @@ static void cmd_auth(int dev_id, int argc, char **argv) free(cr); } -struct { +/* Activate encryption */ + +static struct option enc_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *enc_help = + "Usage:\n" + "\tenc [encrypt enable]\n"; + +static void cmd_enc(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + set_conn_encrypt_cp cp; + evt_encrypt_change rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, enc_options, NULL) { + switch(opt) { + default: + printf(enc_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(enc_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.cparam = &cp; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.event = EVT_ENCRYPT_CHANGE; + + if (hci_send_req(dd, &rq, 25000) < 0) { + perror("HCI set encryption request failed"); + exit(1); + } + + close(dd); + free(cr); +} + +static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); char *doc; @@ -1358,6 +1440,7 @@ struct { { "tpl", cmd_tpl, "Display transmit power level" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, + { "enc", cmd_enc, "Set connection encryption" }, { NULL, NULL, 0 } }; -- cgit From 280cca9f112cbc2f86a9b7653a2ad003769e4fcb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 20:14:52 +0000 Subject: Add sdptool utility --- tools/Makefile.am | 7 +- tools/sdptool.1 | 116 +++ tools/sdptool.c | 2072 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2192 insertions(+), 3 deletions(-) create mode 100644 tools/sdptool.1 create mode 100644 tools/sdptool.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 180c0cc1..4ddeb5c9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -5,12 +5,13 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = hciattach hciconfig -bin_PROGRAMS = hcitool l2ping + +bin_PROGRAMS = hcitool l2ping sdptool hciconfig_SOURCES = hciconfig.c csr.h csr.c -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 noinst_PROGRAMS = ppporc -EXTRA_DIST = $(man_MANS) +EXTRA_DIST = $(man_MANS) diff --git a/tools/sdptool.1 b/tools/sdptool.1 new file mode 100644 index 00000000..8f938f92 --- /dev/null +++ b/tools/sdptool.1 @@ -0,0 +1,116 @@ +.\" $Header$ +.\" +.\" transcript compatibility for postscript use. +.\" +.\" synopsis: .P! +.\" +.de P! +.fl +\!!1 setgray +.fl +\\&.\" +.fl +\!!0 setgray +.fl \" force out current output buffer +\!!save /psv exch def currentpoint translate 0 0 moveto +\!!/showpage{}def +.fl \" prolog +.sy sed -e 's/^/!/' \\$1\" bring in postscript file +\!!psv restore +. +.de pF +.ie \\*(f1 .ds f1 \\n(.f +.el .ie \\*(f2 .ds f2 \\n(.f +.el .ie \\*(f3 .ds f3 \\n(.f +.el .ie \\*(f4 .ds f4 \\n(.f +.el .tm ? font overflow +.ft \\$1 +.. +.de fP +.ie !\\*(f4 \{\ +. ft \\*(f4 +. ds f4\" +' br \} +.el .ie !\\*(f3 \{\ +. ft \\*(f3 +. ds f3\" +' br \} +.el .ie !\\*(f2 \{\ +. ft \\*(f2 +. ds f2\" +' br \} +.el .ie !\\*(f1 \{\ +. ft \\*(f1 +. ds f1\" +' br \} +.el .tm ? font underflow +.. +.ds f1\" +.ds f2\" +.ds f3\" +.ds f4\" +'\" t +.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n +.TH "sdptool" "1" +.SH "NAME" +sdptool \(em control and interrogate SDP servers +.SH "SYNOPSIS" +.PP +\fBsdptool\fR [\fIoptions\fR] {\fIcommand\fR} [\fIcommand parameters\fR \&...] +.SH "DESCRIPTION" +.PP +\fBsdptool\fR provides the interface for +performing SDP queries on Bluetooth devices, and administering a +local \fBsdpd\fR. +.SH "COMMANDS" +.PP +The following commands are available. +.IP "\fBsearch [--bdaddr bdaddr] [--tree] service\fP" 10 +Search for services.. +.IP "" 10 +Known service names are SP< DUN, LAN, FAX, OPUSH, +FTRN, NAP, GN, HID, CIP. +.IP "\fBbrowse [--tree] [bdaddr]\fP" 10 +Browse all available services on the device +specified by a Bluetooth address as a parameter. +.IP "\fBadd [ --channel=N ]\fP" 10 +Add a service to the local +\fBsdpd\fR. +.IP "" 10 +You can specify a channel to add the service on +using the \fB--channel\fP option. +.IP "\fBdel record_handle\fP" 10 +Remove a service from the local +\fBsdpd\fR. +.IP "\fBget [--tree] [--bdaddr bdaddr] record_handle\fP" 10 +Retrieve a service from the local +\fBsdpd\fR. +.IP "\fBsetattr record_handle attrib_id attrib_value\fP" 10 +Set or add an attribute to an SDP record. + +.IP "\fBsetseq record_handle attrib_id attrib_values\fP" 10 +Set or add an attribute sequence to an +SDP record. +.SH "OPTIONS" +.IP "\fB--help\fP" 10 +Displays help on using sdptool. + +.SH "EXAMPLES" +.PP +sdptool browse 00:80:98:24:15:6D +.PP +sdptool add DUN +.PP +sdptool del LAN +.SH "BUGS" +.PP +Documentation needs improving. +.SH "AUTHOR" +.PP +Maxim Krasnyansky . Man page written +by Edd Dumbill . + +.SH "SEE ALSO" +.PP +sdpd(8) +.\" created by instant / docbook-to-man, Thu 15 Jan 2004, 21:01 diff --git a/tools/sdptool.c b/tools/sdptool.c new file mode 100644 index 00000000..5340ab1b --- /dev/null +++ b/tools/sdptool.c @@ -0,0 +1,2072 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky + Copyright (C) 2002 Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1) + +/* + * Convert a string to a BDADDR, with a few "enhancements" - Jean II + */ +int estr2ba(char *str, bdaddr_t *ba) +{ + /* Only trap "local", "any" is already dealt with */ + if(!strcmp(str, "local")) { + bacpy(ba, BDADDR_LOCAL); + return 0; + } + return str2ba(str, ba); +} + +/* Pass args to the inquiry/search handler */ +struct search_context { + char *svc; /* Service */ + uuid_t group; /* Browse group */ + int tree; /* Display full attribute tree */ + uint32_t handle; /* Service record handle */ +}; + +typedef int (*handler_t)(bdaddr_t *bdaddr, struct search_context *arg); + +static char UUID_str[MAX_LEN_UUID_STR]; +static bdaddr_t interface; + +/* Definition of attribute members */ +struct member_def { + char *name; +}; + +/* Definition of an attribute */ +struct attrib_def { + int num; /* Numeric ID - 16 bits */ + char * name; /* User readable name */ + struct member_def * members; /* Definition of attribute args */ + int member_max; /* Max of attribute arg definitions */ +}; + +/* Definition of a service or protocol */ +struct uuid_def { + int num; /* Numeric ID - 16 bits */ + char * name; /* User readable name */ + struct attrib_def * attribs; /* Specific attribute definitions */ + int attrib_max; /* Max of attribute definitions */ +}; + +/* Context information about current attribute */ +struct attrib_context { + struct uuid_def * service; /* Service UUID, if known */ + struct attrib_def * attrib; /* Description of the attribute */ + int member_index; /* Index of current attribute member */ +}; + +/* Context information about the whole service */ +struct service_context { + struct uuid_def * service; /* Service UUID, if known */ +}; + +/* Allow us to do nice formatting of the lists */ +static char *indent_spaces = " "; + +/* ID of the service attribute. + * Most attributes after 0x200 are defined based on the service, so + * we need to find what is the service (which is messy) - Jean II */ +#define SERVICE_ATTR 0x1 + +/* Definition of the optional arguments in protocol list */ +static struct member_def protocol_members[] = { + { "Protocol" }, + { "Channel/Port" }, + { "Version" }, +}; + +/* Definition of the optional arguments in profile list */ +static struct member_def profile_members[] = { + { "Profile" }, + { "Version" }, +}; + +/* Definition of the optional arguments in Language list */ +static struct member_def language_members[] = { + { "Code ISO639" }, + { "Encoding" }, + { "Base Offset" }, +}; + +/* Name of the various common attributes. See BT assigned numbers */ +static struct attrib_def attrib_names[] = { + { 0x0, "ServiceRecordHandle", NULL, 0 }, + { 0x1, "ServiceClassIDList", NULL, 0 }, + { 0x2, "ServiceRecordState", NULL, 0 }, + { 0x3, "ServiceID", NULL, 0 }, + { 0x4, "ProtocolDescriptorList", + protocol_members, sizeof(protocol_members)/sizeof(struct member_def) }, + { 0x5, "BrowseGroupList", NULL, 0 }, + { 0x6, "LanguageBaseAttributeIDList", + language_members, sizeof(language_members)/sizeof(struct member_def) }, + { 0x7, "ServiceInfoTimeToLive", NULL, 0 }, + { 0x8, "ServiceAvailability", NULL, 0 }, + { 0x9, "BluetoothProfileDescriptorList", + profile_members, sizeof(profile_members)/sizeof(struct member_def) }, + { 0xA, "DocumentationURL", NULL, 0 }, + { 0xB, "ClientExecutableURL", NULL, 0 }, + { 0xC, "IconURL", NULL, 0 }, + { 0xD, "AdditionalProtocolDescriptorLists", NULL, 0 }, + /* Definitions after that are tricky (per profile or offset) */ +}; + +const int attrib_max = sizeof(attrib_names)/sizeof(struct attrib_def); + +/* Name of the various SPD attributes. See BT assigned numbers */ +static struct attrib_def sdp_attrib_names[] = { + { 0x200, "VersionNumberList", NULL, 0 }, + { 0x201, "ServiceDatabaseState", NULL, 0 }, +}; + +/* Name of the various SPD attributes. See BT assigned numbers */ +static struct attrib_def browse_attrib_names[] = { + { 0x200, "GroupID", NULL, 0 }, +}; + +/* Name of the various PAN attributes. See BT assigned numbers */ +/* Note : those need to be double checked - Jean II */ +static struct attrib_def pan_attrib_names[] = { + { 0x200, "IpSubnet", NULL, 0 }, /* Obsolete ??? */ + { 0x30A, "SecurityDescription", NULL, 0 }, + { 0x30B, "NetAccessType", NULL, 0 }, + { 0x30C, "MaxNetAccessrate", NULL, 0 }, + { 0x30D, "IPv4Subnet", NULL, 0 }, + { 0x30E, "IPv6Subnet", NULL, 0 }, +}; + +/* Name of the various Generic-Audio attributes. See BT assigned numbers */ +/* Note : totally untested - Jean II */ +static struct attrib_def audio_attrib_names[] = { + { 0x302, "Remote audio volume control", NULL, 0 }, +}; + +/* Same for the UUIDs. See BT assigned numbers */ +static struct uuid_def uuid16_names[] = { + /* -- Protocols -- */ + { 0x1, "SDP (Service Discovery Protocol)", NULL, 0 }, + { 0x2, "UDP", NULL, 0 }, + { 0x3, "RFCOMM", NULL, 0 }, + { 0x4, "TCP", NULL, 0 }, + { 0x5, "TCS-BIN", NULL, 0 }, + { 0x6, "TCS-AT", NULL, 0 }, + { 0x8, "OBEX", NULL, 0 }, + { 0x9, "IP", NULL, 0 }, + { 0xA, "FTP", NULL, 0 }, + { 0xC, "HTTP", NULL, 0 }, + { 0xE, "WSP", NULL, 0 }, + { 0xF, "BNEP (PAN/BNEP)", NULL, 0 }, + { 0x10, "UPnP/ESDP", NULL, 0 }, + { 0x11, "HIDP", NULL, 0 }, + { 0x12, "HardcopyControlChannel", NULL, 0 }, + { 0x14, "HardcopyDataChannel", NULL, 0 }, + { 0x16, "HardcopyNotification", NULL, 0 }, + { 0x17, "AVCTP", NULL, 0 }, + { 0x19, "AVDTP", NULL, 0 }, + { 0x1B, "CMTP", NULL, 0 }, + { 0x1D, "UDI_C-Plane", NULL, 0 }, + { 0x100, "L2CAP", NULL, 0 }, + /* -- Services -- */ + { 0x1000, "ServiceDiscoveryServerServiceClassID (SDP)", + sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) }, + { 0x1001, "BrowseGroupDescriptorServiceClassID (SDP)", + browse_attrib_names, + sizeof(browse_attrib_names)/sizeof(struct attrib_def) }, + { 0x1002, "PublicBrowseGroup (SDP)", NULL, 0 }, + { 0x1101, "SerialPort", NULL, 0 }, + { 0x1102, "LANAccessUsingPPP", NULL, 0 }, + { 0x1103, "DialupNetworking (DUN)", NULL, 0 }, + { 0x1104, "IrMCSync", NULL, 0 }, + { 0x1105, "OBEXObjectPush", NULL, 0 }, + { 0x1106, "OBEXFileTransfer", NULL, 0 }, + { 0x1107, "IrMCSyncCommand", NULL, 0 }, + { 0x1108, "Headset", + audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, + { 0x1109, "CordlessTelephony", NULL, 0 }, + /* ... */ + { 0x110F, "VideoConferencing", NULL, 0 }, + { 0x1110, "Intercom", NULL, 0 }, + { 0x1111, "Fax", NULL, 0 }, + { 0x1112, "HeadsetAudioGateway", NULL, 0 }, + { 0x1113, "WAP", NULL, 0 }, + { 0x1114, "WAP_CLIENT", NULL, 0 }, + { 0x1115, "PANU (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1116, "NAP (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1117, "GN (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1118, "DirectPrinting (BPP)", NULL, 0 }, + { 0x1119, "ReferencePrinting (BPP)", NULL, 0 }, + /* ... */ + { 0x111e, "Handsfree", NULL, 0 }, + { 0x111f, "HandsfreeAudioGateway", NULL, 0 }, + { 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 }, + { 0x1121, "ReflectedUI (BPP)", NULL, 0 }, + { 0x1122, "BasicPrinting (BPP)", NULL, 0 }, + { 0x1123, "PrintingStatus (BPP)", NULL, 0 }, + { 0x1124, "HumanInterfaceDeviceService (HID)", NULL, 0 }, + { 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 }, + { 0x1126, "HCR_Print (HCR)", NULL, 0 }, + { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, + { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, + { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, + /* ... */ + { 0x1200, "PnPInformation", NULL, 0 }, + { 0x1201, "GenericNetworking", NULL, 0 }, + { 0x1202, "GenericFileTransfer", NULL, 0 }, + { 0x1203, "GenericAudio", + audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, + { 0x1204, "GenericTelephony", NULL, 0 }, +}; + +const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); + +void sdp_data_printf(sdp_data_t *, struct attrib_context *, int); + +/* + * Parse a UUID. + * The BT assigned numbers only list UUID16, so I'm not sure the + * other types will ever get used... + */ +void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int indent) +{ + if (uuid) { + if (uuid->type == SDP_UUID16) { + uint16_t uuidNum = uuid->value.uuid16; + struct uuid_def *uuidDef = NULL; + int i; + + for(i = 0; i < uuid16_max; i++) + if(uuid16_names[i].num == uuidNum) { + uuidDef = &uuid16_names[i]; + break; + } + + /* Check if it's the service attribute */ + if (context->attrib && context->attrib->num == SERVICE_ATTR) { + /* We got the service ID !!! */ + context->service = uuidDef; + } + + if(uuidDef) + printf("%.*sUUID16 : 0x%.4x - %s\n", + indent, indent_spaces, + uuidNum, uuidDef->name); + else + printf("%.*sUUID16 : 0x%.4x\n", + indent, indent_spaces, uuidNum); + } else if (uuid->type == SDP_UUID32) { + printf("%.*sUUID32 : 0x%.8x\n", + indent, indent_spaces, uuid->value.uuid32); + } else if (uuid->type == SDP_UUID128) { + unsigned int data0; + unsigned short data1; + unsigned short data2; + unsigned short data3; + unsigned int data4; + unsigned short data5; + + memcpy(&data0, &uuid->value.uuid128.data[0], 4); + memcpy(&data1, &uuid->value.uuid128.data[4], 2); + memcpy(&data2, &uuid->value.uuid128.data[6], 2); + memcpy(&data3, &uuid->value.uuid128.data[8], 2); + memcpy(&data4, &uuid->value.uuid128.data[10], 4); + memcpy(&data5, &uuid->value.uuid128.data[14], 2); + + printf("%.*sUUID128 : 0x%.8x-%.4x-%.4x-%.4x-%.8x-%.4x\n", + indent, indent_spaces, + ntohl(data0), ntohs(data1), ntohs(data2), + ntohs(data3), ntohl(data4), ntohs(data5)); + } else + printf("%.*sEnum type of UUID not set\n", + indent, indent_spaces); + } else + printf("%.*sNull passed to print UUID\n", + indent, indent_spaces); +} + +/* + * Parse a sequence of data elements (i.e. a list) + */ +static void printf_dataseq(sdp_data_t * pData, + struct attrib_context *context, + int indent) +{ + sdp_data_t *sdpdata = NULL; + + sdpdata = pData; + if (sdpdata) { + context->member_index = 0; + do { + sdp_data_printf(sdpdata, context, indent + 2); + sdpdata = sdpdata->next; + context->member_index++; + } while (sdpdata); + } else { + printf("%.*sBroken dataseq link\n", indent, indent_spaces); + } +} + +/* + * Parse a single data element (either in the attribute or in a data + * sequence). + */ +void sdp_data_printf(sdp_data_t *sdpdata, + struct attrib_context *context, + int indent) +{ + char *member_name = NULL; + + /* Find member name. Almost black magic ;-) */ + if (context->attrib && context->attrib->members && + context->member_index < context->attrib->member_max) { + member_name = context->attrib->members[context->member_index].name; + } + + switch (sdpdata->dtd) { + case SDP_DATA_NIL: + printf("%.*sNil\n", indent, indent_spaces); + break; + case SDP_BOOL: + case SDP_UINT8: + case SDP_UINT16: + case SDP_UINT32: + case SDP_UINT64: + case SDP_UINT128: + case SDP_INT8: + case SDP_INT16: + case SDP_INT32: + case SDP_INT64: + case SDP_INT128: + if (member_name) { + printf("%.*s%s (Integer) : 0x%x\n", + indent, indent_spaces, + member_name, sdpdata->val.uint32); + } else { + printf("%.*sInteger : 0x%x\n", indent, indent_spaces, + sdpdata->val.uint32); + } + break; + + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + //printf("%.*sUUID\n", indent, indent_spaces); + sdp_uuid_printf(&sdpdata->val.uuid, context, indent); + break; + + case SDP_TEXT_STR8: + case SDP_TEXT_STR16: + case SDP_TEXT_STR32: + printf("%.*sText : \"%s\"\n", indent, indent_spaces, + sdpdata->val.str); + break; + case SDP_URL_STR8: + case SDP_URL_STR16: + case SDP_URL_STR32: + printf("%.*sURL : %s\n", indent, indent_spaces, + sdpdata->val.str); + break; + + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + printf("%.*sData Sequence\n", indent, indent_spaces); + printf_dataseq(sdpdata->val.dataseq, context, indent); + break; + + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + printf("%.*sData Sequence Alternates\n", indent, indent_spaces); + printf_dataseq(sdpdata->val.dataseq, context, indent); + break; + } +} + +/* + * Parse a single attribute. + */ +void sdp_attr_printf_func(void *value, void *userData) +{ + sdp_data_t *sdpdata = NULL; + uint16_t attrId; + struct service_context *service = (struct service_context *) userData; + struct attrib_context context; + struct attrib_def *attrDef = NULL; + int i; + + sdpdata = (sdp_data_t *)value; + attrId = sdpdata->attrId; + /* Search amongst the generic attributes */ + for (i = 0; i < attrib_max; i++) + if (attrib_names[i].num == attrId) { + attrDef = &attrib_names[i]; + break; + } + /* Search amongst the specific attributes of this service */ + if ((attrDef == NULL) && + (service->service != NULL) && + (service->service->attribs != NULL)) { + struct attrib_def *svc_attribs = service->service->attribs; + int svc_attrib_max = service->service->attrib_max; + for (i = 0; i < svc_attrib_max; i++) + if (svc_attribs[i].num == attrId) { + attrDef = &svc_attribs[i]; + break; + } + } + + if (attrDef) + printf("Attribute Identifier : 0x%x - %s\n", + attrId, attrDef->name); + else + printf("Attribute Identifier : 0x%x\n", attrId); + /* Build context */ + context.service = service->service; + context.attrib = attrDef; + context.member_index = 0; + /* Parse attribute members */ + if (sdpdata) + sdp_data_printf(sdpdata, &context, 2); + else + printf(" NULL value\n"); + /* Update service */ + service->service = context.service; +} + +/* + * Main entry point of this library. Parse a SDP record. + * We assume the record has already been read, parsed and cached + * locally. Jean II + */ +void sdp_printf_service_attr(sdp_record_t *rec) +{ + if (rec && rec->attrlist) { + struct service_context service = { NULL }; + sdp_list_foreach(rec->attrlist, sdp_attr_printf_func, &service); + } +} + +/* + * Set attributes with single values in SDP record + * Jean II + */ +int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value) +{ + sdp_list_t *attrid_list; + uint32_t range = 0x0000ffff; + sdp_record_t *rec; + + /* Get the old SDP record */ + attrid_list = sdp_list_append(NULL, &range); + rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attrid_list); + + if (!rec) { + printf("Service get request failed.\n"); + return -1; + } + + /* Check the type of attribute */ + if (!strncasecmp(value, "u0x", 3)) { + /* UUID16 */ + uint16_t value_int = 0; + uuid_t value_uuid; + value_int = strtoul(value + 3, NULL, 16); + sdp_uuid16_create(&value_uuid, value_int); + printf("Adding attrib 0x%X uuid16 0x%X to record 0x%X\n", + attrib, value_int, handle); + + sdp_attr_add_new(rec, attrib, SDP_UUID16, &value_uuid.value.uuid16); + } else if (!strncasecmp(value, "0x", 2)) { + /* Int */ + uint32_t value_int; + value_int = strtoul(value + 2, NULL, 16); + printf("Adding attrib 0x%X int 0x%X to record 0x%X\n", + attrib, value_int, handle); + + sdp_attr_add_new(rec, attrib, SDP_UINT32, &value_int); + } else { + /* String */ + printf("Adding attrib 0x%X string \"%s\" to record 0x%X\n", + attrib, value, handle); + + /* Add/Update our attribute to the record */ + sdp_attr_add_new(rec, attrib, SDP_TEXT_STR8, value); + } + + /* Update on the server */ + if (sdp_record_update(sess, rec)) { + printf("Service Record update failed (%d).\n", errno); + return -1; + } + return 0; +} + +static struct option set_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *set_help = + "Usage:\n" + "\tget record_handle attrib_id attrib_value\n"; + +/* + * Add an attribute to an existing SDP record on the local SDP server + */ +int cmd_setattr(int argc, char **argv) +{ + int opt, status; + uint32_t handle; + uint16_t attrib; + sdp_session_t *sess; + + for_each_opt(opt, set_options, NULL) { + switch(opt) { + default: + printf(set_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 3) { + printf(set_help); + return -1; + } + + /* Convert command line args */ + handle = strtoul(argv[0], NULL, 16); + attrib = strtoul(argv[1], NULL, 16); + + /* Do it */ + sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); + if (!sess) + return -1; + status = set_attrib(sess, handle, attrib, argv[2]); + sdp_close(sess); + return status; +} + +/* + * We do only simple data sequences. Sequence of sequences is a pain ;-) + * Jean II + */ +int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int argc, char **argv) +{ + sdp_list_t *attrid_list; + uint32_t range = 0x0000ffff; + sdp_record_t *rec; + sdp_data_t *pSequenceHolder = NULL; + void **dtdArray; + void **valueArray; + void **allocArray; + uint8_t uuid16 = SDP_UUID16; + uint8_t uint32 = SDP_UINT32; + uint8_t str8 = SDP_TEXT_STR8; + int i; + + /* Get the old SDP record */ + attrid_list = sdp_list_append(NULL, &range); + rec = sdp_service_attr_req(session, handle, SDP_ATTR_REQ_RANGE, attrid_list); + + if (!rec) { + printf("Service get request failed.\n"); + return -1; + } + + /* Create arrays */ + dtdArray = (void **)malloc(argc * sizeof(void *)); + valueArray = (void **)malloc(argc * sizeof(void *)); + allocArray = (void **)malloc(argc * sizeof(void *)); + + /* Loop on all args, add them in arrays */ + for (i = 0; i < argc; i++) { + /* Check the type of attribute */ + if (!strncasecmp(argv[i], "u0x", 3)) { + /* UUID16 */ + uint16_t value_int = strtoul((argv[i]) + 3, NULL, 16); + uuid_t *value_uuid = (uuid_t *)malloc(sizeof(uuid_t)); + allocArray[i] = value_uuid; + sdp_uuid16_create(value_uuid, value_int); + + printf("Adding uuid16 0x%X to record 0x%X\n", + value_int, handle); + dtdArray[i] = &uuid16; + valueArray[i] = &value_uuid->value.uuid16; + } else if (!strncasecmp(argv[i], "0x", 2)) { + /* Int */ + uint32_t *value_int = (int *)malloc(sizeof(int)); + allocArray[i] = value_int; + *value_int = strtoul((argv[i]) + 2, NULL, 16); + + printf("Adding int 0x%X to record 0x%X\n", + *value_int, handle); + dtdArray[i] = &uint32; + valueArray[i] = value_int; + } else { + /* String */ + printf("Adding string \"%s\" to record 0x%X\n", + argv[i], handle); + dtdArray[i] = &str8; + valueArray[i] = argv[i]; + } + } + + /* Add this sequence to the attrib list */ + pSequenceHolder = sdp_seq_alloc(dtdArray, valueArray, argc); + if (pSequenceHolder) { + sdp_attr_replace(rec, attrib, pSequenceHolder); + + /* Update on the server */ + if (sdp_record_update(session, rec)) { + printf("Service Record update failed (%d).\n", errno); + return -1; + } + } else { + printf("Failed to create pSequenceHolder\n"); + } + + /* Cleanup */ + for (i = 0; i < argc; i++) + free(allocArray[i]); + free(dtdArray); + free(valueArray); + + return 0; +} + +static struct option seq_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *seq_help = + "Usage:\n" + "\tget record_handle attrib_id attrib_values\n"; + +/* + * Add an attribute sequence to an existing SDP record + * on the local SDP server + */ +int cmd_setseq(int argc, char **argv) +{ + int opt, status; + uint32_t handle; + uint16_t attrib; + sdp_session_t *sess; + + for_each_opt(opt, seq_options, NULL) { + switch(opt) { + default: + printf(seq_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 3) { + printf(seq_help); + return -1; + } + + /* Convert command line args */ + handle = strtoul(argv[0], NULL, 16); + attrib = strtoul(argv[1], NULL, 16); + + argc -= 2; + argv += 2; + + /* Do it */ + sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); + if (!sess) + return -1; + status = set_attribseq(sess, handle, attrib, argc, argv); + sdp_close(sess); + return status; +} + +static void print_service_class(void *value, void *userData) +{ + char ServiceClassUUID_str[MAX_LEN_SERVICECLASS_UUID_STR]; + uuid_t *uuid = (uuid_t *)value; + + sdp_uuid2strn(uuid, UUID_str, MAX_LEN_UUID_STR); + sdp_svclass_uuid2strn(uuid, ServiceClassUUID_str, MAX_LEN_SERVICECLASS_UUID_STR); + printf(" \"%s\" (0x%s)\n", ServiceClassUUID_str, UUID_str); +} + +static void print_service_desc(void *value, void *user) +{ + char str[MAX_LEN_PROTOCOL_UUID_STR]; + sdp_data_t *p = (sdp_data_t *)value, *s; + int i = 0, proto = 0; + + for (; p; p = p->next, i++) { + switch (p->dtd) { + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + sdp_uuid2strn(&p->val.uuid, UUID_str, MAX_LEN_UUID_STR); + sdp_proto_uuid2strn(&p->val.uuid, str, sizeof(str)); + proto = sdp_uuid_to_proto(&p->val.uuid); + printf(" \"%s\" (0x%s)\n", str, UUID_str); + break; + case SDP_UINT8: + if (proto == RFCOMM_UUID) + printf(" Channel: %d\n", p->val.uint8); + else + printf(" uint8: 0x%x\n", p->val.uint8); + break; + case SDP_UINT16: + if (proto == L2CAP_UUID) { + if (i == 1) + printf(" PSM: %d\n", p->val.uint16); + else + printf(" Version: 0x%04x\n", p->val.uint16); + } else if (proto == BNEP_UUID) + if (i == 1) + printf(" Version: 0x%04x\n", p->val.uint16); + else + printf(" uint16: 0x%x\n", p->val.uint16); + else + printf(" uint16: 0x%x\n", p->val.uint16); + break; + case SDP_SEQ16: + printf(" SEQ16:"); + for (s = p->val.dataseq; s; s = s->next) + printf(" %x", s->val.uint16); + printf("\n"); + break; + case SDP_SEQ8: + printf(" SEQ8:"); + for (s = p->val.dataseq; s; s = s->next) + printf(" %x", s->val.uint8); + printf("\n"); + break; + default: + printf(" FIXME: dtd=0%x\n", p->dtd); + break; + } + } +} + +void print_lang_attr(void *value, void *user) +{ + sdp_lang_attr_t *lang = (sdp_lang_attr_t *)value; + printf(" code_ISO639: 0x%02x\n", lang->code_ISO639); + printf(" encoding: 0x%02x\n", lang->encoding); + printf(" base_offset: 0x%02x\n", lang->base_offset); +} + +void print_access_protos(value, userData) +{ + sdp_list_t *protDescSeq = (sdp_list_t *)value; + sdp_list_foreach(protDescSeq, print_service_desc, 0); +} + +void print_profile_desc(void *value, void *userData) +{ + sdp_profile_desc_t *desc = (sdp_profile_desc_t *)value; + char str[MAX_LEN_PROFILEDESCRIPTOR_UUID_STR]; + + sdp_uuid2strn(&desc->uuid, UUID_str, MAX_LEN_UUID_STR); + sdp_profile_uuid2strn(&desc->uuid, str, MAX_LEN_PROFILEDESCRIPTOR_UUID_STR); + + printf(" \"%s\" (0x%s)\n", str, UUID_str); + if (desc->version) + printf(" Version: 0x%04x\n", desc->version); +} + +/* + * Parse a SDP record in user friendly form. + */ +void print_service_attr(sdp_record_t *rec) +{ + sdp_list_t *list = 0, *proto = 0; + + sdp_record_print(rec); + + printf("Service RecHandle: 0x%x\n", rec->handle); + + if (sdp_get_service_classes(rec, &list) == 0) { + printf("Service Class ID List:\n"); + sdp_list_foreach(list, print_service_class, 0); + sdp_list_free(list, free); + } + if (sdp_get_access_protos(rec, &proto) == 0) { + printf("Protocol Descriptor List:\n"); + sdp_list_foreach(proto, print_access_protos, 0); + sdp_list_free(proto, (sdp_free_func_t)sdp_data_free); + } + if (sdp_get_lang_attr(rec, &list) == 0) { + printf("Language Base Attr List:\n"); + sdp_list_foreach(list, print_lang_attr, 0); + sdp_list_free(list, free); + } + if (sdp_get_profile_descs(rec, &list) == 0) { + printf("Profile Descriptor List:\n"); + sdp_list_foreach(list, print_profile_desc, 0); + sdp_list_free(list, free); + } +} + +/* + * Support for Service (de)registration + */ +typedef struct { + char *name; + char *provider; + char *desc; + + unsigned int class; + unsigned int profile; + unsigned int channel; +} svc_info_t; + +static int add_sp(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto; + uuid_t root_uuid, sp_uuid, l2cap, rfcomm; + sdp_profile_desc_t profile; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 1; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + sdp_list_free(root, 0); + + sdp_uuid16_create(&sp_uuid, SERIAL_PORT_SVCLASS_ID); + svclass_id = sdp_list_append(0, &sp_uuid); + sdp_set_service_classes(&record, svclass_id); + sdp_list_free(svclass_id, 0); + + sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID); + profile.version = 0x0100; + profiles = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, profiles); + sdp_list_free(profiles, 0); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Serial Port", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Serial Port service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_dun(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root, *aproto; + uuid_t rootu, dun, gn, l2cap, rfcomm; + sdp_profile_desc_t profile; + sdp_list_t *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 1; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&rootu, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &rootu); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&dun, DIALUP_NET_SVCLASS_ID); + svclass_id = sdp_list_append(0, &dun); + sdp_uuid16_create(&gn, GENERIC_NETWORKING_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &gn); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, DIALUP_NET_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Dial-Up Networking service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_lan(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 2; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, LAN_ACCESS_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, LAN_ACCESS_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "LAN Access over PPP", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("LAN Access service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + + +static int add_headset(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 5; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, HEADSET_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Headset", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Headset service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_handsfree(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 3; + uint16_t u16 = 0x31; + sdp_data_t *channel, *features; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, HANDSFREE_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID); + profile.version = 0x0101; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + features = sdp_data_alloc(SDP_UINT16, &u16); + sdp_attr_add(&record, SDP_SUPPORTED_FEATURES, features); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Handsfree service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + + +static int add_fax(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 3; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID); + svclass_id = sdp_list_append(0, &fax_uuid); + sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &tel_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Fax", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Fax service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_opush(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[3]; + sdp_record_t record; + uint8_t chan = si->channel? si->channel: 4; + sdp_data_t *channel; + uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + //uint8_t formats[] = { 0xff }; + void *dtds[sizeof(formats)], *values[sizeof(formats)]; + int i; + uint8_t dtd = SDP_UINT8; + sdp_data_t *sflist; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID); + svclass_id = sdp_list_append(0, &opush_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &chan); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + sdp_uuid16_create(&obex_uuid, OBEX_UUID); + proto[2] = sdp_list_append(0, &obex_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + for (i = 0; i < sizeof(formats); i++) { + dtds[i] = &dtd; + values[i] = &formats[i]; + } + sflist = sdp_seq_alloc(dtds, values, sizeof(formats)); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FORMATS_LIST, sflist); + + sdp_set_info_attr(&record, "OBEX Object Push", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("OBEX Object Push service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(proto[2], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_file_trans(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, ftrn_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[3]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 4; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&ftrn_uuid, OBEX_FILETRANS_SVCLASS_ID); + svclass_id = sdp_list_append(0, &ftrn_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, OBEX_FILETRANS_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + sdp_uuid16_create(&obex_uuid, OBEX_UUID); + proto[2] = sdp_list_append(0, &obex_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("OBEX File Transfer service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(proto[2], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_nap(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint16_t lp = 0x000f, ver = 0x0100; + sdp_data_t *psm, *version; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&ftrn_uuid, NAP_SVCLASS_ID); + svclass_id = sdp_list_append(0, &ftrn_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&bnep_uuid, BNEP_UUID); + proto[1] = sdp_list_append(0, &bnep_uuid); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + + { + uint16_t ptype[4] = { 0x0010, 0x0020, 0x0030, 0x0040 }; + sdp_data_t *head, *pseq; + int p; + + for (p = 0, head = NULL; p < 4; p++) { + sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]); + head = sdp_seq_append(head, data); + } + pseq = sdp_data_alloc(SDP_SEQ16, head); + proto[1] = sdp_list_append(proto[1], pseq); + } + + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Network Access Point Service", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("NAP service registered\n"); +end: + sdp_data_free(version); + sdp_data_free(psm); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_gn(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint16_t lp = 0x000f, ver = 0x0100; + sdp_data_t *psm, *version; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&ftrn_uuid, GN_SVCLASS_ID); + svclass_id = sdp_list_append(0, &ftrn_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&bnep_uuid, BNEP_UUID); + proto[1] = sdp_list_append(0, &bnep_uuid); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Group Network Service", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("GN service registered\n"); +end: + sdp_data_free(version); + sdp_data_free(psm); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_hid(sdp_session_t *sess, svc_info_t *si) +{ + return -1; +} + +static int add_cip(sdp_session_t *sess, svc_info_t *si) +{ + return -1; +} + +static int add_ctp(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, tcsbin, ctp; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t netid = 0x02; // 0x01-0x07 cf. p120 profile document + sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&ctp, CORDLESS_TELEPHONY_SVCLASS_ID); + svclass_id = sdp_list_append(0, &ctp); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, CORDLESS_TELEPHONY_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&tcsbin, TCS_BIN_UUID); + proto[1] = sdp_list_append(0, &tcsbin); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_attr_add(&record, SDP_EXTERNAL_NETWORK, network); + + sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("CTP service registered\n"); +end: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + sdp_data_free(network); + return ret; +} + +struct { + char *name; + uint16_t class; + int (*add)(sdp_session_t *sess, svc_info_t *si); +} service[] = { + { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, + { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, + { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, + { "FAX", FAX_SVCLASS_ID, add_fax }, + { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, + { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, + + { "HS", HEADSET_SVCLASS_ID, add_headset }, + { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, + + { "NAP", NAP_SVCLASS_ID, add_nap }, + { "GN", GN_SVCLASS_ID, add_gn }, + + { "HID", HID_SVCLASS_ID, add_hid }, + { "CIP", CIP_SVCLASS_ID, add_cip }, + { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, + + { 0 } +}; + +/* Add local service */ +int add_service(bdaddr_t *bdaddr, svc_info_t *si) +{ + int i; + sdp_session_t *sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); + + if (!sess) + return -1; + if (si->name) + for (i=0; service[i].name; i++) + if (!strcasecmp(service[i].name, si->name)) { + int ret = service[i].add(sess, si); + free(si->name); + sdp_close(sess); + return ret; + } + printf("Unknown service name: %s\n", si->name); + free(si->name); + sdp_close(sess); + return -1; +} + +static struct option add_options[] = { + {"help", 0,0, 'h'}, + {"channel", 1,0, 'c'}, + {0, 0, 0, 0} +}; + +static char *add_help = + "Usage:\n" + "\tadd [--channel=CHAN] service\n"; + +int cmd_add(int argc, char **argv) +{ + svc_info_t si; + int opt; + + memset(&si, 0, sizeof(si)); + for_each_opt(opt, add_options, 0) { + switch(opt) { + case 'c': + si.channel = atoi(optarg); + break; + default: + printf(add_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(add_help); + return -1; + } + + si.name = strdup(argv[0]); + return add_service(0, &si); +} + +/* Delete local service */ +int del_service(bdaddr_t *bdaddr, void *arg) +{ + uint32_t handle, range = 0x0000ffff; + sdp_list_t *attr; + sdp_session_t *sess; + sdp_record_t *rec; + + if (!arg) { + printf("Record handle was not specified.\n"); + return -1; + } + sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); + if (!sess) { + printf("No local SDP server!\n"); + return -1; + } + handle = strtoul((char *)arg, 0, 16); + attr = sdp_list_append(0, &range); + rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr); + sdp_list_free(attr, 0); + if (!rec) { + printf("Service Record not found.\n"); + sdp_close(sess); + return -1; + } + if (sdp_record_unregister(sess, rec)) { + printf("Failed to unregister service record: %s\n", strerror(errno)); + sdp_close(sess); + return -1; + } + printf("Service Record deleted.\n"); + sdp_close(sess); + return 0; +} + +static struct option del_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *del_help = + "Usage:\n" + "\tdel record_handle\n"; + +int cmd_del(int argc, char **argv) +{ + int opt; + + for_each_opt(opt, del_options, 0) { + switch(opt) { + default: + printf(del_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(del_help); + return -1; + } + return del_service(0, argv[0]); +} + +/* + * Perform an inquiry and search/browse all peer found. + */ +static void inquiry(handler_t handler, void *arg) +{ + inquiry_info ii[20]; + uint8_t count = 0; + int i; + + printf("Inquiring ...\n"); + if (sdp_general_inquiry(ii, 20, 8, &count) < 0) { + printf("Inquiry failed\n"); + return; + } + for (i=0; isvc) + printf("Searching for %s on %s ...\n", context->svc, str); + else + printf("Browsing %s ...\n", str); + + attrid = sdp_list_append(0, &range); + search = sdp_list_append(0, &context->group); + if (sdp_service_search_attr_req(sess, search, SDP_ATTR_REQ_RANGE, attrid, &seq)) { + printf("Service Search failed: %s\n", strerror(errno)); + sdp_close(sess); + return -1; + } + sdp_list_free(attrid, 0); + sdp_list_free(search, 0); + + for (; seq; seq = next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; + struct search_context sub_context; + + if (context->tree) { + /* Display full tree */ + sdp_printf_service_attr(rec); + } else { + /* Display user friendly form */ + print_service_attr(rec); + } + printf("\n"); + + if (sdp_get_group_id(rec, &sub_context.group) != -1) { + /* Set the subcontext for browsing the sub tree */ + memcpy(&sub_context, context, sizeof(struct search_context)); + /* Browse the next level down if not done */ + if (sub_context.group.value.uuid16 != context->group.value.uuid16) + do_search(bdaddr, &sub_context); + } + next = seq->next; + free(seq); + sdp_record_free(rec); + } + sdp_close(sess); + return 0; +} + +static struct option browse_options[] = { + {"help", 0,0, 'h'}, + {"tree", 0,0, 't'}, + {0, 0, 0, 0} +}; + +static char *browse_help = + "Usage:\n" + "\tbrowse [--tree] [bdaddr]\n"; + +/* + * Browse the full SDP database (i.e. list all services starting from the + * root/top-level). + */ +int cmd_browse(int argc, char **argv) +{ + struct search_context context; + int opt; + + /* Initialise context */ + memset(&context, '\0', sizeof(struct search_context)); + /* We want to browse the top-level/root */ + sdp_uuid16_create(&(context.group), PUBLIC_BROWSE_GROUP); + + for_each_opt(opt, browse_options, 0) { + switch(opt) { + case 't': + context.tree = 1; + break; + default: + printf(browse_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc >= 1) { + bdaddr_t bdaddr; + estr2ba(argv[0], &bdaddr); + return do_search(&bdaddr, &context); + } + return do_search(0, &context); +} + +static struct option search_options[] = { + {"help", 0,0, 'h'}, + {"bdaddr", 1,0, 'b'}, + {"tree", 0,0, 't'}, + {0, 0, 0, 0} +}; + +static char *search_help = + "Usage:\n" + "\tsearch [--bdaddr bdaddr] [--tree] SERVICE\n" + "SERVICE is a name (string) or UUID (0x1002)\n"; + +/* + * Search for a specific SDP service + * + * Note : we should support multiple services on the command line : + * sdptool search 0x0100 0x000f 0x1002 + * (this would search a service supporting both L2CAP and BNEP directly in + * the top level browse group) + */ +int cmd_search(int argc, char **argv) +{ + struct search_context context; + uint16_t class = 0; + bdaddr_t bdaddr; + int has_addr = 0; + int i; + int opt; + + /* Initialise context */ + memset(&context, '\0', sizeof(struct search_context)); + + for_each_opt(opt, search_options, 0) { + switch(opt) { + case 'b': + estr2ba(optarg, &bdaddr); + has_addr = 1; + break; + case 't': + context.tree = 1; + break; + default: + printf(search_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(search_help); + return -1; + } + /* Note : we need to find a way to support search combining + * multiple services - Jean II */ + context.svc = strdup(argv[0]); + if (!strncasecmp(context.svc, "0x", 2)) { + int num; + /* This is a UUID16, just convert to int */ + sscanf(context.svc + 2, "%X", &num); + class = num; + printf("Class 0x%X\n", class); + } else { + /* Convert class name to an UUID */ + + for (i=0; service[i].name; i++) + if (strcasecmp(context.svc, service[i].name) == 0) { + class = service[i].class; + break; + } + if (!class) { + printf("Unknown service %s\n", context.svc); + return -1; + } + } + + sdp_uuid16_create(&context.group, class); + + if (has_addr) + return do_search(&bdaddr, &context); + return do_search(0, &context); +} + +/* + * Show how to get a specific SDP record by its handle. + * Not really useful to the user, just show how it can be done... + * Jean II + */ +int get_service(bdaddr_t *bdaddr, struct search_context *context) +{ + sdp_list_t *attrid; + uint32_t range = 0x0000ffff; + sdp_record_t *rec; + sdp_session_t *session = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY); + + if (!session) { + char str[20]; + ba2str(bdaddr, str); + printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno)); + return -1; + } + attrid = sdp_list_append(0, &range); + rec = sdp_service_attr_req(session, context->handle, SDP_ATTR_REQ_RANGE, attrid); + sdp_list_free(attrid, 0); + sdp_close(session); + if (!rec) { + printf("Service get request failed.\n"); + return -1; + } + if (context->tree) { + /* Display full tree */ + sdp_printf_service_attr(rec); + } else { + /* Display user friendly form */ + print_service_attr(rec); + } + printf("\n"); + sdp_record_free(rec); + return 0; +} + +static struct option get_options[] = { + {"help", 0,0, 'h'}, + {"bdaddr", 1,0, 'b'}, + {"tree", 0,0, 't'}, + {0, 0, 0, 0} +}; + +static char *get_help = + "Usage:\n" + "\tget [--tree] [--bdaddr bdaddr] record_handle\n"; + +/* + * Get a specific SDP record on the local SDP server + */ +int cmd_get(int argc, char **argv) +{ + struct search_context context; + bdaddr_t bdaddr; + int has_addr = 0; + int opt; + + /* Initialise context */ + memset(&context, '\0', sizeof(struct search_context)); + + for_each_opt(opt, get_options, 0) { + switch(opt) { + case 'b': + estr2ba(optarg, &bdaddr); + has_addr = 1; + break; + case 't': + context.tree = 1; + break; + default: + printf(get_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(get_help); + return -1; + } + /* Convert command line parameters */ + context.handle = strtoul(argv[0], 0, 16); + + return get_service(has_addr? &bdaddr: BDADDR_LOCAL, &context); +} + +struct { + char *cmd; + int (*func)(int argc, char **argv); + char *doc; +} command[] = { + { "search", cmd_search, "Search for a service" }, + { "browse", cmd_browse, "Browse all available services" }, + { "add", cmd_add, "Add local service" }, + { "del", cmd_del, "Delete local service" }, + { "get", cmd_get, "Get local service" }, + { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, + { "setseq", cmd_setseq, "Set/Add attribute sequence to a SDP record" }, + { 0, 0, 0} +}; + +static void usage(void) +{ + int i; + + printf("sdptool - SDP Tool v%s\n", VERSION); + printf("Usage:\n" + "\tsdptool [options] [command parameters]\n"); + printf("Options:\n" + "\t--help\t\tDisplay help\n" + "\t--source\tSpecify source interface\n"); + + printf("Commands:\n"); + for (i=0; command[i].cmd; i++) + printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc); + + printf("\nServices:\n\t"); + for (i=0; service[i].name; i++) + printf("%s ", service[i].name); + printf("\n"); +} + +static struct option main_options[] = { + {"help", 0, 0, 'h'}, + {"source", 1, 0, 'S'}, + {0, 0, 0, 0} +}; + +int main(int argc, char **argv) +{ + int opt, i; + + bacpy(&interface, BDADDR_ANY); + while ((opt=getopt_long(argc, argv, "+hS:", main_options, 0)) != -1) { + switch(opt) { + case 'S': + str2ba(optarg, &interface); + break; + case 'h': + default: + usage(); + return -1; + } + } + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + return -1; + } + for (i=0; command[i].cmd; i++) + if (strncmp(command[i].cmd, argv[0], 4) == 0) + return command[i].func(argc, argv); + return -1; +} -- cgit From df713b4db4fb851b197d982d9e91cd85df50839d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 21:32:22 +0000 Subject: Add the ciptool utility --- tools/Makefile.am | 4 +- tools/ciptool.1 | 68 ++++++++ tools/ciptool.c | 479 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 549 insertions(+), 2 deletions(-) create mode 100644 tools/ciptool.1 create mode 100644 tools/ciptool.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 4ddeb5c9..44b30990 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -6,11 +6,11 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = hciattach hciconfig -bin_PROGRAMS = hcitool l2ping sdptool +bin_PROGRAMS = hcitool l2ping sdptool ciptool hciconfig_SOURCES = hciconfig.c csr.h csr.c -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 noinst_PROGRAMS = ppporc diff --git a/tools/ciptool.1 b/tools/ciptool.1 new file mode 100644 index 00000000..982f414b --- /dev/null +++ b/tools/ciptool.1 @@ -0,0 +1,68 @@ +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH CIPTOOL 1 "JUNE 6, 2003" "" "" + +.SH NAME +ciptool \- Bluetooth Common ISDN Access Profile (CIP) +.SH SYNOPSIS +.BR "ciptool +[ +.I options +] < +.I command +> +.SH DESCRIPTION +.B ciptool +is used to set up, maintain, and inspect the CIP configuration +of the Bluetooth subsystem in the Linux kernel. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands. +.TP +.BI -i " | " +The command is applied to device +.I +hciX +, which must be the name or the address of an installed Bluetooth +device. If not specified, the command will be use the first +available Bluetooth device. +.SH COMMANDS +.TP +.BI show +Display information about the connected devices. +.TP +.BI search +Search for Bluetooth devices and connect to first one that +offers CIP support. +.TP +.BI connect " [psm]" +Connect the local device to the remote Bluetooth device on the +specified PSM number. If no PSM is specified, it will use the +SDP to retrieve it from the remote device. +.TP +.BI release " [bdaddr]" +Release a connection to the specific device. If no address is +given and only one device is connected this will be released. +.TP +.BI loopback " [psm]" +Create a connection to the remote device for Bluetooth testing. +This command will not provide a CAPI controller, because it is +only for testing the CAPI Message Transport Protocol. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/ciptool.c b/tools/ciptool.c new file mode 100644 index 00000000..31984985 --- /dev/null +++ b/tools/ciptool.c @@ -0,0 +1,479 @@ +/* + * + * Bluetooth Common ISDN Access Profile (CIP) + * + * Copyright (C) 2002-2003 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ + return; +} + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static char *cmtp_state[] = { + "unknown", + "connected", + "open", + "bound", + "listening", + "connecting", + "connecting", + "config", + "disconnecting", + "closed" +}; + +static char *cmtp_flagstostr(uint32_t flags) +{ + static char str[100] = ""; + + strcat(str, "["); + + if (flags & (1 << CMTP_LOOPBACK)) + strcat(str, "loopback"); + + strcat(str, "]"); + + return str; +} + +static int get_psm(bdaddr_t *src, bdaddr_t *dst, unsigned short *psm) +{ + sdp_session_t *s; + sdp_list_t *srch, *attrs, *rsp; + uuid_t svclass; + uint16_t attr; + int err; + + if (!(s = sdp_connect(src, dst, 0))) + return -1; + + sdp_uuid16_create(&svclass, CIP_SVCLASS_ID); + srch = sdp_list_append(NULL, &svclass); + + attr = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append(NULL, &attr); + + err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); + + sdp_close(s); + + if (err) + return 0; + + for (; rsp; rsp = rsp->next) { + sdp_record_t *rec = (sdp_record_t *) rsp->data; + sdp_list_t *protos; + + if (!sdp_get_access_protos(rec, &protos)) { + unsigned short p = sdp_get_proto_port(protos, L2CAP_UUID); + if (p > 0) { + *psm = p; + return 1; + } + } + } + + return 0; +} + +static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigned short psm, uint32_t flags) +{ + struct cmtp_connadd_req req; + struct hci_dev_info di; + struct sockaddr_l2 addr; + struct l2cap_options opts; + int sk, size; + + hci_devinfo(dev_id, &di); + if (!(di.link_policy & HCI_LP_RSWITCH)) { + printf("Local device is not accepting role switch\n"); + } + + if ((sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { + perror("Can't create L2CAP socket"); + exit(1); + } + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, src); + addr.l2_psm = 0; + + if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror("Can't bind L2CAP socket"); + close(sk); + exit(1); + } + + size = sizeof(opts); + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) { + perror("Can't get L2CAP options"); + close(sk); + exit(1); + } + + opts.imtu = CMTP_DEFAULT_MTU; + opts.omtu = CMTP_DEFAULT_MTU; + opts.flush_to = 0xffff; + + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { + perror("Can't set L2CAP options"); + close(sk); + exit(1); + } + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, dst); + addr.l2_psm = psm; + + if (connect(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror("Can't connect L2CAP socket"); + close(sk); + exit(1); + } + + req.sock = sk; + req.flags = flags; + + if (ioctl(ctl, CMTPCONNADD, &req) < 0) { + perror("Can't create connection"); + exit(1); + } + + return sk; +} + +static void cmd_show(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct cmtp_connlist_req req; + struct cmtp_conninfo ci[16]; + char addr[18]; + int i; + + req.cnum = 16; + req.ci = ci; + + if (ioctl(ctl, CMTPGETCONNLIST, &req) < 0) { + perror("Can't get connection list"); + exit(1); + } + + for (i = 0; i < req.cnum; i++) { + ba2str(&ci[i].bdaddr, addr); + printf("%d %s %s %s\n", ci[i].num, addr, + cmtp_state[ci[i].state], + ci[i].flags ? cmtp_flagstostr(ci[i].flags) : ""); + } +} + +static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + inquiry_info *info = NULL; + bdaddr_t src, dst; + unsigned short psm; + int i, dev_id, num_rsp, length, flags; + char addr[18]; + uint8_t class[3]; + + ba2str(bdaddr, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + hci_devba(dev_id, &src); + } else + bacpy(&src, bdaddr); + + length = 8; /* ~10 seconds */ + num_rsp = 0; + flags = 0; + + printf("Searching ...\n"); + + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + + for (i = 0; i < num_rsp; i++) { + memcpy(class, (info+i)->dev_class, 3); + if ((class[1] == 2) && ((class[0] / 4) == 5)) { + bacpy(&dst, &(info+i)->bdaddr); + ba2str(&dst, addr); + + printf("\tChecking service for %s\n", addr); + if (!get_psm(&src, &dst, &psm)) + continue; + + free(info); + + printf("\tConnecting to device %s\n", addr); + do_connect(ctl, dev_id, &src, &dst, psm, 0); + return; + } + } + + free(info); + fprintf(stderr, "\tNo devices in range or visible\n"); + exit(1); +} + +static void cmd_create(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + bdaddr_t src, dst; + unsigned short psm; + int dev_id; + char addr[18]; + + if (argc < 2) + return; + + str2ba(argv[1], &dst); + + ba2str(bdaddr, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) { + dev_id = hci_get_route(&dst); + hci_devba(dev_id, &src); + } else + bacpy(&src, bdaddr); + + if (argc < 3) { + if (!get_psm(&src, &dst, &psm)) + psm = htobs(4099); + } else + psm = htobs(atoi(argv[2])); + + do_connect(ctl, dev_id, &src, &dst, psm, 0); +} + +static void cmd_release(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct cmtp_conndel_req req; + struct cmtp_connlist_req cl; + struct cmtp_conninfo ci[16]; + + if (argc < 2) { + cl.cnum = 16; + cl.ci = ci; + + if (ioctl(ctl, CMTPGETCONNLIST, &cl) < 0) { + perror("Can't get connection list"); + exit(1); + } + + if (cl.cnum == 0) + return; + + if (cl.cnum != 1) { + fprintf(stderr, "You have to specifiy the device address.\n"); + exit(1); + } + + bacpy(&req.bdaddr, &ci[0].bdaddr); + } else + str2ba(argv[1], &req.bdaddr); + + if (ioctl(ctl, CMTPCONNDEL, &req) < 0) { + perror("Can't release connection"); + exit(1); + } +} + +static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct cmtp_conndel_req req; + struct sigaction sa; + struct pollfd p; + bdaddr_t src, dst; + unsigned short psm; + int dev_id, sk; + char addr[18]; + + if (argc < 2) + return; + + str2ba(argv[1], &dst); + + ba2str(bdaddr, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) { + dev_id = hci_get_route(&dst); + hci_devba(dev_id, &src); + } else + bacpy(&src, bdaddr); + + ba2str(&dst, addr); + printf("Connecting to %s in loopback mode\n", addr); + + if (argc < 3) { + if (!get_psm(&src, &dst, &psm)) + psm = htobs(4099); + } else + psm = htobs(atoi(argv[2])); + + sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK)); + + printf("Press CTRL-C for hangup\n"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + p.fd = sk; + p.events = POLLERR | POLLHUP; + + while (!__io_canceled) { + p.revents = 0; + if (poll(&p, 1, 100)) + break; + } + + bacpy(&req.bdaddr, &dst); + ioctl(ctl, CMTPCONNDEL, &req); +} + + +static struct { + char *cmd; + char *alt; + void (*func)(int ctl, bdaddr_t *bdaddr, int argc, char **argv); + char *opt; + char *doc; +} command[] = { + { "show", "list", cmd_show, 0, "Show remote connections" }, + { "search", "scan", cmd_search, 0, "Search for a remote device" }, + { "connect", "create", cmd_create, "", "Connect a remote device" }, + { "release", "disconnect", cmd_release, "[bdaddr]", "Disconnect the remote device" }, + { "loopback", "test", cmd_loopback, "", "Loopback test of a device" }, + { NULL, NULL, NULL, 0, 0 } +}; + +static void usage(void) +{ + int i; + + printf("ciptool - Bluetooth Common ISDN Access Profile (CIP)\n\n"); + + printf("Usage:\n" + "\tciptool [options] [command]\n" + "\n"); + + printf("Options:\n" + "\t-i [hciX|bdaddr] Local HCI device or BD Address\n" + "\t-h, --help Display help\n" + "\n"); + + printf("Commands:\n"); + for (i = 0; command[i].cmd; i++) + printf("\t%-8s %-10s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); + printf("\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + bdaddr_t bdaddr; + int i, opt, ctl; + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch(opt) { + case 'i': + if (!strncmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); + break; + case 'h': + usage(); + exit(0); + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + return 0; + } + + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_CMTP)) < 0 ) { + perror("Can't open CMTP control socket"); + exit(1); + } + + for (i = 0; command[i].cmd; i++) { + if (strncmp(command[i].cmd, argv[0], 4) && strncmp(command[i].alt, argv[0], 4)) + continue; + command[i].func(ctl, &bdaddr, argc, argv); + close(ctl); + exit(0); + } + + usage(); + + close(ctl); + + return 0; +} -- cgit From a16293f34e175408334275267776142408032d45 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 14:28:28 +0000 Subject: Display string as hex bytes if it is longer than strlen() --- tools/sdptool.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 5340ab1b..abb8b439 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -396,8 +396,15 @@ void sdp_data_printf(sdp_data_t *sdpdata, case SDP_TEXT_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: - printf("%.*sText : \"%s\"\n", indent, indent_spaces, - sdpdata->val.str); + if (sdpdata->unitSize > strlen(sdpdata->val.str)) { + int i; + printf("%.*sData :", indent, indent_spaces); + for (i = 0; i < sdpdata->unitSize; i++) + printf(" %02x", (unsigned char) sdpdata->val.str[i]); + printf("\n"); + } else + printf("%.*sText : \"%s\"\n", indent, indent_spaces, + sdpdata->val.str); break; case SDP_URL_STR8: case SDP_URL_STR16: -- cgit From 32fc232a8bfd1f5541a2667f02fa476d95c95dd3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 21:10:23 +0000 Subject: Update the manpage --- tools/hcitool.1 | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index bb52e1ba..f23cf7f5 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -158,6 +158,10 @@ is 0. .BI auth " " Request authentication for the device with Bluetooth address .IR bdaddr . +.TP +.BI enc " [encrypt enable]" +Enable or disable the encryption for the device with Bluetooth address +.IR bdaddr . .SH AUTHORS Written by Maxim Krasnyansky .PP -- cgit From b4e62d0942cc975be9f427d444231d5f104c87d0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 21:19:18 +0000 Subject: Change default prefix to /usr --- tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 44b30990..1ff3c9bc 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -mandir = $(prefix)/usr/share/man +mandir = $(prefix)/share/man sbin_PROGRAMS = hciattach hciconfig -- cgit From 719873a6b8d26c78b0a9a2380647e83c8e4bc05c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Apr 2004 00:08:19 +0000 Subject: Modifying $mandir is no longer needed --- tools/Makefile.am | 2 -- 1 file changed, 2 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 1ff3c9bc..ca7369a2 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,8 +2,6 @@ # $Id$ # -mandir = $(prefix)/share/man - sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping sdptool ciptool -- cgit From 1f72ace38b1c7575e4ace602975a3e6915716952 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Apr 2004 15:32:01 +0000 Subject: Fix PSM value for big endian machines --- tools/ciptool.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index 31984985..d9aa0085 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -167,7 +167,7 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); - addr.l2_psm = psm; + addr.l2_psm = htobs(psm); if (connect(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Can't connect L2CAP socket"); @@ -279,9 +279,9 @@ static void cmd_create(int ctl, bdaddr_t *bdaddr, int argc, char **argv) if (argc < 3) { if (!get_psm(&src, &dst, &psm)) - psm = htobs(4099); + psm = 4099; } else - psm = htobs(atoi(argv[2])); + psm = atoi(argv[2]); do_connect(ctl, dev_id, &src, &dst, psm, 0); } @@ -347,9 +347,9 @@ static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) if (argc < 3) { if (!get_psm(&src, &dst, &psm)) - psm = htobs(4099); + psm = 4099; } else - psm = htobs(atoi(argv[2])); + psm = atoi(argv[2]); sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK)); -- cgit From 1d3715db11f573060cb02a2b7b7c44f06607d337 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 06:04:35 +0000 Subject: Update BlueZ library configuration --- tools/Makefile.am | 4 ++++ tools/ciptool.c | 4 ++++ tools/hciattach.c | 4 ++++ tools/hciconfig.c | 4 ++++ tools/hcitool.c | 4 ++++ tools/sdptool.c | 6 +++++- 6 files changed, 25 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index ca7369a2..354f841c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -8,6 +8,10 @@ bin_PROGRAMS = hcitool l2ping sdptool ciptool hciconfig_SOURCES = hciconfig.c csr.h csr.c +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 noinst_PROGRAMS = ppporc diff --git a/tools/ciptool.c b/tools/ciptool.c index d9aa0085..bec3fc2b 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -21,6 +21,10 @@ * */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/tools/hciattach.c b/tools/hciattach.c index 799e338d..926e3fab 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -24,6 +24,10 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 39804e45..6ab7f190 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -25,6 +25,10 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/tools/hcitool.c b/tools/hcitool.c index 8fd7b83d..667212fe 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -25,6 +25,10 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/tools/sdptool.c b/tools/sdptool.c index abb8b439..87646cab 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -28,14 +28,18 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include #include +#include #include #include -#include #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1) -- cgit From 44d98edef4ab08644f87ebfb67ab6d5fb41ffa14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Apr 2004 13:12:13 +0000 Subject: Fix more endian bugs for the ACL handle --- tools/hcitool.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 667212fe..37450098 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -447,7 +447,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } cc = 1; } else - handle = cr->conn_info->handle; + handle = htobs(cr->conn_info->handle); printf("\tBD Address: %s\n", argv[0]); @@ -721,7 +721,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 100) < 0) perror("Disconnect failed"); close(dd); @@ -827,6 +827,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) struct hci_request rq; read_rssi_rp rp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, rssi_options, NULL) { @@ -871,10 +872,12 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = READ_RSSI_RP_SIZE; @@ -911,6 +914,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) struct hci_request rq; get_link_quality_rp rp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, lq_options, NULL) { @@ -955,10 +959,12 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_GET_LINK_QUALITY; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = GET_LINK_QUALITY_RP_SIZE; @@ -1041,7 +1047,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; @@ -1131,7 +1137,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); @@ -1170,6 +1176,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) read_link_supervision_timeout_rp rp; write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, lst_options, NULL) { @@ -1214,11 +1221,13 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + if (argc == 1) { memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; @@ -1239,7 +1248,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) else printf("Link supervision timeout never expires\n"); } else { - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.link_sup_to = strtol(argv[1], NULL, 10); memset(&rq, 0, sizeof(rq)); @@ -1320,7 +1329,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; @@ -1402,7 +1411,7 @@ static void cmd_enc(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; memset(&rq, 0, sizeof(rq)); -- cgit From 8e0ea134300e2c9fab5ab18d0610f4bec1e79bef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 11:16:58 +0000 Subject: Add hid2hci utility --- tools/Makefile.am | 20 ++- tools/hid2hci.8 | 42 ++++++ tools/hid2hci.c | 419 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 476 insertions(+), 5 deletions(-) create mode 100644 tools/hid2hci.8 create mode 100644 tools/hid2hci.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 354f841c..c45f5635 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,18 +2,28 @@ # $Id$ # -sbin_PROGRAMS = hciattach hciconfig +sbin_PROGRAMS = hciattach hciconfig hid2hci bin_PROGRAMS = hcitool l2ping sdptool ciptool +noinst_PROGRAMS = ppporc + hciconfig_SOURCES = hciconfig.c csr.h csr.c -LDFLAGS = @BLUEZ_LIBS@ +hciconfig_LDFLAGS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +hcitool_LDFLAGS = @BLUEZ_LIBS@ + +l2ping_LDFLAGS = @BLUEZ_LIBS@ + +sdptool_LDFLAGS = @BLUEZ_LIBS@ -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 +ciptool_LDFLAGS = @BLUEZ_LIBS@ + +ppporc_LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ -noinst_PROGRAMS = ppporc +man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 EXTRA_DIST = $(man_MANS) diff --git a/tools/hid2hci.8 b/tools/hid2hci.8 new file mode 100644 index 00000000..8f7ea4fe --- /dev/null +++ b/tools/hid2hci.8 @@ -0,0 +1,42 @@ +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH HID2HCI 8 "JUNE 6, 2003" "" "" + +.SH NAME +hid2hci \- Bluetooth HID to HCI mode switching utility +.SH SYNOPSIS +.BR "hid2hci +[ +.I options +] +.SH DESCRIPTION +.B hid2hci +is used to set up switch HID proxy Bluetooth dongle into the HCI +mode and back. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible options. +.TP +.BI -0 +Switches the device into HCI mode. +.TP +.BI -1 +Switches the device into HID mode. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/hid2hci.c b/tools/hid2hci.c new file mode 100644 index 00000000..95a7c7d6 --- /dev/null +++ b/tools/hid2hci.c @@ -0,0 +1,419 @@ +/* + * + * Bluetooth HID to HCI mode switching utility + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static char usbpath[PATH_MAX + 1] = "/proc/bus/usb"; + +struct usb_device_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__ ((packed)); + +struct usb_ctrltransfer { + uint8_t bRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + + uint32_t timeout; /* in milliseconds */ + void *data; /* pointer to data */ +}; + +#define IOCTL_USB_CONTROL _IOWR('U', 0, struct usb_ctrltransfer) + +#define USB_RECIP_DEVICE 0x00 +#define USB_TYPE_VENDOR 0x40 +#define USB_DIR_OUT 0x00 + + +static char devpath[PATH_MAX + 1] = "/dev"; + +struct hiddev_devinfo { + unsigned int bustype; + unsigned int busnum; + unsigned int devnum; + unsigned int ifnum; + short vendor; + short product; + short version; + unsigned num_applications; +}; + +struct hiddev_report_info { + unsigned report_type; + unsigned report_id; + unsigned num_fields; +}; + +typedef __signed__ int __s32; + +struct hiddev_usage_ref { + unsigned report_type; + unsigned report_id; + unsigned field_index; + unsigned usage_index; + unsigned usage_code; + __s32 value; +}; + +#define HIDIOCGDEVINFO _IOR('H', 0x03, struct hiddev_devinfo) +#define HIDIOCINITREPORT _IO('H', 0x05) +#define HIDIOCSREPORT _IOW('H', 0x08, struct hiddev_report_info) +#define HIDIOCSUSAGE _IOW('H', 0x0C, struct hiddev_usage_ref) + +#define HID_REPORT_TYPE_OUTPUT 2 + + +#define HCI 0 +#define HID 1 + +struct device_info; + +struct device_id { + int mode; + uint16_t vendor; + uint16_t product; + int (*func)(struct device_info *dev); +}; + +struct device_info { + uint16_t busnum; + uint16_t devnum; + struct device_id *id; +}; + + +static int switch_hidproxy(struct device_info *dev) +{ + struct usb_ctrltransfer ctrl; + char devname[PATH_MAX + 1]; + int fd, err; + + snprintf(devname, PATH_MAX, "%s/%03d/%03d", + usbpath, dev->busnum, dev->devnum); + + fd = open(devname, O_RDWR); + if (fd < 0) + return fd; + + ctrl.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; + ctrl.bRequest = 0; + ctrl.wValue = dev->id->mode; + ctrl.wIndex = 0; + ctrl.wLength = 0; + + ctrl.data = NULL; + ctrl.timeout = 10000; + + err = ioctl(fd, IOCTL_USB_CONTROL, &ctrl); + + if (err == 0) { + err = -1; + errno = EALREADY; + } else { + if (errno == ETIMEDOUT) + err = 0; + } + + close(fd); + + return err; +} + +static int send_report(int fd, const unsigned char *buf, size_t size) +{ + struct hiddev_report_info rinfo; + struct hiddev_usage_ref uref; + int i, err; + + for (i = 0; i < size; i++) { + memset(&uref, 0, sizeof(uref)); + uref.report_type = HID_REPORT_TYPE_OUTPUT; + uref.report_id = 0x10; + uref.field_index = 0; + uref.usage_index = i; + uref.usage_code = 0xff000001; + uref.value = buf[i]; + err = ioctl(fd, HIDIOCSUSAGE, &uref); + if (err < 0) + return err; + } + + memset(&rinfo, 0, sizeof(rinfo)); + rinfo.report_type = HID_REPORT_TYPE_OUTPUT; + rinfo.report_id = 0x10; + rinfo.num_fields = 1; + err = ioctl(fd, HIDIOCSREPORT, &rinfo); + + return err; +} + +static int switch_logitech(struct device_info *dev) +{ + char devname[PATH_MAX + 1]; + int i, fd, err = -1; + + for (i = 0; i < 16; i++) { + struct hiddev_devinfo dinfo; + char rep1[] = { 0xff, 0x80, 0x80, 0x01, 0x00, 0x00 }; + char rep2[] = { 0xff, 0x80, 0x00, 0x00, 0x30, 0x00 }; + char rep3[] = { 0xff, 0x81, 0x80, 0x00, 0x00, 0x00 }; + + sprintf(devname, "%s/hiddev%d", devpath, i); + fd = open(devname, O_RDWR); + if (fd < 0) { + sprintf(devname, "%s/usb/hiddev%d", devpath, i); + fd = open(devname, O_RDWR); + if (fd < 0) { + sprintf(devname, "%s/usb/hid/hiddev%d", devpath, i); + fd = open(devname, O_RDWR); + if (fd < 0) + continue; + } + } + + memset(&dinfo, 0, sizeof(dinfo)); + err = ioctl(fd, HIDIOCGDEVINFO, &dinfo); + if (err < 0 || dinfo.busnum != dev->busnum || + dinfo.devnum != dev->devnum) { + close(fd); + continue; + } + + err = ioctl(fd, HIDIOCINITREPORT, 0); + if (err < 0) { + close(fd); + break; + } + + err = send_report(fd, rep1, sizeof(rep1)); + if (err < 0) { + close(fd); + break; + } + + err = send_report(fd, rep2, sizeof(rep2)); + if (err < 0) { + close(fd); + break; + } + + err = send_report(fd, rep3, sizeof(rep3)); + close(fd); + break; + } + + return err; +} + +static struct device_id device_list[] = { + { HCI, 0x0a12, 0x1000, switch_hidproxy }, + { HID, 0x0a12, 0x0001, switch_hidproxy }, + { HCI, 0x05ac, 0x1000, switch_hidproxy }, + { HID, 0x05ac, 0x8203, switch_hidproxy }, + { HCI, 0x046d, 0xc703, switch_logitech }, + { HCI, 0x046d, 0xc704, switch_logitech }, + { HCI, 0x046d, 0xc705, switch_logitech }, + { -1 } +}; + +static struct device_id *match_device(int mode, uint16_t vendor, uint16_t product) +{ + int i; + + for (i = 0; device_list[i].mode >= 0; i++) { + if (mode != device_list[i].mode) + continue; + if (vendor == device_list[i].vendor && + product == device_list[i].product) + return &device_list[i]; + } + + return NULL; +} + +static int find_devices(int mode, struct device_info *dev, size_t size) +{ + DIR *busdir, *devdir; + struct dirent *entry; + struct usb_device_descriptor desc; + struct device_id *id; + int fd, len, busnum, devnum, count = 0; + char buspath[PATH_MAX + 1]; + char devname[PATH_MAX + 1]; + + if (!(busdir = opendir(usbpath))) + return -1; + + while ((entry = readdir(busdir))) { + if (entry->d_name[0] == '.') + continue; + + if (!strchr("0123456789", + entry->d_name[strlen(entry->d_name) - 1])) + continue; + + busnum = atoi(entry->d_name); + snprintf(buspath, PATH_MAX, "%s/%s", usbpath, entry->d_name); + if (!(devdir = opendir(buspath))) + continue; + + while ((entry = readdir(devdir))) { + if (entry->d_name[0] == '.') + continue; + + if (!strchr("0123456789", + entry->d_name[strlen(entry->d_name) - 1])) + continue; + + devnum = atoi(entry->d_name); + snprintf(devname, PATH_MAX, "%s/%s", + buspath, entry->d_name); + + if ((fd = open(devname, O_RDONLY)) < 0) + continue; + + len = read(fd, &desc, sizeof(desc)); + if (len < 0 || len != sizeof(desc)) + continue; + + id = match_device(mode, desc.idVendor, desc.idProduct); + if (!id) + continue; + + if (count < size) { + dev[count].busnum = busnum; + dev[count].devnum = devnum; + dev[count].id = id; + count++; + } + } + + closedir(devdir); + } + + closedir(busdir); + + return count; +} + + +static void usage(void) +{ + printf("hid2hci - Bluetooth HID to HCI mode switching utility\n\n"); + + printf("Usage:\n" + "\thid2hci [options]\n" + "\n"); + + printf("Options:\n" + "\t-h, --help Display help\n" + "\t-0, --tohci Switch to HCI mode (default)\n" + "\t-1, --tohid Switch to HID mode\n" + "\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "tohci", 0, 0, '0' }, + { "tohid", 0, 0, '1' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct device_info dev[16]; + int i, opt, num, mode = HCI; + + while ((opt = getopt_long(argc, argv, "+01h", main_options, NULL)) != -1) { + switch (opt) { + case '0': + mode = HCI; + break; + case '1': + mode = HID; + break; + case 'h': + usage(); + exit(0); + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + num = find_devices(mode, dev, sizeof(dev) / sizeof(dev[0])); + if (num <= 0) { + fprintf(stderr, "No devices in %s mode found\n", + mode ? "HID" : "HCI"); + exit(1); + } + + for (i = 0; i < num; i++) { + struct device_id *id = dev[i].id; + + printf("Switching device %04x:%04x to %s mode ", + id->vendor, id->product, mode ? "HID" : "HCI"); + fflush(stdout); + + if (id->func(&dev[i]) < 0) + printf("failed (%s)\n", strerror(errno)); + else + printf("was successful\n"); + } + + return 0; +} -- cgit From ecbe15c8f763206abf39b17252ef8270f3d5b507 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 11:18:19 +0000 Subject: Add CVS $Id line --- tools/ciptool.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index bec3fc2b..fc23bf2e 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -19,6 +19,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * + * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From fab001c1250c40ef96b85a60a7b8111596688452 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 11:22:47 +0000 Subject: Fix warning in hcisecfilter --- tools/Makefile.am | 2 +- tools/hcisecfilter.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index c45f5635..c1eb4564 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -6,7 +6,7 @@ sbin_PROGRAMS = hciattach hciconfig hid2hci bin_PROGRAMS = hcitool l2ping sdptool ciptool -noinst_PROGRAMS = ppporc +noinst_PROGRAMS = ppporc hcisecfilter hciconfig_SOURCES = hciconfig.c csr.h csr.c diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 2ff5c48a..9aaead0f 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -15,7 +15,7 @@ int main(void) memset((void *)&type_mask, 0, sizeof(type_mask)); hci_set_bit(HCI_EVENT_PKT, &type_mask); - printf("Type mask: { 0x%lx }\n", type_mask); + printf("Type mask: { 0x%x }\n", type_mask); // Events memset((void *)event_mask, 0, sizeof(event_mask)); @@ -36,7 +36,7 @@ int main(void) hci_set_bit(EVT_READ_REMOTE_VERSION_COMPLETE, event_mask); hci_set_bit(EVT_REMOTE_NAME_REQ_COMPLETE, event_mask); - printf("Event mask: { 0x%lx, 0x%lx }\n", event_mask[0], event_mask[1]); + printf("Event mask: { 0x%x, 0x%x }\n", event_mask[0], event_mask[1]); // OGF_LINK_CTL memset((void *) ocf_mask, 0, sizeof(ocf_mask)); @@ -45,7 +45,7 @@ int main(void) hci_set_bit(OCF_READ_REMOTE_FEATURES, ocf_mask); hci_set_bit(OCF_READ_REMOTE_VERSION, ocf_mask); - printf("OGF_LINK_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + printf("OGF_LINK_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); // OGF_LINK_POLICY @@ -53,7 +53,7 @@ int main(void) hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); - printf("OGF_LINK_POLICY: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + printf("OGF_LINK_POLICY: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); // OGF_HOST_CTL @@ -65,7 +65,7 @@ int main(void) hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); hci_set_bit(OCF_READ_TRANSMIT_POWER_LEVEL, ocf_mask); - printf("OGF_HOST_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + printf("OGF_HOST_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); // OGF_INFO_PARAM @@ -76,7 +76,7 @@ int main(void) hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); - printf("OGF_INFO_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", + printf("OGF_INFO_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); // OGF_INFO_PARAM @@ -86,6 +86,8 @@ int main(void) hci_set_bit(OCF_GET_LINK_QUALITY, ocf_mask); hci_set_bit(OCF_READ_RSSI, ocf_mask); - printf("OGF_STATUS_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", + printf("OGF_STATUS_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + return 0; } -- cgit From 7b44fb1986b0bae4fc37130c22a975972261f851 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 14:12:26 +0000 Subject: The lmp_featurestostr() now uses a character number as width --- tools/hciconfig.c | 2 +- tools/hcitool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 6ab7f190..7e6f6849 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -113,7 +113,7 @@ void print_dev_features(struct hci_dev_info *di, int format) di->features[2], di->features[3], di->features[4], di->features[5], di->features[6], di->features[7], - lmp_featurestostr(di->features, "\t\t", 3)); + lmp_featurestostr(di->features, "\t\t", 63)); } } diff --git a/tools/hcitool.c b/tools/hcitool.c index 37450098..b01f78d6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -465,7 +465,7 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 3)); + lmp_featurestostr(features, "\t\t", 63)); } if (cc) -- cgit From 241112a349dde07429e27098be760476c99f556d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 15:09:01 +0000 Subject: Add support for inquiry mode --- tools/hciconfig.8 | 6 ++++++ tools/hciconfig.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index aac5e98a..8e9fb257 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -121,6 +121,12 @@ With no prints the current IAC setting. Otherwise, sets the IAC to .IR iac . .TP +.BI inqmode " [mode]" +With no +.IR mode , +prints out the current inquiry mode. Otherwise, sets inquiry mode to +.IR mode . +.TP .BI inqparms " [win:int]" With no .IR win:int , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 7e6f6849..7134bfc1 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -649,6 +649,59 @@ void cmd_version(int ctl, int hdev, char *opt) bt_compidtostr(ver.manufacturer), ver.manufacturer); } +void cmd_inq_mode(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + write_inquiry_mode_cp cp; + + cp.mode = atoi(opt); + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQUIRY_MODE; + rq.cparam = &cp; + rq.clen = WRITE_INQUIRY_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("Can't set inquiry mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + read_inquiry_mode_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQUIRY_MODE; + rq.rparam = &rp; + rq.rlen = READ_INQUIRY_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("Can't read inquiry mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read inquiry mode on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + + print_dev_hdr(&di); + printf("\tInquiry mode: %s\n", + rp.mode == 1 ? "Inquiry with RSSI" : "Standard Inquiry"); + } +} + void cmd_inq_parms(int ctl, int hdev, char *opt) { struct hci_request rq; @@ -1011,6 +1064,7 @@ struct { { "class", cmd_class, "[class]", "Get/Set class of device" }, { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, + { "inqmode", cmd_inq_mode, "[mode]", "Get/set inquiry mode" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, -- cgit From 2facfcf46852253bfd96c3888128a419d3a04c6a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 19:10:25 +0000 Subject: Add support for AFH mode --- tools/hciconfig.8 | 6 ++++++ tools/hciconfig.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 8e9fb257..b8b780ee 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -157,6 +157,12 @@ to to slots. .TP +.BI afhmode " [mode]" +With no +.IR mode , +prints out the current AFH mode. Otherwise, sets AFH mode to +.IR mode . +.TP .BI aclmtu " " Sets ACL MTU to to diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 7134bfc1..6393764b 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -898,6 +898,58 @@ void cmd_page_to(int ctl, int hdev, char *opt) } } +void cmd_afh_mode(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + write_afh_mode_cp cp; + + cp.mode = atoi(opt); + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_AFH_MODE; + rq.cparam = &cp; + rq.clen = WRITE_AFH_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("Can't set AFH mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + read_afh_mode_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_AFH_MODE; + rq.rparam = &rp; + rq.rlen = READ_AFH_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("Can't read AFH mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read AFH mode on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + + print_dev_hdr(&di); + printf("\tAFH mode: %s\n", rp.mode == 1 ? "Enabled" : "Disabled"); + } +} + static void print_rev_ericsson(int dd) { struct hci_request rq; @@ -1068,6 +1120,7 @@ struct { { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, + { "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" }, { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, { "features", cmd_features, 0, "Display device features" }, -- cgit From 56cbbde9aaecbfdd1f1e4c820de92110355aa365 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 19:11:20 +0000 Subject: Add support for getting the AFH channel map --- tools/hcitool.1 | 4 +++ tools/hcitool.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index f23cf7f5..1d87b9a0 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -139,6 +139,10 @@ for the current transmit power level (which is default) or .BR 1 for the maximum transmit power level. .TP +.BI afh " " +Display AFH channel map for the connection to the device with Bluetooth address +.IR bdaddr . +.TP .BI lst " [value]" With no .IR value , diff --git a/tools/hcitool.c b/tools/hcitool.c index b01f78d6..99355861 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1074,6 +1074,102 @@ static void cmd_tpl(int dev_id, int argc, char **argv) free(cr); } +/* Get AFH channel map */ + +static struct option afh_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *afh_help = + "Usage:\n" + "\tafh \n"; + +static void cmd_afh(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_afh_map_rp rp; + bdaddr_t bdaddr; + uint16_t handle; + int opt, dd; + + for_each_opt(opt, afh_options, NULL) { + switch(opt) { + default: + printf(afh_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(afh_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + handle = htobs(cr->conn_info->handle); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_AFH_MAP; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_AFH_MAP_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read AFH map request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + + if (rp.mode == 0x01) { + int i; + printf("AFH map: 0x"); + for (i = 0; i < 10; i++) + printf("%02x", rp.map[i]); + printf("\n"); + } else + printf("AFH disabled\n"); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -1451,6 +1547,7 @@ static struct { { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, + { "afh", cmd_afh, "Display AFH channel map" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, -- cgit From b66d3f9b2cb8934a0eb7ac07f347001984488ac6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 10:39:47 +0000 Subject: Unify copyright and license information --- tools/ciptool.c | 29 +++++++++--------- tools/csr.c | 34 ++++++++++++-------- tools/csr.h | 29 ++++++++++-------- tools/hciattach.c | 52 ++++++++++++++++--------------- tools/hciconfig.c | 51 +++++++++++++++--------------- tools/hcisecfilter.c | 63 ++++++++++++++++++++++++++++--------- tools/hcitool.c | 51 +++++++++++++++--------------- tools/hid2hci.c | 30 +++++++++--------- tools/l2ping.c | 87 ++++++++++++++++++++++++++++------------------------ tools/ppporc.c | 50 ++++++++++++++---------------- tools/sdptool.c | 55 +++++++++++++++++---------------- 11 files changed, 295 insertions(+), 236 deletions(-) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index fc23bf2e..d0b6625d 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -1,23 +1,26 @@ /* * - * Bluetooth Common ISDN Access Profile (CIP) + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2003 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * * * $Id$ @@ -46,7 +49,6 @@ #include #include - static volatile sig_atomic_t __io_canceled = 0; static void sig_hup(int sig) @@ -387,7 +389,6 @@ static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) ioctl(ctl, CMTPCONNDEL, &req); } - static struct { char *cmd; char *alt; diff --git a/tools/csr.c b/tools/csr.c index e2069cd7..60cba66b 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -1,26 +1,35 @@ /* * - * CSR BlueCore specific functions + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003 Marcel Holtmann + * Copyright (C) 2003-2004 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -32,7 +41,6 @@ #include "csr.h" - static struct { uint16_t id; char *str; diff --git a/tools/csr.h b/tools/csr.h index 254f108e..b96dd0f7 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -1,24 +1,29 @@ /* * - * CSR BlueCore specific functions + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003 Marcel Holtmann + * Copyright (C) 2003-2004 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ #define CSR_VARID_BUILDID 0x2819 diff --git a/tools/hciattach.c b/tools/hciattach.c index 926e3fab..7194ad6a 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -1,27 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H @@ -47,8 +51,8 @@ #include #include -#include #include +#include struct uart_t { char *type; diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 6393764b..d7b7513a 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1,28 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 9aaead0f..fd296afd 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -1,3 +1,36 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include @@ -11,23 +44,23 @@ int main(void) uint32_t event_mask[2]; uint32_t ocf_mask[4]; - // Packet types + /* Packet types */ memset((void *)&type_mask, 0, sizeof(type_mask)); hci_set_bit(HCI_EVENT_PKT, &type_mask); - + printf("Type mask: { 0x%x }\n", type_mask); - // Events + /* Events */ memset((void *)event_mask, 0, sizeof(event_mask)); - hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); - hci_set_bit(EVT_INQUIRY_RESULT, event_mask); + hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); + hci_set_bit(EVT_INQUIRY_RESULT, event_mask); - hci_set_bit(EVT_CONN_COMPLETE, event_mask); - hci_set_bit(EVT_CONN_REQUEST, event_mask); - hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); + hci_set_bit(EVT_CONN_COMPLETE, event_mask); + hci_set_bit(EVT_CONN_REQUEST, event_mask); + hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); - hci_set_bit(EVT_AUTH_COMPLETE, event_mask); - hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); + hci_set_bit(EVT_AUTH_COMPLETE, event_mask); + hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); hci_set_bit(EVT_CMD_COMPLETE, event_mask); hci_set_bit(EVT_CMD_STATUS, event_mask); @@ -38,7 +71,7 @@ int main(void) printf("Event mask: { 0x%x, 0x%x }\n", event_mask[0], event_mask[1]); - // OGF_LINK_CTL + /* OGF_LINK_CTL */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_INQUIRY, ocf_mask); hci_set_bit(OCF_REMOTE_NAME_REQ, ocf_mask); @@ -48,7 +81,7 @@ int main(void) printf("OGF_LINK_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - // OGF_LINK_POLICY + /* OGF_LINK_POLICY */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); @@ -56,7 +89,7 @@ int main(void) printf("OGF_LINK_POLICY: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - // OGF_HOST_CTL + /* OGF_HOST_CTL */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_READ_AUTH_ENABLE, ocf_mask); hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); @@ -68,7 +101,7 @@ int main(void) printf("OGF_HOST_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - // OGF_INFO_PARAM + /* OGF_INFO_PARAM */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_READ_LOCAL_VERSION, ocf_mask); hci_set_bit(OCF_READ_LOCAL_FEATURES, ocf_mask); @@ -79,7 +112,7 @@ int main(void) printf("OGF_INFO_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - // OGF_INFO_PARAM + /* OGF_INFO_PARAM */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); hci_set_bit(OCF_RESET_FAILED_CONTACT_COUNTER, ocf_mask); diff --git a/tools/hcitool.c b/tools/hcitool.c index 99355861..5cecdf7e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1,28 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 95a7c7d6..73b7e12c 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -1,23 +1,26 @@ /* * - * Bluetooth HID to HCI mode switching utility + * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2003-2004 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * * * $Id$ @@ -38,7 +41,6 @@ #include #include - static char usbpath[PATH_MAX + 1] = "/proc/bus/usb"; struct usb_device_descriptor { @@ -75,7 +77,6 @@ struct usb_ctrltransfer { #define USB_TYPE_VENDOR 0x40 #define USB_DIR_OUT 0x00 - static char devpath[PATH_MAX + 1] = "/dev"; struct hiddev_devinfo { @@ -113,7 +114,6 @@ struct hiddev_usage_ref { #define HID_REPORT_TYPE_OUTPUT 2 - #define HCI 0 #define HID 1 @@ -132,7 +132,6 @@ struct device_info { struct device_id *id; }; - static int switch_hidproxy(struct device_info *dev) { struct usb_ctrltransfer ctrl; @@ -347,7 +346,6 @@ static int find_devices(int mode, struct device_info *dev, size_t size) return count; } - static void usage(void) { printf("hid2hci - Bluetooth HID to HCI mode switching utility\n\n"); diff --git a/tools/l2ping.c b/tools/l2ping.c index d5d7748b..85d12eee 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -1,30 +1,37 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -93,20 +100,20 @@ static void ping(char *svr) memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; addr.l2_bdaddr = bdaddr; - if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("Can't bind socket."); exit(1); - } + } str2ba(svr, &addr.l2_bdaddr); - if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("Can't connect."); exit(1); } /* Get local address */ opt = sizeof(addr); - if( getsockname(s, (struct sockaddr *)&addr, &opt) < 0 ) { + if (getsockname(s, (struct sockaddr *)&addr, &opt) < 0) { perror("Can't get local address."); exit(1); } @@ -115,7 +122,7 @@ static void ping(char *svr) printf("Ping: %s from %s (data size %d) ...\n", svr, str, size); /* Initialize buffer */ - for(i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) + for (i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) buf[i]=(i%40)+'A'; id = ident; @@ -132,34 +139,34 @@ static void ping(char *svr) gettimeofday(&tv_send, NULL); /* Send Echo Request */ - if( send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0 ){ + if (send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0) { perror("Send failed"); exit(1); } /* Wait for Echo Response */ lost = 0; - while( 1 ) { + while (1) { struct pollfd pf[1]; register int err; pf[0].fd = s; pf[0].events = POLLIN; - if( (err = poll(pf, 1, 10*1000)) < 0 ) { + if ((err = poll(pf, 1, 10*1000)) < 0) { perror("Poll failed"); exit(1); } - if( !err ){ + if (!err) { lost = 1; break; } - if( (err = recv(s, buf, sizeof(buf), 0)) < 0 ) { + if ((err = recv(s, buf, sizeof(buf), 0)) < 0) { perror("Recv failed"); exit(1); } - if( !err ){ + if (!err){ printf("Disconnected\n"); exit(1); } @@ -171,9 +178,9 @@ static void ping(char *svr) continue; /* Check type */ - if( cmd->code == L2CAP_ECHO_RSP ) + if (cmd->code == L2CAP_ECHO_RSP) break; - if( cmd->code == L2CAP_COMMAND_REJ ){ + if (cmd->code == L2CAP_COMMAND_REJ) { printf("Peer doesn't support Echo packets\n"); exit(1); } @@ -181,7 +188,7 @@ static void ping(char *svr) } sent_pkt++; - if( !lost ){ + if (!lost) { recv_pkt++; gettimeofday(&tv_recv, NULL); @@ -189,12 +196,12 @@ static void ping(char *svr) printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id, tv2fl(tv_diff)); - if( delay ) sleep(delay); + if (delay) sleep(delay); } else { printf("no response from %s: id %d\n", svr, id); } - if( ++id > 254 ) id = ident; + if (++id > 254) id = ident; } stat(0); } diff --git a/tools/ppporc.c b/tools/ppporc.c index 514ceb65..60aefd39 100644 --- a/tools/ppporc.c +++ b/tools/ppporc.c @@ -1,26 +1,35 @@ /* * - * PPP over Bluetooth RFCOMM + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -35,11 +44,9 @@ #include #include - extern int optind, opterr, optopt; extern char *optarg; - /* IO cancelation */ static volatile sig_atomic_t __io_canceled; @@ -53,7 +60,6 @@ static inline void io_cancel(void) __io_canceled = 1; } - /* Signal functions */ static void sig_hup(int sig) { @@ -66,7 +72,6 @@ static void sig_term(int sig) io_cancel(); } - /* Read exactly len bytes (Signal safe)*/ static inline int read_n(int fd, char *buf, int len) { @@ -88,7 +93,6 @@ static inline int read_n(int fd, char *buf, int len) return t; } - /* Write exactly len bytes (Signal safe)*/ static inline int write_n(int fd, char *buf, int len) { @@ -110,7 +114,6 @@ static inline int write_n(int fd, char *buf, int len) return t; } - /* Create the RFCOMM connection */ static int create_connection(bdaddr_t *bdaddr, uint8_t channel) { @@ -142,7 +145,6 @@ static int create_connection(bdaddr_t *bdaddr, uint8_t channel) return fd; } - /* Process the data from socket and pseudo tty */ static int process_data(int fd) { @@ -157,7 +159,7 @@ static int process_data(int fd) p[1].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; err = 0; - + while (!__io_canceled) { p[0].revents = 0; p[1].revents = 0; @@ -186,7 +188,7 @@ static int process_data(int fd) if (p[1].revents) { if (p[1].revents & (POLLERR | POLLHUP | POLLNVAL)) - break; + break; r = read(fd, buf, sizeof(buf)); if (r < 0) { if (errno != EINTR && errno != EAGAIN) { @@ -204,13 +206,11 @@ static int process_data(int fd) return err; } - static void usage(void) { printf("Usage:\tppporc [channel]\n"); } - int main(int argc, char** argv) { struct sigaction sa; @@ -219,7 +219,6 @@ int main(int argc, char** argv) bdaddr_t bdaddr; uint8_t channel; - /* Parse command line options */ while ((opt = getopt(argc, argv, "h")) != EOF) { switch(opt) { @@ -246,12 +245,10 @@ int main(int argc, char** argv) exit(0); } - /* Initialize syslog */ openlog("ppporc", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); syslog(LOG_INFO, "PPP over RFCOMM"); - /* Initialize signals */ memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; @@ -266,7 +263,6 @@ int main(int argc, char** argv) sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); - syslog(LOG_INFO, "Connecting to %s", argv[0]); if ((fd = create_connection(&bdaddr, channel)) < 0) { diff --git a/tools/sdptool.c b/tools/sdptool.c index 87646cab..1dcdf8e4 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1,31 +1,32 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky - Copyright (C) 2002 Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From 596ce96eefb0a1f7feda4ecd29a49d8bc6792cf3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 3 May 2004 13:25:14 +0000 Subject: Fix default baudrate for ST devices --- tools/hciattach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 7194ad6a..3e8be20a 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -779,7 +779,7 @@ static int st(int fd, struct uart_t *u, struct termios *ti) break; default: cmd[4] = 0x10; - u->speed = 57600; + u->speed = 115200; break; } -- cgit From 014f95443e8c29ffd6f28d7f3eac916b16f96b00 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 08:30:41 +0000 Subject: Fix section number --- tools/hciconfig.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index b8b780ee..3c6c96d8 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -1,4 +1,4 @@ -.TH HCICONFIG 1 "Nov 11 2002" BlueZ "Linux System Administration" +.TH HCICONFIG 8 "Nov 11 2002" BlueZ "Linux System Administration" .SH NAME hciconfig \- configure Bluetooth devices .SH SYNOPSIS -- cgit From 0a61c1514914951ff94e1228e8031737cc423e41 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 May 2004 13:47:19 +0000 Subject: Use 10 characters array in swave() routine --- tools/hciattach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 3e8be20a..50432ec3 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -640,7 +640,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) static int swave(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 500000}; - char cmd[9], rsp[100]; + char cmd[10], rsp[100]; int r; // Silicon Wave set baud rate command -- cgit From 2cc3c8c8b4ae24e312533f1c60abb9f70e07f2a7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 May 2004 10:41:37 +0000 Subject: Use LDADD instead of LDFLAGS --- tools/Makefile.am | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index c1eb4564..6956f9de 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -10,17 +10,17 @@ noinst_PROGRAMS = ppporc hcisecfilter hciconfig_SOURCES = hciconfig.c csr.h csr.c -hciconfig_LDFLAGS = @BLUEZ_LIBS@ +hciconfig_LDADD = @BLUEZ_LIBS@ -hcitool_LDFLAGS = @BLUEZ_LIBS@ +hcitool_LDADD = @BLUEZ_LIBS@ -l2ping_LDFLAGS = @BLUEZ_LIBS@ +l2ping_LDADD = @BLUEZ_LIBS@ -sdptool_LDFLAGS = @BLUEZ_LIBS@ +sdptool_LDADD = @BLUEZ_LIBS@ -ciptool_LDFLAGS = @BLUEZ_LIBS@ +ciptool_LDADD = @BLUEZ_LIBS@ -ppporc_LDFLAGS = @BLUEZ_LIBS@ +ppporc_LDADD = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ -- cgit From 120825fb6af4c6dd0c933c798f2fe997d84d2466 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Jun 2004 09:59:40 +0000 Subject: Add build id's for HCI 18.1 and HCI 18.2 firmware --- tools/csr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 60cba66b..6d9185e1 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -242,6 +242,10 @@ static struct { { 856, "HCI 17.3.2" }, { 857, "HCI 17.3.2" }, { 858, "HCI 17.3.2" }, + { 1168, "HCI 18.1" }, + { 1169, "HCI 18.1" }, + { 1392, "HCI 18.2" }, + { 1393, "HCI 18.2" }, { 0, } }; -- cgit From 2650bf7cbc4b7e0121a9995cd056b8debf3bc424 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jun 2004 11:43:19 +0000 Subject: Add support for audio source and audio sink --- tools/sdptool.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 1dcdf8e4..b3ccf411 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1562,6 +1562,124 @@ end: return ret; } +static int add_audio_source(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, avdtp, a2src; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + sdp_data_t *psm, *version; + uint16_t lp = 0x0019, ver = 0x0100; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID); + svclass_id = sdp_list_append(0, &a2src); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&avdtp, AVDTP_UUID); + proto[1] = sdp_list_append(0, &avdtp); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Audio Source", 0, 0); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto done; + } + + printf("Audio source service registered\n"); + +done: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_audio_sink(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, avdtp, a2snk; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + sdp_data_t *psm, *version; + uint16_t lp = 0x0019, ver = 0x0100; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&a2snk, AUDIO_SINK_SVCLASS_ID); + svclass_id = sdp_list_append(0, &a2snk); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&avdtp, AVDTP_UUID); + proto[1] = sdp_list_append(0, &avdtp); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Audio Sink", 0, 0); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto done; + } + + printf("Audio sink service registered\n"); + +done: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + struct { char *name; uint16_t class; @@ -1584,6 +1702,9 @@ struct { { "CIP", CIP_SVCLASS_ID, add_cip }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, + { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source }, + { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, + { 0 } }; -- cgit From f3ba72e2b071ba40bfe535a4b76193100a956462 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 12 Jun 2004 09:41:17 +0000 Subject: Change timeout for create connection --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 5cecdf7e..8f03ae86 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -660,7 +660,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 1000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From 587fe743849609dd150666d84f8fa53cd403a70e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 Jun 2004 16:30:41 +0000 Subject: Add support for AmbiCom BT2000C card --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 50432ec3..2024c1de 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -833,6 +833,9 @@ struct uart_t uart[] = { /* 3Com Bluetooth Card (Version 3.0) */ { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + /* AmbiCom BT2000C Bluetooth PC/CF Card */ + { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, + { NULL, 0 } }; -- cgit From ee253a9633d29120dcc2e3be4265240ae538a072 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Jul 2004 03:25:36 +0000 Subject: Add Jean to the copyright statement --- tools/sdptool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index b3ccf411..4f89491d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -6,6 +6,7 @@ * Copyright (C) 2002-2003 Maxim Krasnyansky * Copyright (C) 2002-2004 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane + * Copyright (C) 2002-2003 Jean Tourrilhes * * * This program is free software; you can redistribute it and/or modify -- cgit From 43f017c9527dd4f64670831114f3c85f5defebbd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:05:27 +0000 Subject: Use AM_CFLAGS instead of INCLUDES --- tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 6956f9de..a10ad999 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -22,7 +22,7 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 -- cgit From 15c1cf1ca0d2fc45dff471d71339db49deecd1cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:20:28 +0000 Subject: Make use of MAINTAINERCLEANFILES --- tools/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index a10ad999..cdba20b4 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -27,3 +27,5 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 EXTRA_DIST = $(man_MANS) + +MAINTAINERCLEANFILES = Makefile.in -- cgit From 01e800f18ea32d2b9d285bb245d303e3aa81fc3b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Jul 2004 07:36:18 +0000 Subject: Use packet type and allow role switch --- tools/hcitool.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8f03ae86..df33412f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -394,6 +394,7 @@ static void cmd_info(int dev_id, int argc, char **argv) char name[248]; unsigned char features[8]; struct hci_version version; + struct hci_dev_info di; struct hci_conn_info_req *cr; int opt, dd, cc = 0; @@ -425,6 +426,11 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + printf("Requesting information ...\n"); dd = hci_open_dev(dev_id); @@ -443,7 +449,7 @@ static void cmd_info(int dev_id, int argc, char **argv) bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, htobs(HCI_DM1 | HCI_DH1), 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -618,7 +624,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) uint16_t handle; uint8_t role; - role = 0; + role = 0x01; ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; for_each_opt(opt, cc_options, NULL) { -- cgit From 90a6c1b2e4b6f065bd2c134fa06fe93b174e094d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 Jul 2004 20:57:01 +0000 Subject: Use the functions from the USB library --- tools/Makefile.am | 4 +- tools/hid2hci.8 | 3 + tools/hid2hci.c | 179 +++++++++++++++++------------------------------------- 3 files changed, 63 insertions(+), 123 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index cdba20b4..ca0514ce 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -22,7 +22,9 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -AM_CFLAGS = @BLUEZ_CFLAGS@ +hid2hci_LDADD = @USB_LIBS@ + +AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 diff --git a/tools/hid2hci.8 b/tools/hid2hci.8 index 8f7ea4fe..6aa9be29 100644 --- a/tools/hid2hci.8 +++ b/tools/hid2hci.8 @@ -32,6 +32,9 @@ mode and back. .BI -h Gives a list of possible options. .TP +.BI -q +Don't display any messages. +.TP .BI -0 Switches the device into HCI mode. .TP diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 73b7e12c..6b2aec72 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -33,49 +33,23 @@ #include #include #include -#include -#include #include -#include #include #include #include -static char usbpath[PATH_MAX + 1] = "/proc/bus/usb"; - -struct usb_device_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize0; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; - uint8_t iManufacturer; - uint8_t iProduct; - uint8_t iSerialNumber; - uint8_t bNumConfigurations; -} __attribute__ ((packed)); - -struct usb_ctrltransfer { - uint8_t bRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; - - uint32_t timeout; /* in milliseconds */ - void *data; /* pointer to data */ -}; +#include -#define IOCTL_USB_CONTROL _IOWR('U', 0, struct usb_ctrltransfer) +#ifndef usb_get_busses +struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif -#define USB_RECIP_DEVICE 0x00 -#define USB_TYPE_VENDOR 0x40 -#define USB_DIR_OUT 0x00 +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif static char devpath[PATH_MAX + 1] = "/dev"; @@ -127,34 +101,21 @@ struct device_id { }; struct device_info { - uint16_t busnum; - uint16_t devnum; + struct usb_device *dev; struct device_id *id; }; -static int switch_hidproxy(struct device_info *dev) +static int switch_hidproxy(struct device_info *devinfo) { - struct usb_ctrltransfer ctrl; - char devname[PATH_MAX + 1]; - int fd, err; - - snprintf(devname, PATH_MAX, "%s/%03d/%03d", - usbpath, dev->busnum, dev->devnum); - - fd = open(devname, O_RDWR); - if (fd < 0) - return fd; + struct usb_dev_handle *udev; + int err; - ctrl.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - ctrl.bRequest = 0; - ctrl.wValue = dev->id->mode; - ctrl.wIndex = 0; - ctrl.wLength = 0; + udev = usb_open(devinfo->dev); + if (!udev) + return -errno; - ctrl.data = NULL; - ctrl.timeout = 10000; - - err = ioctl(fd, IOCTL_USB_CONTROL, &ctrl); + err = usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, devinfo->id->mode, 0, NULL, 0, 10000); if (err == 0) { err = -1; @@ -164,7 +125,7 @@ static int switch_hidproxy(struct device_info *dev) err = 0; } - close(fd); + usb_close(udev); return err; } @@ -197,7 +158,7 @@ static int send_report(int fd, const unsigned char *buf, size_t size) return err; } -static int switch_logitech(struct device_info *dev) +static int switch_logitech(struct device_info *devinfo) { char devname[PATH_MAX + 1]; int i, fd, err = -1; @@ -223,8 +184,8 @@ static int switch_logitech(struct device_info *dev) memset(&dinfo, 0, sizeof(dinfo)); err = ioctl(fd, HIDIOCGDEVINFO, &dinfo); - if (err < 0 || dinfo.busnum != dev->busnum || - dinfo.devnum != dev->devnum) { + if (err < 0 || dinfo.busnum != atoi(devinfo->dev->bus->dirname) || + dinfo.devnum != atoi(devinfo->dev->filename)) { close(fd); continue; } @@ -281,68 +242,30 @@ static struct device_id *match_device(int mode, uint16_t vendor, uint16_t produc return NULL; } -static int find_devices(int mode, struct device_info *dev, size_t size) +static int find_devices(int mode, struct device_info *devinfo, size_t size) { - DIR *busdir, *devdir; - struct dirent *entry; - struct usb_device_descriptor desc; + struct usb_bus *bus; + struct usb_device *dev; struct device_id *id; - int fd, len, busnum, devnum, count = 0; - char buspath[PATH_MAX + 1]; - char devname[PATH_MAX + 1]; - - if (!(busdir = opendir(usbpath))) - return -1; - - while ((entry = readdir(busdir))) { - if (entry->d_name[0] == '.') - continue; - - if (!strchr("0123456789", - entry->d_name[strlen(entry->d_name) - 1])) - continue; + int count = 0; - busnum = atoi(entry->d_name); - snprintf(buspath, PATH_MAX, "%s/%s", usbpath, entry->d_name); - if (!(devdir = opendir(buspath))) - continue; + usb_find_busses(); + usb_find_devices(); - while ((entry = readdir(devdir))) { - if (entry->d_name[0] == '.') - continue; - - if (!strchr("0123456789", - entry->d_name[strlen(entry->d_name) - 1])) - continue; - - devnum = atoi(entry->d_name); - snprintf(devname, PATH_MAX, "%s/%s", - buspath, entry->d_name); - - if ((fd = open(devname, O_RDONLY)) < 0) - continue; - - len = read(fd, &desc, sizeof(desc)); - if (len < 0 || len != sizeof(desc)) - continue; - - id = match_device(mode, desc.idVendor, desc.idProduct); + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) { + id = match_device(mode, dev->descriptor.idVendor, + dev->descriptor.idProduct); if (!id) continue; if (count < size) { - dev[count].busnum = busnum; - dev[count].devnum = devnum; - dev[count].id = id; + devinfo[count].dev = dev; + devinfo[count].id = id; count++; } } - closedir(devdir); - } - - closedir(busdir); - return count; } @@ -356,6 +279,7 @@ static void usage(void) printf("Options:\n" "\t-h, --help Display help\n" + "\t-q, --quiet Don't display any messages\n" "\t-0, --tohci Switch to HCI mode (default)\n" "\t-1, --tohid Switch to HID mode\n" "\n"); @@ -363,6 +287,7 @@ static void usage(void) static struct option main_options[] = { { "help", 0, 0, 'h' }, + { "quiet", 0, 0, 'q' }, { "tohci", 0, 0, '0' }, { "tohid", 0, 0, '1' }, { 0, 0, 0, 0 } @@ -371,9 +296,9 @@ static struct option main_options[] = { int main(int argc, char *argv[]) { struct device_info dev[16]; - int i, opt, num, mode = HCI; + int i, opt, num, quiet = 0, mode = HCI; - while ((opt = getopt_long(argc, argv, "+01h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+01qh", main_options, NULL)) != -1) { switch (opt) { case '0': mode = HCI; @@ -381,6 +306,9 @@ int main(int argc, char *argv[]) case '1': mode = HID; break; + case 'q': + quiet = 1; + break; case 'h': usage(); exit(0); @@ -393,24 +321,31 @@ int main(int argc, char *argv[]) argv += optind; optind = 0; + usb_init(); + num = find_devices(mode, dev, sizeof(dev) / sizeof(dev[0])); if (num <= 0) { - fprintf(stderr, "No devices in %s mode found\n", - mode ? "HID" : "HCI"); + if (!quiet) + fprintf(stderr, "No devices in %s mode found\n", + mode ? "HID" : "HCI"); exit(1); } for (i = 0; i < num; i++) { struct device_id *id = dev[i].id; - printf("Switching device %04x:%04x to %s mode ", - id->vendor, id->product, mode ? "HID" : "HCI"); + if (!quiet) + printf("Switching device %04x:%04x to %s mode ", + id->vendor, id->product, mode ? "HID" : "HCI"); fflush(stdout); - if (id->func(&dev[i]) < 0) - printf("failed (%s)\n", strerror(errno)); - else - printf("was successful\n"); + if (id->func(&dev[i]) < 0) { + if (!quiet) + printf("failed (%s)\n", strerror(errno)); + } else { + if (!quiet) + printf("was successful\n"); + } } return 0; -- cgit From c37be1ab2480c43fdaec098f75ec5e25a65ceb59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 13:01:42 +0000 Subject: Make more parts optional --- tools/Makefile.am | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index ca0514ce..79871391 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,7 +2,20 @@ # $Id$ # -sbin_PROGRAMS = hciattach hciconfig hid2hci +manfiles = hid2hci.8 + +if HID2HCI +xbindir = $(sbindir) +xmandir = $(mandir) + +xbin_PROGRAMS = hid2hci + +hid2hci_LDADD = @USB_LIBS@ + +xman_MANS = $(manfiles) +endif + +sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping sdptool ciptool @@ -22,12 +35,10 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -hid2hci_LDADD = @USB_LIBS@ - AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ -man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 -EXTRA_DIST = $(man_MANS) +EXTRA_DIST = $(man_MANS) $(manfiles) MAINTAINERCLEANFILES = Makefile.in -- cgit From 8474a2bd7c42eb2a9df05797d83ed724fb5108a9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 13:58:40 +0000 Subject: Don't forget the hid2hci manpage --- tools/Makefile.am | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 79871391..086f521e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,17 +2,16 @@ # $Id$ # -manfiles = hid2hci.8 - if HID2HCI xbindir = $(sbindir) -xmandir = $(mandir) xbin_PROGRAMS = hid2hci hid2hci_LDADD = @USB_LIBS@ -xman_MANS = $(manfiles) +hid2hci_manfiles = hid2hci.8 +else +hid2hci_manfiles = endif sbin_PROGRAMS = hciattach hciconfig @@ -37,8 +36,8 @@ ppporc_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 $(hid2hci_manfiles) -EXTRA_DIST = $(man_MANS) $(manfiles) +EXTRA_DIST = $(man_MANS) hid2hci.8 MAINTAINERCLEANFILES = Makefile.in -- cgit From 48c6c4bd7bef34ccac611f7f01c7d3725b40b1c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 16:43:40 +0000 Subject: Check for AVM BlueFRITZ! USB v2.0 --- tools/hciconfig.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index d7b7513a..78c56ce7 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1003,9 +1003,12 @@ static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) printf("\tFirmware %d.%d.%03d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); } -static void print_rev_avm(uint16_t rev) +static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver) { - printf("\tFirmware 03.%d.%d\n", rev >> 8, rev & 0xff); + if (lmp_subver == 0x01) + printf("\tFirmware 03.%d.%d\n", hci_rev >> 8, hci_rev & 0xff); + else + printf("\tUnknown type\n"); } static void cmd_revision(int ctl, int hdev, char *opt) @@ -1038,7 +1041,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_rev_broadcom(ver.hci_rev, ver.lmp_subver); break; case 31: - print_rev_avm(ver.hci_rev); + print_rev_avm(ver.hci_rev, ver.lmp_subver); break; default: printf("\tUnsupported manufacturer\n"); -- cgit From 8d8392b6c6b12f3aa5a1c2efa025d01a9f44a6ff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Jul 2004 17:45:58 +0000 Subject: Rewrite the hid2hci check --- tools/Makefile.am | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 086f521e..6470a8a9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -3,18 +3,14 @@ # if HID2HCI -xbindir = $(sbindir) - -xbin_PROGRAMS = hid2hci - -hid2hci_LDADD = @USB_LIBS@ - +hid2hci_programs = hid2hci hid2hci_manfiles = hid2hci.8 else +hid2hci_programs = hid2hci_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig +sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool @@ -34,10 +30,14 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ +if HID2HCI +hid2hci_LDADD = @USB_LIBS@ +endif + AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 $(hid2hci_manfiles) -EXTRA_DIST = $(man_MANS) hid2hci.8 +EXTRA_DIST = $(man_MANS) hid2hci.8 hid2hci.c MAINTAINERCLEANFILES = Makefile.in -- cgit From 750ac6d869c3b4bd94ecdb6dce9c16265326b954 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Aug 2004 13:17:11 +0000 Subject: Check for usb_get_busses() and usb_interrupt_read() --- tools/hid2hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 6b2aec72..c800c7ee 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -40,8 +40,8 @@ #include -#ifndef usb_get_busses -struct usb_bus *usb_get_busses(void) +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) { return usb_busses; } -- cgit From 5c8acb2c0dabd7fe0c8397d97c140d78b7bd8cd7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Aug 2004 10:10:13 +0000 Subject: Don't include asm/types.h --- tools/hciattach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 2024c1de..b3f40b3a 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include -- cgit From 4a5bc48ff3c2a2f3acdacc6fc6ee2632687455e7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Aug 2004 10:11:10 +0000 Subject: Don't include asm/types.h and asm/byteorder.h --- tools/l2ping.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/l2ping.c b/tools/l2ping.c index 85d12eee..af056bc6 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -51,9 +51,6 @@ #include #include -#include -#include - #include #include @@ -134,7 +131,7 @@ static void ping(char *svr) /* Build command header */ cmd->code = L2CAP_ECHO_REQ; cmd->ident = id; - cmd->len = __cpu_to_le16(size); + cmd->len = htobs(size); gettimeofday(&tv_send, NULL); @@ -171,7 +168,7 @@ static void ping(char *svr) exit(1); } - cmd->len = __le16_to_cpu(cmd->len); + cmd->len = btohs(cmd->len); /* Check for our id */ if( cmd->ident != id ) -- cgit From e7989c831f54770196b92d24d78f80d5c5161352 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Aug 2004 11:22:22 +0000 Subject: Let the id display start with 0 even if internal it start with 200 --- tools/l2ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/l2ping.c b/tools/l2ping.c index af056bc6..1f3f3a41 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -191,7 +191,7 @@ static void ping(char *svr) gettimeofday(&tv_recv, NULL); timersub(&tv_recv, &tv_send, &tv_diff); - printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id, tv2fl(tv_diff)); + printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id - ident, tv2fl(tv_diff)); if (delay) sleep(delay); } else { -- cgit From ca8d9c9f9ac9b20b33bde4c1407ce80f44b814ec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 20 Sep 2004 15:51:15 +0000 Subject: Mention flow|noflow in help text and other speeds --- tools/hciattach.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index b3f40b3a..a22a0b1d 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -84,12 +84,18 @@ static int uart_speed(int s) return B230400; case 460800: return B460800; + case 500000: + return B500000; + case 576000: + return B576000; case 921600: return B921600; case 1000000: return B1000000; case 1152000: return B1152000; + case 1500000: + return B1500000; default: return B57600; } @@ -932,7 +938,7 @@ static void usage(void) { printf("hciattach - HCI UART driver initialization utility\n"); printf("Usage:\n"); - printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow]\n"); + printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow|noflow]\n"); printf("\thciattach -l\n"); } -- cgit From 6153da844acccec9519301e3e15743643c096e09 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 1 Oct 2004 11:38:41 +0000 Subject: Fix class display and some compile warnings for 64 bit userland --- tools/hciconfig.c | 26 +++++++++++++------------- tools/sdptool.c | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 78c56ce7..862deeb9 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -397,10 +397,10 @@ void cmd_name(int ctl, int hdev, char *opt) */ static char *get_minor_device_name(int major, int minor) { - switch(major) { - case 0:/* misc */ + switch (major) { + case 0: /* misc */ return ""; - case 1:/* computer */ + case 1: /* computer */ switch(minor) { case 0: return "Uncategorized"; @@ -418,7 +418,7 @@ static char *get_minor_device_name(int major, int minor) return "Wearable"; } break; - case 2:/* phone */ + case 2: /* phone */ switch(minor) { case 0: return "Uncategorized"; @@ -436,7 +436,7 @@ static char *get_minor_device_name(int major, int minor) return "Sim Card Reader"; } break; - case 3:/* lan access */ + case 3: /* lan access */ if (minor == 0) return "Uncategorized"; switch(minor / 8) { @@ -458,7 +458,7 @@ static char *get_minor_device_name(int major, int minor) return "No service available"; } break; - case 4:/* audio/video */ + case 4: /* audio/video */ switch(minor) { case 0: return "Uncategorized"; @@ -498,7 +498,7 @@ static char *get_minor_device_name(int major, int minor) return "Gaming/Toy"; } break; - case 5:/* peripheral */ + case 5: /* peripheral */ switch(minor) { case 16: return "Keyboard"; @@ -508,7 +508,7 @@ static char *get_minor_device_name(int major, int minor) return "Combo keyboard/pointing device"; } break; - case 6:/* imaging */ + case 6: /* imaging */ if (minor & 4) return "Display"; if (minor & 8) @@ -518,7 +518,7 @@ static char *get_minor_device_name(int major, int minor) if (minor & 32) return "Printer"; break; - case 63:/* uncategorised */ + case 63: /* uncategorised */ return ""; } return "Unknown (reserved) minor device class"; @@ -550,14 +550,14 @@ void cmd_class(int ctl, int hdev, char *opt) } if (opt) { uint32_t cod = strtoul(opt, NULL, 16); - if (0 > hci_write_class_of_dev(s, cod, 1000)) { + if (hci_write_class_of_dev(s, cod, 1000) < 0) { printf("Can't write local class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { uint8_t cls[3]; - if (0 > hci_read_class_of_dev(s, cls, 1000)) { + if (hci_read_class_of_dev(s, cls, 1000) < 0) { printf("Can't read class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); @@ -567,7 +567,7 @@ void cmd_class(int ctl, int hdev, char *opt) printf("\tService Classes: "); if (cls[2]) { int first = 1; - for(s=0; s < sizeof(services); s++) + for (s = 0; s < sizeof(*services); s++) if (cls[2] & (1 << s)) { if (!first) printf(", "); @@ -577,7 +577,7 @@ void cmd_class(int ctl, int hdev, char *opt) } else printf("Unspecified"); printf("\n\tDevice Class: "); - if ((cls[1] & 0x1f) > sizeof(major_devices)) + if ((cls[1] & 0x1f) > sizeof(*major_devices)) printf("Invalid Device Class!\n"); else printf("%s, %s\n", major_devices[cls[1] & 0x1f], diff --git a/tools/sdptool.c b/tools/sdptool.c index 4f89491d..99684d9c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -813,7 +813,7 @@ void print_lang_attr(void *value, void *user) printf(" base_offset: 0x%02x\n", lang->base_offset); } -void print_access_protos(value, userData) +void print_access_protos(void *value, void *userData) { sdp_list_t *protDescSeq = (sdp_list_t *)value; sdp_list_foreach(protDescSeq, print_service_desc, 0); -- cgit From 70bc373b28975204b08974d45213e5772a07a41e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Oct 2004 09:52:09 +0000 Subject: Add support for the Zoom PCMCIA card --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index a22a0b1d..d59992e1 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -842,6 +842,9 @@ struct uart_t uart[] = { /* AmbiCom BT2000C Bluetooth PC/CF Card */ { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, + /* Zoom Bluetooth PCMCIA Card */ + { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { NULL, 0 } }; -- cgit From b089fd9850e50bb0a75dacfb665ec1e85aaa30b4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Oct 2004 10:31:33 +0000 Subject: Add timeout option --- tools/l2ping.1 | 9 ++++++++- tools/l2ping.c | 27 +++++++++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/l2ping.1 b/tools/l2ping.1 index 186e5056..0c7da44b 100644 --- a/tools/l2ping.1 +++ b/tools/l2ping.1 @@ -10,6 +10,8 @@ l2ping \- Send L2CAP echo request and receive answer ] [ .I -c count ] [ +.I -t timeout +] [ .I -f ] < .I bd_addr @@ -34,6 +36,11 @@ Send .B count number of packets then exit. .TP +.I -c timeout +Wait +.B timeout +for the response. +.TP .I -f Kind of flood ping. Use with care! It reduces the delay time between packets to 0. @@ -44,6 +51,6 @@ The Bluetooth MAC address to be pinged in dotted hex notation like or .B 01:EF:cd:aB:02:03 .SH AUTHORS -Written by Maxim Krasnyansky +Written by Maxim Krasnyansky and Marcel Holtmann .PP man page by Nils Faerber diff --git a/tools/l2ping.c b/tools/l2ping.c index 1f3f3a41..45ddbe92 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -56,10 +56,11 @@ /* Defaults */ bdaddr_t bdaddr; -int size = 20; -int ident = 200; -int delay = 1; -int count = -1; +int size = 20; +int ident = 200; +int delay = 1; +int count = -1; +int timeout = 10; /* Stats */ int sent_pkt = 0, recv_pkt = 0; @@ -120,7 +121,7 @@ static void ping(char *svr) /* Initialize buffer */ for (i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) - buf[i]=(i%40)+'A'; + buf[i] = (i % 40) + 'A'; id = ident; @@ -148,7 +149,7 @@ static void ping(char *svr) register int err; pf[0].fd = s; pf[0].events = POLLIN; - if ((err = poll(pf, 1, 10*1000)) < 0) { + if ((err = poll(pf, 1, timeout * 1000)) < 0) { perror("Poll failed"); exit(1); } @@ -193,12 +194,14 @@ static void ping(char *svr) printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id - ident, tv2fl(tv_diff)); - if (delay) sleep(delay); + if (delay) + sleep(delay); } else { printf("no response from %s: id %d\n", svr, id); } - if (++id > 254) id = ident; + if (++id > 254) + id = ident; } stat(0); } @@ -207,7 +210,7 @@ static void usage(void) { printf("l2ping - L2CAP ping\n"); printf("Usage:\n"); - printf("\tl2ping [-S source addr] [-s size] [-c count] [-f] \n"); + printf("\tl2ping [-S source addr] [-s size] [-c count] [-t timeout] [-f] \n"); } extern int optind,opterr,optopt; @@ -220,7 +223,7 @@ int main(int argc, char *argv[]) /* Default options */ bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"s:c:fS:")) != EOF) { + while ((opt=getopt(argc,argv,"s:c:t:fS:")) != EOF) { switch(opt) { case 'f': /* Kinda flood ping */ @@ -231,6 +234,10 @@ int main(int argc, char *argv[]) count = atoi(optarg); break; + case 't': + timeout = atoi(optarg); + break; + case 's': size = atoi(optarg); break; -- cgit From 3aa6a3e9a775e1d143d3640fe7f3ced170bb71b9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Oct 2004 13:59:57 +0000 Subject: Sleep some time after sending break --- tools/hciattach.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index d59992e1..ac94c41e 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -908,8 +908,10 @@ int init_uart(char *dev, struct uart_t *u, int send_break) tcflush(fd, TCIOFLUSH); - if (send_break) + if (send_break) { tcsendbreak(fd, 0); + usleep(500000); + } if (u->init && u->init(fd, u, &ti) < 0) return -1; -- cgit From 1dd606979d87e4d725df282fdb00669fb8a76d1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 13 Oct 2004 12:05:52 +0000 Subject: Add support for SIM Access Profile --- tools/sdptool.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 99684d9c..025ab0da 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -254,6 +254,7 @@ static struct uuid_def uuid16_names[] = { { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, + { 0x112d, "SIM Access (SAP)", NULL, 0 }, /* ... */ { 0x1200, "PnPInformation", NULL, 0 }, { 0x1201, "GenericNetworking", NULL, 0 }, @@ -1154,7 +1155,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); - sdp_set_info_attr(&record, "", 0, 0); + sdp_set_info_attr(&record, "Handsfree", 0, 0); if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { printf("Service Record registration failed\n"); @@ -1171,6 +1172,67 @@ end: return ret; } +static int add_simaccess(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 3; + uint16_t u16 = 0x31; + sdp_data_t *channel, *features; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, SAP_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_TELEPHONY_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID); + profile.version = 0x0101; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + features = sdp_data_alloc(SDP_UINT16, &u16); + sdp_attr_add(&record, SDP_SUPPORTED_FEATURES, features); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "SIM Access", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Handsfree service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} static int add_fax(sdp_session_t *session, svc_info_t *si) { @@ -1695,6 +1757,7 @@ struct { { "HS", HEADSET_SVCLASS_ID, add_headset }, { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, + { "SAP", SAP_SVCLASS_ID, add_simaccess }, { "NAP", NAP_SVCLASS_ID, add_nap }, { "GN", GN_SVCLASS_ID, add_gn }, -- cgit From b3f9653837d74d6866c90114e52d9d4c024d6423 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Oct 2004 05:51:25 +0000 Subject: Wait some time before calling disconnect --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index df33412f..089ca103 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -477,8 +477,10 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } - if (cc) + if (cc) { + usleep(10000); hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } close(dd); } -- cgit From e0a9a33079d4ae64c6553e02f5da4f5a039c372f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 05:44:23 +0000 Subject: Display revision information for Digianswer devices --- tools/hciconfig.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 862deeb9..9405de08 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -959,7 +959,7 @@ static void print_rev_ericsson(int dd) unsigned char buf[102]; memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; + rq.ogf = OGF_VENDOR_CMD; rq.ocf = 0x000f; rq.cparam = NULL; rq.clen = 0; @@ -967,7 +967,7 @@ static void print_rev_ericsson(int dd) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\n Can't read revision info. %s(%d)\n", strerror(errno), errno); + printf("\nCan't read revision info. %s(%d)\n", strerror(errno), errno); return; } @@ -998,6 +998,28 @@ static void print_rev_csr(int dd, uint16_t rev) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); } +static void print_rev_digianswer(int dd) +{ + struct hci_request rq; + unsigned char req[] = { 0x07 }; + unsigned char buf[102]; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x000e; + rq.cparam = req; + rq.clen = sizeof(req); + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\nCan't read revision info. %s(%d)\n", strerror(errno), errno); + return; + } + + printf("\t%s\n", buf + 1); +} + static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) { printf("\tFirmware %d.%d.%03d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); @@ -1037,6 +1059,9 @@ static void cmd_revision(int ctl, int hdev, char *opt) case 10: print_rev_csr(dd, ver.hci_rev); break; + case 12: + print_rev_digianswer(dd); + break; case 15: print_rev_broadcom(ver.hci_rev, ver.lmp_subver); break; -- cgit From 7e08a09c87660616b173f338aff9baf3f7b61f5d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 07:20:17 +0000 Subject: Use Bluetooth library functions --- tools/hcitool.c | 67 +++++++++++---------------------------------------------- 1 file changed, 13 insertions(+), 54 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 089ca103..7cb807ec 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -732,7 +732,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 100) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) perror("Disconnect failed"); close(dd); @@ -752,9 +752,8 @@ static char *sr_help = static void cmd_sr(int dev_id, int argc, char **argv) { - struct hci_request rq; - switch_role_cp cp; - evt_role_change rp; + bdaddr_t bdaddr; + uint8_t role; int opt, dd; for_each_opt(opt, sr_options, NULL) { @@ -772,21 +771,21 @@ static void cmd_sr(int dev_id, int argc, char **argv) return; } - str2ba(argv[0], &cp.bdaddr); + str2ba(argv[0], &bdaddr); switch (argv[1][0]) { case 'm': - cp.role = 0; + role = 0; break; case 's': - cp.role = 1; + role = 1; break; default: - cp.role = atoi(argv[1]); + role = atoi(argv[1]); break; } if (dev_id < 0) { - dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &cp.bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -799,25 +798,11 @@ static void cmd_sr(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_POLICY; - rq.ocf = OCF_SWITCH_ROLE; - rq.cparam = &cp; - rq.clen = SWITCH_ROLE_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_ROLE_CHANGE_SIZE; - rq.event = EVT_ROLE_CHANGE; - - if (hci_send_req(dd, &rq, 300) < 0) { + if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) { perror("Switch role request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "Switch role cmd failed (0x%2.2X)\n", rp.status); - exit(1); - } - close(dd); } @@ -1388,9 +1373,6 @@ static char *auth_help = static void cmd_auth(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - auth_requested_cp cp; - evt_auth_complete rp; bdaddr_t bdaddr; int opt, dd; @@ -1436,18 +1418,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) exit(1); } - cp.handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_AUTH_REQUESTED; - rq.cparam = &cp; - rq.clen = AUTH_REQUESTED_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_AUTH_COMPLETE_SIZE; - rq.event = EVT_AUTH_COMPLETE; - - if (hci_send_req(dd, &rq, 25000) < 0) { + if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) { perror("HCI authentication request failed"); exit(1); } @@ -1470,10 +1441,8 @@ static char *enc_help = static void cmd_enc(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - set_conn_encrypt_cp cp; - evt_encrypt_change rp; bdaddr_t bdaddr; + uint8_t encrypt; int opt, dd; for_each_opt(opt, enc_options, NULL) { @@ -1518,19 +1487,9 @@ static void cmd_enc(int dev_id, int argc, char **argv) exit(1); } - cp.handle = htobs(cr->conn_info->handle); - cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_ENCRYPT; - rq.cparam = &cp; - rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; + encrypt = (argc > 1) ? atoi(argv[1]) : 1; - if (hci_send_req(dd, &rq, 25000) < 0) { + if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) { perror("HCI set encryption request failed"); exit(1); } -- cgit From 4e37d72b4562ffbfc3e73ef5d9bf0b722e841ab1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 07:37:55 +0000 Subject: Use the library functions for reading and writing the inquiry mode --- tools/hciconfig.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 9405de08..797cb775 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -666,42 +666,25 @@ void cmd_inq_mode(int ctl, int hdev, char *opt) memset(&rq, 0, sizeof(rq)); if (opt) { - write_inquiry_mode_cp cp; + uint8_t mode = atoi(opt); - cp.mode = atoi(opt); - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_INQUIRY_MODE; - rq.cparam = &cp; - rq.clen = WRITE_INQUIRY_MODE_RP_SIZE; - - if (hci_send_req(dd, &rq, 1000) < 0) { + if (hci_write_inquiry_mode(dd, mode, 1000) < 0) { printf("Can't set inquiry mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { - read_inquiry_mode_rp rp; - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_INQUIRY_MODE; - rq.rparam = &rp; - rq.rlen = READ_INQUIRY_MODE_RP_SIZE; + uint8_t mode; - if (hci_send_req(dd, &rq, 1000) < 0) { + if (hci_read_inquiry_mode(dd, &mode, 1000) < 0) { printf("Can't read inquiry mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - if (rp.status) { - printf("Read inquiry mode on hci%d returned status %d\n", - hdev, rp.status); - exit(1); - } print_dev_hdr(&di); printf("\tInquiry mode: %s\n", - rp.mode == 1 ? "Inquiry with RSSI" : "Standard Inquiry"); + mode == 1 ? "Inquiry with RSSI" : "Standard Inquiry"); } } -- cgit From 8831229d721edddb91548d86420a013f5b44b57f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 08:34:08 +0000 Subject: Support for enabling the kernel security manager --- tools/hciconfig.8 | 42 ++++++++++++++++++++++++------------------ tools/hciconfig.c | 28 +++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 3c6c96d8..5340978d 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -25,7 +25,7 @@ encryption enabled). .SH OPTIONS .TP .BI -h -Gives a list of possible commands +Gives a list of possible commands. .TP .BI -a Other than the basic info, print features, packet type, link policy, link mode, @@ -33,40 +33,46 @@ name, class, version. .SH COMMANDS .TP .BI up -Open and initialize HCI device +Open and initialize HCI device. .TP .BI down -Close HCI device +Close HCI device. .TP .BI reset -Reset HCI device +Reset HCI device. .TP .BI rstat -Reset statistic counters +Reset statistic counters. .TP .BI auth -Enable authentication +Enable authentication (sets device to security mode 3). .TP .BI noauth -Disable authentication +Disable authentication. .TP .BI encrypt -Enable encryption +Enable encryption (sets device to security mode 3). .TP .BI noencrypt -Disable encryption +Disable encryption. +.TP +.BI secmgr +Enable security manager (current kernel support is limited). +.TP +.BI nosecmgr +Disable security manager. .TP .BI piscan -Enable page and inquiry scan +Enable page and inquiry scan. .TP .BI noscan -Disable page and inquiry scan +Disable page and inquiry scan. .TP .BI iscan -Enable inquiry scan, disable page scan +Enable inquiry scan, disable page scan. .TP .BI pscan -Enable page scan, disable inquiry scan +Enable page scan, disable inquiry scan. .TP .BI ptype " [type]" With no @@ -182,13 +188,13 @@ bytes and SCO buffer size to packets. .TP .BI features -Display device features +Display device features. .TP .BI version -Display version information +Display version information. .TP .BI revision -Display revision information +Display revision information. .TP .BI lm " [mode]" With no @@ -232,8 +238,8 @@ ACCEPT is present, the device will accept baseband connections even when there are no listening .I AF_BLUETOOTH -sockets +sockets. .SH AUTHORS -Written by Maxim Krasnyansky +Written by Maxim Krasnyansky and Marcel Holtmann .PP man page by Fabrizio Gennari diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 797cb775..0e591e8d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -198,12 +198,12 @@ void cmd_auth(int ctl, int hdev, char *opt) struct hci_dev_req dr; dr.dev_id = hdev; - if( !strcmp(opt, "auth") ) + if (!strcmp(opt, "auth")) dr.dev_opt = AUTH_ENABLED; else dr.dev_opt = AUTH_DISABLED; - if( ioctl(ctl, HCISETAUTH, (unsigned long)&dr) < 0 ) { + if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) { printf("Can't set auth on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -214,17 +214,33 @@ void cmd_encrypt(int ctl, int hdev, char *opt) struct hci_dev_req dr; dr.dev_id = hdev; - if( !strcmp(opt, "encrypt") ) + if (!strcmp(opt, "encrypt")) dr.dev_opt = ENCRYPT_P2P; else dr.dev_opt = ENCRYPT_DISABLED; - if( ioctl(ctl, HCISETENCRYPT, (unsigned long)&dr) < 0 ) { + if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) { printf("Can't set encrypt on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } +void cmd_secmgr(int ctl, int hdev, char *opt) +{ + int val, s = hci_open_dev(hdev); + + if (!strcmp(opt, "secmgr")) + val = 1; + else + val = 0; + + if (ioctl(s, HCISETSECMGR, val) < 0) { + printf("Can't set security manager on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + close(s); +} + void cmd_up(int ctl, int hdev, char *opt) { int ret; @@ -236,7 +252,7 @@ void cmd_up(int ctl, int hdev, char *opt) printf("Can't init device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - cmd_scan(ctl, hdev, "piscan"); + cmd_scan(ctl, hdev, "piscan"); } void cmd_down(int ctl, int hdev, char *opt) @@ -1119,6 +1135,8 @@ struct { { "noauth", cmd_auth, 0, "Disable Authentication" }, { "encrypt", cmd_encrypt, 0, "Enable Encryption" }, { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, + { "secmgr", cmd_secmgr, 0, "Enable Security Manager" }, + { "nosecmgr", cmd_secmgr, 0, "Disable Security Manager" }, { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, { "noscan", cmd_scan, 0, "Disable scan" }, { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, -- cgit From 9e05169423054722af54ca7e93261c2c8c694e3d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 26 Oct 2004 02:21:16 +0000 Subject: Add more audio/video profile translations --- tools/sdptool.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 025ab0da..c63750c4 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -226,8 +226,12 @@ static struct uuid_def uuid16_names[] = { { 0x1108, "Headset", audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, { 0x1109, "CordlessTelephony", NULL, 0 }, - /* ... */ - { 0x110F, "VideoConferencing", NULL, 0 }, + { 0x110a, "AudioSource", NULL, 0 }, + { 0x110b, "AudioSink", NULL, 0 }, + { 0x110c, "RemoteControlTarget", NULL, 0 }, + { 0x110d, "AdvancedAudio", NULL, 0 }, + { 0x110e, "RemoteControl", NULL, 0 }, + { 0x110f, "VideoConferencing", NULL, 0 }, { 0x1110, "Intercom", NULL, 0 }, { 0x1111, "Fax", NULL, 0 }, { 0x1112, "HeadsetAudioGateway", NULL, 0 }, -- cgit From 1c111444bad2e4f0d66874a9032e43f91cb6cc3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Nov 2004 11:18:50 +0000 Subject: Some whitespace cleanup --- tools/hcitool.c | 102 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 47 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 7cb807ec..6c41483b 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -65,7 +65,7 @@ static int dev_info(int s, int dev_id, long arg) struct hci_dev_info di = {dev_id: dev_id}; char addr[18]; - if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void *) &di)) return 0; ba2str(&di.bdaddr, addr); @@ -91,12 +91,12 @@ static int conn_list(int s, int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { perror("Can't get connection list"); exit(1); } - for (i=0; i < cl->conn_num; i++, ci++) { + for (i = 0; i < cl->conn_num; i++, ci++) { char addr[18]; ba2str(&ci->bdaddr, addr); printf("\t%s %s %s handle %d state %d lm %s\n", @@ -105,6 +105,7 @@ static int conn_list(int s, int dev_id, long arg) addr, ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } + return 0; } @@ -122,14 +123,15 @@ static int find_conn(int s, int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { perror("Can't get connection list"); exit(1); } - for (i=0; i < cl->conn_num; i++, ci++) - if (!bacmp((bdaddr_t *)arg, &ci->bdaddr)) + for (i = 0; i < cl->conn_num; i++, ci++) + if (!bacmp((bdaddr_t *) arg, &ci->bdaddr)) return 1; + return 0; } @@ -137,7 +139,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) { register int i,n; - for (i=0, n=1; ibdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -466,15 +469,18 @@ static void cmd_info(int dev_id, int argc, char **argv) if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" "\tManufacturer: %s (%d)\n", - lmp_vertostr(version.lmp_ver), version.lmp_ver, version.lmp_subver, - bt_compidtostr(version.manufacturer), version.manufacturer); + lmp_vertostr(version.lmp_ver), + version.lmp_ver, + version.lmp_subver, + bt_compidtostr(version.manufacturer), + version.manufacturer); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", - features[0], features[1], features[2], features[3], - features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 63)); + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7], + lmp_featurestostr(features, "\t\t", 63)); } if (cc) { @@ -508,7 +514,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) uint8_t ogf; for_each_opt(opt, cmd_options, NULL) { - switch(opt) { + switch (opt) { default: printf(cmd_help); return; @@ -573,7 +579,6 @@ static void cmd_cmd(int dev_id, int argc, char **argv) hex_dump(" ", 20, ptr, len); fflush(stdout); hci_close_dev(dd); - return; } /* Display active connections */ @@ -592,7 +597,7 @@ static void cmd_con(int dev_id, int argc, char **argv) int opt; for_each_opt(opt, con_options, NULL) { - switch(opt) { + switch (opt) { default: printf(con_help); return; @@ -630,7 +635,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; for_each_opt(opt, cc_options, NULL) { - switch(opt) { + switch (opt) { case 'p': hci_strtoptype(optarg, &ptype); break; @@ -668,7 +673,8 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 25000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), + 0, role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } @@ -691,7 +697,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, dc_options, NULL) { - switch(opt) { + switch (opt) { default: printf(dc_help); return; @@ -732,7 +738,8 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), + HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) perror("Disconnect failed"); close(dd); @@ -757,7 +764,7 @@ static void cmd_sr(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, sr_options, NULL) { - switch(opt) { + switch (opt) { default: printf(sr_help); return; @@ -827,7 +834,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, rssi_options, NULL) { - switch(opt) { + switch (opt) { default: printf(rssi_help); return; @@ -884,7 +891,8 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } if (rp.status) { - printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); + printf("Read RSSI returned (error) status 0x%2.2X\n", + rp.status); exit(1); } printf("RSSI return value: %d\n", rp.rssi); @@ -914,7 +922,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, lq_options, NULL) { - switch(opt) { + switch (opt) { default: printf(lq_help); return; @@ -971,7 +979,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) } if (rp.status) { - fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", + fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", rp.status); exit(1); } @@ -1002,7 +1010,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, tpl_options, NULL) { - switch(opt) { + switch (opt) { default: printf(tpl_help); return; @@ -1091,7 +1099,7 @@ static void cmd_afh(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, afh_options, NULL) { - switch(opt) { + switch (opt) { default: printf(afh_help); return; @@ -1148,7 +1156,7 @@ static void cmd_afh(int dev_id, int argc, char **argv) } if (rp.status) { - fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", + fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", rp.status); exit(1); } @@ -1187,7 +1195,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) int opt, dd, ptype; for_each_opt(opt, cpt_options, NULL) { - switch(opt) { + switch (opt) { default: printf(cpt_help); return; @@ -1272,7 +1280,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, lst_options, NULL) { - switch(opt) { + switch (opt) { default: printf(lst_help); return; @@ -1377,7 +1385,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, auth_options, NULL) { - switch(opt) { + switch (opt) { default: printf(auth_help); return; @@ -1446,7 +1454,7 @@ static void cmd_enc(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, enc_options, NULL) { - switch(opt) { + switch (opt) { default: printf(enc_help); return; @@ -1535,7 +1543,7 @@ static void usage(void) "\t--help\tDisplay help\n" "\t-i dev\tHCI device\n"); printf("Commands:\n"); - for (i=0; command[i].cmd; i++) + for (i = 0; command[i].cmd; i++) printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); printf("\n" @@ -1544,8 +1552,8 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, + {"help", 0,0, 'h'}, + {"device", 1,0, 'i'}, {0, 0, 0, 0} }; @@ -1555,7 +1563,7 @@ int main(int argc, char **argv) bdaddr_t ba; while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { - switch(opt) { + switch (opt) { case 'i': dev_id = hci_devid(optarg); if (dev_id < 0) { @@ -1585,7 +1593,7 @@ int main(int argc, char **argv) exit(1); } - for (i=0; command[i].cmd; i++) { + for (i = 0; command[i].cmd; i++) { if (strncmp(command[i].cmd, argv[0], 3)) continue; command[i].func(dev_id, argc, argv); -- cgit From 5327e84a4c0f07e44d8c3b23410c355465b094e5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Nov 2004 11:23:01 +0000 Subject: Add support for changing the link key of a connection --- tools/hcitool.1 | 6 ++++- tools/hcitool.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index 1d87b9a0..c4c69b87 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -166,7 +166,11 @@ Request authentication for the device with Bluetooth address .BI enc " [encrypt enable]" Enable or disable the encryption for the device with Bluetooth address .IR bdaddr . +.TP +.BI key " " +Change the connection link key for the device with Bluetooth address +.IR bdaddr . .SH AUTHORS -Written by Maxim Krasnyansky +Written by Maxim Krasnyansky and Marcel Holtmann .PP man page by Fabrizio Gennari diff --git a/tools/hcitool.c b/tools/hcitool.c index 6c41483b..4ecead2f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1506,6 +1506,74 @@ static void cmd_enc(int dev_id, int argc, char **argv) free(cr); } +/* Change connection link key */ + +static struct option key_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *key_help = + "Usage:\n" + "\tkey \n"; + +static void cmd_key(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, key_options, NULL) { + switch (opt) { + default: + printf(key_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(key_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_change_link_key(dd, htobs(cr->conn_info->handle), 25000) < 0) { + perror("Changing link key failed"); + exit(1); + } + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1529,6 +1597,7 @@ static struct { { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, + { "key", cmd_key, "Change connection link key" }, { NULL, NULL, 0 } }; -- cgit From 1fc62ff85f185eae7f2297648fc9a2846fcb284d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 22:55:42 +0000 Subject: Use the new AFH functions --- tools/hciconfig.c | 33 +++++---------------------------- tools/hcitool.c | 23 ++++------------------- 2 files changed, 9 insertions(+), 47 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 0e591e8d..854c8715 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -670,7 +670,6 @@ void cmd_version(int ctl, int hdev, char *opt) void cmd_inq_mode(int ctl, int hdev, char *opt) { - struct hci_request rq; int dd; dd = hci_open_dev(hdev); @@ -679,8 +678,6 @@ void cmd_inq_mode(int ctl, int hdev, char *opt) exit(1); } - memset(&rq, 0, sizeof(rq)); - if (opt) { uint8_t mode = atoi(opt); @@ -902,7 +899,6 @@ void cmd_page_to(int ctl, int hdev, char *opt) void cmd_afh_mode(int ctl, int hdev, char *opt) { - struct hci_request rq; int dd; dd = hci_open_dev(hdev); @@ -911,44 +907,25 @@ void cmd_afh_mode(int ctl, int hdev, char *opt) exit(1); } - memset(&rq, 0, sizeof(rq)); - if (opt) { - write_afh_mode_cp cp; - - cp.mode = atoi(opt); - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_AFH_MODE; - rq.cparam = &cp; - rq.clen = WRITE_AFH_MODE_RP_SIZE; + uint8_t mode = atoi(opt); - if (hci_send_req(dd, &rq, 1000) < 0) { + if (hci_write_afh_mode(dd, mode, 1000) < 0) { printf("Can't set AFH mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { - read_afh_mode_rp rp; - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_AFH_MODE; - rq.rparam = &rp; - rq.rlen = READ_AFH_MODE_RP_SIZE; + uint8_t mode; - if (hci_send_req(dd, &rq, 1000) < 0) { + if (hci_read_afh_mode(dd, &mode, 1000) < 0) { printf("Can't read AFH mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - if (rp.status) { - printf("Read AFH mode on hci%d returned status %d\n", - hdev, rp.status); - exit(1); - } print_dev_hdr(&di); - printf("\tAFH mode: %s\n", rp.mode == 1 ? "Enabled" : "Disabled"); + printf("\tAFH mode: %s\n", mode == 1 ? "Enabled" : "Disabled"); } } diff --git a/tools/hcitool.c b/tools/hcitool.c index 4ecead2f..8bb68427 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1092,10 +1092,9 @@ static char *afh_help = static void cmd_afh(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_afh_map_rp rp; bdaddr_t bdaddr; uint16_t handle; + uint8_t mode, map[10]; int opt, dd; for_each_opt(opt, afh_options, NULL) { @@ -1142,30 +1141,16 @@ static void cmd_afh(int dev_id, int argc, char **argv) handle = htobs(cr->conn_info->handle); - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_AFH_MAP; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_AFH_MAP_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_afh_map(dd, handle, &mode, map, 1000) < 0) { perror("HCI read AFH map request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } - - if (rp.mode == 0x01) { + if (mode == 0x01) { int i; printf("AFH map: 0x"); for (i = 0; i < 10; i++) - printf("%02x", rp.map[i]); + printf("%02x", map[i]); printf("\n"); } else printf("AFH disabled\n"); -- cgit From e0cbfd7cc76db2b084c1218408e71838d3c4e3b0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Nov 2004 14:43:56 +0000 Subject: Add HCI 18.3 firmware build ids --- tools/csr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 6d9185e1..d5737fd9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -246,6 +246,10 @@ static struct { { 1169, "HCI 18.1" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, + { 1733, "HCI 18.3" }, + { 1734, "HCI 18.3" }, + { 1735, "HCI 18.3" }, + { 1737, "HCI 18.3" }, { 0, } }; -- cgit From 16a857ba91612b9350062f233fcfb007bcd3f7c2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 18 Nov 2004 07:46:44 +0000 Subject: More build ids for HCI 18.2 and the BlueCore3-Multimedia --- tools/csr.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index d5737fd9..b085b869 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -246,6 +246,14 @@ static struct { { 1169, "HCI 18.1" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, + { 1501, "HCI 18.2" }, + { 1503, "HCI 18.2" }, + { 1504, "HCI 18.2" }, + { 1505, "HCI 18.2" }, + { 1506, "HCI 18.2" }, + { 1520, "HCI 18.2" }, + { 1591, "HCI 18.2" }, + { 1592, "HCI 18.2" }, { 1733, "HCI 18.3" }, { 1734, "HCI 18.3" }, { 1735, "HCI 18.3" }, -- cgit From 27bcb4ea2983a5ee437704dece36067653b7c22e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 18 Nov 2004 07:53:06 +0000 Subject: Add build ids for BlueCore3-ROM --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index b085b869..143fcca0 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -242,8 +242,10 @@ static struct { { 856, "HCI 17.3.2" }, { 857, "HCI 17.3.2" }, { 858, "HCI 17.3.2" }, + { 1120, "HCI 17.11" }, { 1168, "HCI 18.1" }, { 1169, "HCI 18.1" }, + { 1298, "HCI 18.2" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, { 1501, "HCI 18.2" }, -- cgit From d500612b723b88342b46c18e57730cec4b1d96af Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Nov 2004 20:22:32 +0000 Subject: Add more build ids and chip versions --- tools/csr.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 143fcca0..54acc260 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -45,6 +45,9 @@ static struct { uint16_t id; char *str; } csr_map[] = { + { 66, "HCI 9.8" }, + { 97, "HCI 10.3" }, + { 101, "HCI 10.5" }, { 111, "HCI 11.0" }, { 112, "HCI 11.1" }, { 114, "HCI 11.2" }, @@ -245,6 +248,7 @@ static struct { { 1120, "HCI 17.11" }, { 1168, "HCI 18.1" }, { 1169, "HCI 18.1" }, + { 1241, "HCI 18.x" }, { 1298, "HCI 18.2" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, @@ -287,10 +291,31 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) else return "BlueCore01b"; case 0x02: - if (rev == 0x89) - return "BlueCore02 (ES2)"; - else + switch (rev) { + case 0x89: + return "BlueCore02-External (ES2)"; + case 0x8a: + return "BlueCore02-External"; + case 0x28: + return "BlueCore02-ROM/Audio/Flash"; + default: return "BlueCore02"; + } + case 0x03: + switch (rev) { + case 0x43: + return "BlueCore3-MM"; + case 0x15: + return "BlueCore3-ROM"; + case 0xe2: + return "BlueCore3-Flash"; + case 0x26: + return "BlueCore4-External"; + case 0x30: + return "BlueCore4-ROM"; + default: + return "BlueCore3 or BlueCore4"; + } default: return "Unknown"; } -- cgit From 2ec32295cb3b5f8b1cf140a8913d1e75dd8a6db5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 03:49:36 +0000 Subject: Update UUID translation for WAP --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index c63750c4..3257159a 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -236,7 +236,7 @@ static struct uuid_def uuid16_names[] = { { 0x1111, "Fax", NULL, 0 }, { 0x1112, "HeadsetAudioGateway", NULL, 0 }, { 0x1113, "WAP", NULL, 0 }, - { 0x1114, "WAP_CLIENT", NULL, 0 }, + { 0x1114, "WAP Client", NULL, 0 }, { 0x1115, "PANU (PAN/BNEP)", pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, { 0x1116, "NAP (PAN/BNEP)", -- cgit From 2b6e37e7f5891fcdfa163bc4f7b988f4287f05bb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 12:35:17 +0000 Subject: Add build id of the Apple firmware update 1.2 --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 54acc260..6861c4ab 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -258,6 +258,7 @@ static struct { { 1505, "HCI 18.2" }, { 1506, "HCI 18.2" }, { 1520, "HCI 18.2" }, + { 1586, "HCI 18.2" }, { 1591, "HCI 18.2" }, { 1592, "HCI 18.2" }, { 1733, "HCI 18.3" }, -- cgit From 6b24ea1e4fdfba1d9f189d2575d1f9695daca7e9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 15:02:25 +0000 Subject: Add support for KYE/Genius adapter --- tools/hid2hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index c800c7ee..115e0ef5 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -219,6 +219,8 @@ static int switch_logitech(struct device_info *devinfo) static struct device_id device_list[] = { { HCI, 0x0a12, 0x1000, switch_hidproxy }, { HID, 0x0a12, 0x0001, switch_hidproxy }, + { HCI, 0x0458, 0x1000, switch_hidproxy }, + { HID, 0x0458, 0x003f, switch_hidproxy }, { HCI, 0x05ac, 0x1000, switch_hidproxy }, { HID, 0x05ac, 0x8203, switch_hidproxy }, { HCI, 0x046d, 0xc703, switch_logitech }, -- cgit From 20ab71f23fe08b749b43dbd3c7a96e0313a6471e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 18:55:17 +0000 Subject: Add build id for the KYE/Genius Bluetooth adapter --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 6861c4ab..5f6f4b27 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -250,6 +250,7 @@ static struct { { 1169, "HCI 18.1" }, { 1241, "HCI 18.x" }, { 1298, "HCI 18.2" }, + { 1354, "HCI 18.2" } { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, { 1501, "HCI 18.2" }, -- cgit From feb6bed4073bfb6eef1e636d9c055dcb8f320637 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 18:55:53 +0000 Subject: Typo --- tools/csr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 5f6f4b27..ca28ef2f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -250,7 +250,7 @@ static struct { { 1169, "HCI 18.1" }, { 1241, "HCI 18.x" }, { 1298, "HCI 18.2" }, - { 1354, "HCI 18.2" } + { 1354, "HCI 18.2" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, { 1501, "HCI 18.2" }, -- cgit From c75b3f2fae502b565565bcb94a4fab9dd889646a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 4 Dec 2004 04:53:46 +0000 Subject: Use --device and make more functions static --- tools/sdptool.c | 161 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 87 insertions(+), 74 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 3257159a..8d212c4e 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -34,12 +34,15 @@ #include #endif -#include #include -#include #include +#include +#include #include +#include +#include +#include #include #include @@ -48,7 +51,7 @@ /* * Convert a string to a BDADDR, with a few "enhancements" - Jean II */ -int estr2ba(char *str, bdaddr_t *ba) +static int estr2ba(char *str, bdaddr_t *ba) { /* Only trap "local", "any" is already dealt with */ if(!strcmp(str, "local")) { @@ -268,16 +271,16 @@ static struct uuid_def uuid16_names[] = { { 0x1204, "GenericTelephony", NULL, 0 }, }; -const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); +static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); -void sdp_data_printf(sdp_data_t *, struct attrib_context *, int); +static void sdp_data_printf(sdp_data_t *, struct attrib_context *, int); /* * Parse a UUID. * The BT assigned numbers only list UUID16, so I'm not sure the * other types will ever get used... */ -void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int indent) +static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int indent) { if (uuid) { if (uuid->type == SDP_UUID16) { @@ -360,7 +363,7 @@ static void printf_dataseq(sdp_data_t * pData, * Parse a single data element (either in the attribute or in a data * sequence). */ -void sdp_data_printf(sdp_data_t *sdpdata, +static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, int indent) { @@ -443,7 +446,7 @@ void sdp_data_printf(sdp_data_t *sdpdata, /* * Parse a single attribute. */ -void sdp_attr_printf_func(void *value, void *userData) +static void sdp_attr_printf_func(void *value, void *userData) { sdp_data_t *sdpdata = NULL; uint16_t attrId; @@ -496,7 +499,7 @@ void sdp_attr_printf_func(void *value, void *userData) * We assume the record has already been read, parsed and cached * locally. Jean II */ -void sdp_printf_service_attr(sdp_record_t *rec) +static void sdp_printf_service_attr(sdp_record_t *rec) { if (rec && rec->attrlist) { struct service_context service = { NULL }; @@ -508,7 +511,7 @@ void sdp_printf_service_attr(sdp_record_t *rec) * Set attributes with single values in SDP record * Jean II */ -int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value) +static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value) { sdp_list_t *attrid_list; uint32_t range = 0x0000ffff; @@ -560,8 +563,8 @@ int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *valu } static struct option set_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { 0, 0, 0, 0 } }; static char *set_help = @@ -571,7 +574,7 @@ static char *set_help = /* * Add an attribute to an existing SDP record on the local SDP server */ -int cmd_setattr(int argc, char **argv) +static int cmd_setattr(int argc, char **argv) { int opt, status; uint32_t handle; @@ -610,7 +613,7 @@ int cmd_setattr(int argc, char **argv) * We do only simple data sequences. Sequence of sequences is a pain ;-) * Jean II */ -int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int argc, char **argv) +static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int argc, char **argv) { sdp_list_t *attrid_list; uint32_t range = 0x0000ffff; @@ -695,8 +698,8 @@ int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int } static struct option seq_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { 0, 0, 0, 0 } }; static char *seq_help = @@ -707,7 +710,7 @@ static char *seq_help = * Add an attribute sequence to an existing SDP record * on the local SDP server */ -int cmd_setseq(int argc, char **argv) +static int cmd_setseq(int argc, char **argv) { int opt, status; uint32_t handle; @@ -810,7 +813,7 @@ static void print_service_desc(void *value, void *user) } } -void print_lang_attr(void *value, void *user) +static void print_lang_attr(void *value, void *user) { sdp_lang_attr_t *lang = (sdp_lang_attr_t *)value; printf(" code_ISO639: 0x%02x\n", lang->code_ISO639); @@ -818,13 +821,13 @@ void print_lang_attr(void *value, void *user) printf(" base_offset: 0x%02x\n", lang->base_offset); } -void print_access_protos(void *value, void *userData) +static void print_access_protos(void *value, void *userData) { sdp_list_t *protDescSeq = (sdp_list_t *)value; sdp_list_foreach(protDescSeq, print_service_desc, 0); } -void print_profile_desc(void *value, void *userData) +static void print_profile_desc(void *value, void *userData) { sdp_profile_desc_t *desc = (sdp_profile_desc_t *)value; char str[MAX_LEN_PROFILEDESCRIPTOR_UUID_STR]; @@ -840,7 +843,7 @@ void print_profile_desc(void *value, void *userData) /* * Parse a SDP record in user friendly form. */ -void print_service_attr(sdp_record_t *rec) +static void print_service_attr(sdp_record_t *rec) { sdp_list_t *list = 0, *proto = 0; @@ -926,7 +929,7 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Serial Port", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -984,7 +987,7 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1040,7 +1043,7 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "LAN Access over PPP", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1099,7 +1102,7 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Headset", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1161,7 +1164,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Handsfree", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1223,7 +1226,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "SIM Access", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1281,7 +1284,7 @@ static int add_fax(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Fax", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1354,7 +1357,7 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "OBEX Object Push", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1415,7 +1418,7 @@ static int add_file_trans(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1488,7 +1491,7 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Network Access Point Service", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1547,7 +1550,7 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Group Network Service", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1614,7 +1617,7 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1777,7 +1780,7 @@ struct { }; /* Add local service */ -int add_service(bdaddr_t *bdaddr, svc_info_t *si) +static int add_service(bdaddr_t *bdaddr, svc_info_t *si) { int i; sdp_session_t *sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); @@ -1799,16 +1802,16 @@ int add_service(bdaddr_t *bdaddr, svc_info_t *si) } static struct option add_options[] = { - {"help", 0,0, 'h'}, - {"channel", 1,0, 'c'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { "channel", 1,0, 'c' }, + { 0, 0, 0, 0} }; static char *add_help = "Usage:\n" "\tadd [--channel=CHAN] service\n"; -int cmd_add(int argc, char **argv) +static int cmd_add(int argc, char **argv) { svc_info_t si; int opt; @@ -1837,7 +1840,7 @@ int cmd_add(int argc, char **argv) } /* Delete local service */ -int del_service(bdaddr_t *bdaddr, void *arg) +static int del_service(bdaddr_t *bdaddr, void *arg) { uint32_t handle, range = 0x0000ffff; sdp_list_t *attr; @@ -1873,15 +1876,15 @@ int del_service(bdaddr_t *bdaddr, void *arg) } static struct option del_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { 0, 0, 0, 0 } }; static char *del_help = "Usage:\n" "\tdel record_handle\n"; -int cmd_del(int argc, char **argv) +static int cmd_del(int argc, char **argv) { int opt; @@ -1923,7 +1926,7 @@ static void inquiry(handler_t handler, void *arg) /* * Search for a specific SDP service */ -int do_search(bdaddr_t *bdaddr, struct search_context *context) +static int do_search(bdaddr_t *bdaddr, struct search_context *context) { sdp_list_t *attrid, *search, *seq, *next; uint32_t range = 0x0000ffff; @@ -1984,9 +1987,9 @@ int do_search(bdaddr_t *bdaddr, struct search_context *context) } static struct option browse_options[] = { - {"help", 0,0, 'h'}, - {"tree", 0,0, 't'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { "tree", 0,0, 't' }, + { 0, 0, 0, 0 } }; static char *browse_help = @@ -1997,7 +2000,7 @@ static char *browse_help = * Browse the full SDP database (i.e. list all services starting from the * root/top-level). */ -int cmd_browse(int argc, char **argv) +static int cmd_browse(int argc, char **argv) { struct search_context context; int opt; @@ -2029,10 +2032,10 @@ int cmd_browse(int argc, char **argv) } static struct option search_options[] = { - {"help", 0,0, 'h'}, - {"bdaddr", 1,0, 'b'}, - {"tree", 0,0, 't'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { "bdaddr", 1,0, 'b' }, + { "tree", 0,0, 't' }, + { 0, 0, 0, 0} }; static char *search_help = @@ -2048,7 +2051,7 @@ static char *search_help = * (this would search a service supporting both L2CAP and BNEP directly in * the top level browse group) */ -int cmd_search(int argc, char **argv) +static int cmd_search(int argc, char **argv) { struct search_context context; uint16_t class = 0; @@ -2116,7 +2119,7 @@ int cmd_search(int argc, char **argv) * Not really useful to the user, just show how it can be done... * Jean II */ -int get_service(bdaddr_t *bdaddr, struct search_context *context) +static int get_service(bdaddr_t *bdaddr, struct search_context *context) { sdp_list_t *attrid; uint32_t range = 0x0000ffff; @@ -2150,10 +2153,10 @@ int get_service(bdaddr_t *bdaddr, struct search_context *context) } static struct option get_options[] = { - {"help", 0,0, 'h'}, - {"bdaddr", 1,0, 'b'}, - {"tree", 0,0, 't'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { "bdaddr", 1,0, 'b' }, + { "tree", 0,0, 't' }, + { 0, 0, 0, 0 } }; static char *get_help = @@ -2163,7 +2166,7 @@ static char *get_help = /* * Get a specific SDP record on the local SDP server */ -int cmd_get(int argc, char **argv) +static int cmd_get(int argc, char **argv) { struct search_context context; bdaddr_t bdaddr; @@ -2200,7 +2203,7 @@ int cmd_get(int argc, char **argv) return get_service(has_addr? &bdaddr: BDADDR_LOCAL, &context); } -struct { +static struct { char *cmd; int (*func)(int argc, char **argv); char *doc; @@ -2212,14 +2215,14 @@ struct { { "get", cmd_get, "Get local service" }, { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, { "setseq", cmd_setseq, "Set/Add attribute sequence to a SDP record" }, - { 0, 0, 0} + { 0, 0, 0 } }; static void usage(void) { int i; - printf("sdptool - SDP Tool v%s\n", VERSION); + printf("sdptool - SDP tool v%s\n", VERSION); printf("Usage:\n" "\tsdptool [options] [command parameters]\n"); printf("Options:\n" @@ -2227,47 +2230,57 @@ static void usage(void) "\t--source\tSpecify source interface\n"); printf("Commands:\n"); - for (i=0; command[i].cmd; i++) + for (i = 0; command[i].cmd; i++) printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc); printf("\nServices:\n\t"); - for (i=0; service[i].name; i++) + for (i = 0; service[i].name; i++) printf("%s ", service[i].name); printf("\n"); } static struct option main_options[] = { - {"help", 0, 0, 'h'}, - {"source", 1, 0, 'S'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } }; int main(int argc, char **argv) { - int opt, i; + int i, opt; bacpy(&interface, BDADDR_ANY); - while ((opt=getopt_long(argc, argv, "+hS:", main_options, 0)) != -1) { + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { - case 'S': - str2ba(optarg, &interface); + case 'i': + if (!strncmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &interface); + else + str2ba(optarg, &interface); break; + case 'h': - default: usage(); - return -1; + exit(0); + + default: + exit(1); } } + argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); - return -1; + exit(1); } - for (i=0; command[i].cmd; i++) + + for (i = 0; command[i].cmd; i++) if (strncmp(command[i].cmd, argv[0], 4) == 0) return command[i].func(argc, argv); + return -1; } -- cgit From ba3d640d8a665d61973172b2a0e9531b735f5f91 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 4 Dec 2004 18:17:59 +0000 Subject: Remove one whitespace --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 854c8715..22aaeda7 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1063,7 +1063,7 @@ void print_dev_hdr(struct hci_dev_info *di) ba2str(&di->bdaddr, addr); printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); - printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", + printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", addr, di->acl_mtu, di->acl_pkts, di->sco_mtu, di->sco_pkts); } -- cgit From b85cf3e041b3972ed220af85c0152efdc9fe19f3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Dec 2004 11:48:52 +0000 Subject: Whitespace cleanup --- tools/sdptool.c | 374 ++++++++++++++++++++++++++------------------------------ 1 file changed, 176 insertions(+), 198 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 8d212c4e..fb657a3d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -63,7 +63,7 @@ static int estr2ba(char *str, bdaddr_t *ba) /* Pass args to the inquiry/search handler */ struct search_context { - char *svc; /* Service */ + char *svc; /* Service */ uuid_t group; /* Browse group */ int tree; /* Display full attribute tree */ uint32_t handle; /* Service record handle */ @@ -76,35 +76,35 @@ static bdaddr_t interface; /* Definition of attribute members */ struct member_def { - char *name; + char *name; }; /* Definition of an attribute */ struct attrib_def { - int num; /* Numeric ID - 16 bits */ - char * name; /* User readable name */ - struct member_def * members; /* Definition of attribute args */ - int member_max; /* Max of attribute arg definitions */ + int num; /* Numeric ID - 16 bits */ + char *name; /* User readable name */ + struct member_def *members; /* Definition of attribute args */ + int member_max; /* Max of attribute arg definitions */ }; /* Definition of a service or protocol */ struct uuid_def { - int num; /* Numeric ID - 16 bits */ - char * name; /* User readable name */ - struct attrib_def * attribs; /* Specific attribute definitions */ - int attrib_max; /* Max of attribute definitions */ + int num; /* Numeric ID - 16 bits */ + char *name; /* User readable name */ + struct attrib_def *attribs; /* Specific attribute definitions */ + int attrib_max; /* Max of attribute definitions */ }; /* Context information about current attribute */ struct attrib_context { - struct uuid_def * service; /* Service UUID, if known */ - struct attrib_def * attrib; /* Description of the attribute */ - int member_index; /* Index of current attribute member */ + struct uuid_def *service; /* Service UUID, if known */ + struct attrib_def *attrib; /* Description of the attribute */ + int member_index; /* Index of current attribute member */ }; /* Context information about the whole service */ struct service_context { - struct uuid_def * service; /* Service UUID, if known */ + struct uuid_def *service; /* Service UUID, if known */ }; /* Allow us to do nice formatting of the lists */ @@ -117,158 +117,157 @@ static char *indent_spaces = " "; /* Definition of the optional arguments in protocol list */ static struct member_def protocol_members[] = { - { "Protocol" }, - { "Channel/Port" }, - { "Version" }, + { "Protocol" }, + { "Channel/Port" }, + { "Version" }, }; /* Definition of the optional arguments in profile list */ static struct member_def profile_members[] = { - { "Profile" }, - { "Version" }, + { "Profile" }, + { "Version" }, }; /* Definition of the optional arguments in Language list */ static struct member_def language_members[] = { - { "Code ISO639" }, - { "Encoding" }, - { "Base Offset" }, + { "Code ISO639" }, + { "Encoding" }, + { "Base Offset" }, }; /* Name of the various common attributes. See BT assigned numbers */ static struct attrib_def attrib_names[] = { - { 0x0, "ServiceRecordHandle", NULL, 0 }, - { 0x1, "ServiceClassIDList", NULL, 0 }, - { 0x2, "ServiceRecordState", NULL, 0 }, - { 0x3, "ServiceID", NULL, 0 }, - { 0x4, "ProtocolDescriptorList", - protocol_members, sizeof(protocol_members)/sizeof(struct member_def) }, - { 0x5, "BrowseGroupList", NULL, 0 }, - { 0x6, "LanguageBaseAttributeIDList", - language_members, sizeof(language_members)/sizeof(struct member_def) }, - { 0x7, "ServiceInfoTimeToLive", NULL, 0 }, - { 0x8, "ServiceAvailability", NULL, 0 }, - { 0x9, "BluetoothProfileDescriptorList", - profile_members, sizeof(profile_members)/sizeof(struct member_def) }, - { 0xA, "DocumentationURL", NULL, 0 }, - { 0xB, "ClientExecutableURL", NULL, 0 }, - { 0xC, "IconURL", NULL, 0 }, - { 0xD, "AdditionalProtocolDescriptorLists", NULL, 0 }, - /* Definitions after that are tricky (per profile or offset) */ + { 0x0, "ServiceRecordHandle", NULL, 0 }, + { 0x1, "ServiceClassIDList", NULL, 0 }, + { 0x2, "ServiceRecordState", NULL, 0 }, + { 0x3, "ServiceID", NULL, 0 }, + { 0x4, "ProtocolDescriptorList", + protocol_members, sizeof(protocol_members)/sizeof(struct member_def) }, + { 0x5, "BrowseGroupList", NULL, 0 }, + { 0x6, "LanguageBaseAttributeIDList", + language_members, sizeof(language_members)/sizeof(struct member_def) }, + { 0x7, "ServiceInfoTimeToLive", NULL, 0 }, + { 0x8, "ServiceAvailability", NULL, 0 }, + { 0x9, "BluetoothProfileDescriptorList", + profile_members, sizeof(profile_members)/sizeof(struct member_def) }, + { 0xA, "DocumentationURL", NULL, 0 }, + { 0xB, "ClientExecutableURL", NULL, 0 }, + { 0xC, "IconURL", NULL, 0 }, + { 0xD, "AdditionalProtocolDescriptorLists", NULL, 0 }, + /* Definitions after that are tricky (per profile or offset) */ }; const int attrib_max = sizeof(attrib_names)/sizeof(struct attrib_def); /* Name of the various SPD attributes. See BT assigned numbers */ static struct attrib_def sdp_attrib_names[] = { - { 0x200, "VersionNumberList", NULL, 0 }, - { 0x201, "ServiceDatabaseState", NULL, 0 }, + { 0x200, "VersionNumberList", NULL, 0 }, + { 0x201, "ServiceDatabaseState", NULL, 0 }, }; /* Name of the various SPD attributes. See BT assigned numbers */ static struct attrib_def browse_attrib_names[] = { - { 0x200, "GroupID", NULL, 0 }, + { 0x200, "GroupID", NULL, 0 }, }; /* Name of the various PAN attributes. See BT assigned numbers */ /* Note : those need to be double checked - Jean II */ static struct attrib_def pan_attrib_names[] = { - { 0x200, "IpSubnet", NULL, 0 }, /* Obsolete ??? */ - { 0x30A, "SecurityDescription", NULL, 0 }, - { 0x30B, "NetAccessType", NULL, 0 }, - { 0x30C, "MaxNetAccessrate", NULL, 0 }, - { 0x30D, "IPv4Subnet", NULL, 0 }, - { 0x30E, "IPv6Subnet", NULL, 0 }, + { 0x200, "IpSubnet", NULL, 0 }, /* Obsolete ??? */ + { 0x30A, "SecurityDescription", NULL, 0 }, + { 0x30B, "NetAccessType", NULL, 0 }, + { 0x30C, "MaxNetAccessrate", NULL, 0 }, + { 0x30D, "IPv4Subnet", NULL, 0 }, + { 0x30E, "IPv6Subnet", NULL, 0 }, }; /* Name of the various Generic-Audio attributes. See BT assigned numbers */ /* Note : totally untested - Jean II */ static struct attrib_def audio_attrib_names[] = { - { 0x302, "Remote audio volume control", NULL, 0 }, + { 0x302, "Remote audio volume control", NULL, 0 }, }; /* Same for the UUIDs. See BT assigned numbers */ static struct uuid_def uuid16_names[] = { - /* -- Protocols -- */ - { 0x1, "SDP (Service Discovery Protocol)", NULL, 0 }, - { 0x2, "UDP", NULL, 0 }, - { 0x3, "RFCOMM", NULL, 0 }, - { 0x4, "TCP", NULL, 0 }, - { 0x5, "TCS-BIN", NULL, 0 }, - { 0x6, "TCS-AT", NULL, 0 }, - { 0x8, "OBEX", NULL, 0 }, - { 0x9, "IP", NULL, 0 }, - { 0xA, "FTP", NULL, 0 }, - { 0xC, "HTTP", NULL, 0 }, - { 0xE, "WSP", NULL, 0 }, - { 0xF, "BNEP (PAN/BNEP)", NULL, 0 }, - { 0x10, "UPnP/ESDP", NULL, 0 }, - { 0x11, "HIDP", NULL, 0 }, - { 0x12, "HardcopyControlChannel", NULL, 0 }, - { 0x14, "HardcopyDataChannel", NULL, 0 }, - { 0x16, "HardcopyNotification", NULL, 0 }, - { 0x17, "AVCTP", NULL, 0 }, - { 0x19, "AVDTP", NULL, 0 }, - { 0x1B, "CMTP", NULL, 0 }, - { 0x1D, "UDI_C-Plane", NULL, 0 }, - { 0x100, "L2CAP", NULL, 0 }, - /* -- Services -- */ - { 0x1000, "ServiceDiscoveryServerServiceClassID (SDP)", - sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) }, - { 0x1001, "BrowseGroupDescriptorServiceClassID (SDP)", - browse_attrib_names, - sizeof(browse_attrib_names)/sizeof(struct attrib_def) }, - { 0x1002, "PublicBrowseGroup (SDP)", NULL, 0 }, - { 0x1101, "SerialPort", NULL, 0 }, - { 0x1102, "LANAccessUsingPPP", NULL, 0 }, - { 0x1103, "DialupNetworking (DUN)", NULL, 0 }, - { 0x1104, "IrMCSync", NULL, 0 }, - { 0x1105, "OBEXObjectPush", NULL, 0 }, - { 0x1106, "OBEXFileTransfer", NULL, 0 }, - { 0x1107, "IrMCSyncCommand", NULL, 0 }, - { 0x1108, "Headset", - audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, - { 0x1109, "CordlessTelephony", NULL, 0 }, - { 0x110a, "AudioSource", NULL, 0 }, - { 0x110b, "AudioSink", NULL, 0 }, - { 0x110c, "RemoteControlTarget", NULL, 0 }, - { 0x110d, "AdvancedAudio", NULL, 0 }, - { 0x110e, "RemoteControl", NULL, 0 }, - { 0x110f, "VideoConferencing", NULL, 0 }, - { 0x1110, "Intercom", NULL, 0 }, - { 0x1111, "Fax", NULL, 0 }, - { 0x1112, "HeadsetAudioGateway", NULL, 0 }, - { 0x1113, "WAP", NULL, 0 }, - { 0x1114, "WAP Client", NULL, 0 }, - { 0x1115, "PANU (PAN/BNEP)", - pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, - { 0x1116, "NAP (PAN/BNEP)", - pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, - { 0x1117, "GN (PAN/BNEP)", - pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, - { 0x1118, "DirectPrinting (BPP)", NULL, 0 }, - { 0x1119, "ReferencePrinting (BPP)", NULL, 0 }, - /* ... */ - { 0x111e, "Handsfree", NULL, 0 }, - { 0x111f, "HandsfreeAudioGateway", NULL, 0 }, - { 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 }, - { 0x1121, "ReflectedUI (BPP)", NULL, 0 }, - { 0x1122, "BasicPrinting (BPP)", NULL, 0 }, - { 0x1123, "PrintingStatus (BPP)", NULL, 0 }, - { 0x1124, "HumanInterfaceDeviceService (HID)", NULL, 0 }, - { 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 }, - { 0x1126, "HCR_Print (HCR)", NULL, 0 }, - { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, - { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, - { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, - { 0x112d, "SIM Access (SAP)", NULL, 0 }, - /* ... */ - { 0x1200, "PnPInformation", NULL, 0 }, - { 0x1201, "GenericNetworking", NULL, 0 }, - { 0x1202, "GenericFileTransfer", NULL, 0 }, - { 0x1203, "GenericAudio", - audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, - { 0x1204, "GenericTelephony", NULL, 0 }, + /* -- Protocols -- */ + { 0x0001, "SDP (Service Discovery Protocol)", NULL, 0 }, + { 0x0002, "UDP", NULL, 0 }, + { 0x0003, "RFCOMM", NULL, 0 }, + { 0x0004, "TCP", NULL, 0 }, + { 0x0005, "TCS-BIN", NULL, 0 }, + { 0x0006, "TCS-AT", NULL, 0 }, + { 0x0008, "OBEX", NULL, 0 }, + { 0x0009, "IP", NULL, 0 }, + { 0x000a, "FTP", NULL, 0 }, + { 0x000c, "HTTP", NULL, 0 }, + { 0x000e, "WSP", NULL, 0 }, + { 0x000f, "BNEP (PAN/BNEP)", NULL, 0 }, + { 0x0010, "UPnP/ESDP", NULL, 0 }, + { 0x0011, "HIDP", NULL, 0 }, + { 0x0012, "HardcopyControlChannel", NULL, 0 }, + { 0x0014, "HardcopyDataChannel", NULL, 0 }, + { 0x0016, "HardcopyNotification", NULL, 0 }, + { 0x0017, "AVCTP", NULL, 0 }, + { 0x0019, "AVDTP", NULL, 0 }, + { 0x001b, "CMTP", NULL, 0 }, + { 0x001d, "UDI_C-Plane", NULL, 0 }, + { 0x0100, "L2CAP", NULL, 0 }, + /* -- Services -- */ + { 0x1000, "ServiceDiscoveryServerServiceClassID (SDP)", + sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) }, + { 0x1001, "BrowseGroupDescriptorServiceClassID (SDP)", + browse_attrib_names, sizeof(browse_attrib_names)/sizeof(struct attrib_def) }, + { 0x1002, "PublicBrowseGroup (SDP)", NULL, 0 }, + { 0x1101, "SerialPort", NULL, 0 }, + { 0x1102, "LANAccessUsingPPP", NULL, 0 }, + { 0x1103, "DialupNetworking (DUN)", NULL, 0 }, + { 0x1104, "IrMCSync", NULL, 0 }, + { 0x1105, "OBEXObjectPush", NULL, 0 }, + { 0x1106, "OBEXFileTransfer", NULL, 0 }, + { 0x1107, "IrMCSyncCommand", NULL, 0 }, + { 0x1108, "Headset", + audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, + { 0x1109, "CordlessTelephony", NULL, 0 }, + { 0x110a, "AudioSource", NULL, 0 }, + { 0x110b, "AudioSink", NULL, 0 }, + { 0x110c, "RemoteControlTarget", NULL, 0 }, + { 0x110d, "AdvancedAudio", NULL, 0 }, + { 0x110e, "RemoteControl", NULL, 0 }, + { 0x110f, "VideoConferencing", NULL, 0 }, + { 0x1110, "Intercom", NULL, 0 }, + { 0x1111, "Fax", NULL, 0 }, + { 0x1112, "HeadsetAudioGateway", NULL, 0 }, + { 0x1113, "WAP", NULL, 0 }, + { 0x1114, "WAP Client", NULL, 0 }, + { 0x1115, "PANU (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1116, "NAP (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1117, "GN (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1118, "DirectPrinting (BPP)", NULL, 0 }, + { 0x1119, "ReferencePrinting (BPP)", NULL, 0 }, + /* ... */ + { 0x111e, "Handsfree", NULL, 0 }, + { 0x111f, "HandsfreeAudioGateway", NULL, 0 }, + { 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 }, + { 0x1121, "ReflectedUI (BPP)", NULL, 0 }, + { 0x1122, "BasicPrinting (BPP)", NULL, 0 }, + { 0x1123, "PrintingStatus (BPP)", NULL, 0 }, + { 0x1124, "HumanInterfaceDeviceService (HID)", NULL, 0 }, + { 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 }, + { 0x1126, "HCR_Print (HCR)", NULL, 0 }, + { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, + { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, + { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, + { 0x112d, "SIM Access (SAP)", NULL, 0 }, + /* ... */ + { 0x1200, "PnPInformation", NULL, 0 }, + { 0x1201, "GenericNetworking", NULL, 0 }, + { 0x1202, "GenericFileTransfer", NULL, 0 }, + { 0x1203, "GenericAudio", + audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, + { 0x1204, "GenericTelephony", NULL, 0 }, }; static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); @@ -302,14 +301,13 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in if(uuidDef) printf("%.*sUUID16 : 0x%.4x - %s\n", - indent, indent_spaces, - uuidNum, uuidDef->name); + indent, indent_spaces, uuidNum, uuidDef->name); else printf("%.*sUUID16 : 0x%.4x\n", - indent, indent_spaces, uuidNum); + indent, indent_spaces, uuidNum); } else if (uuid->type == SDP_UUID32) { printf("%.*sUUID32 : 0x%.8x\n", - indent, indent_spaces, uuid->value.uuid32); + indent, indent_spaces, uuid->value.uuid32); } else if (uuid->type == SDP_UUID128) { unsigned int data0; unsigned short data1; @@ -326,23 +324,21 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in memcpy(&data5, &uuid->value.uuid128.data[14], 2); printf("%.*sUUID128 : 0x%.8x-%.4x-%.4x-%.4x-%.8x-%.4x\n", - indent, indent_spaces, - ntohl(data0), ntohs(data1), ntohs(data2), - ntohs(data3), ntohl(data4), ntohs(data5)); + indent, indent_spaces, + ntohl(data0), ntohs(data1), ntohs(data2), + ntohs(data3), ntohl(data4), ntohs(data5)); } else printf("%.*sEnum type of UUID not set\n", - indent, indent_spaces); + indent, indent_spaces); } else printf("%.*sNull passed to print UUID\n", - indent, indent_spaces); + indent, indent_spaces); } /* * Parse a sequence of data elements (i.e. a list) */ -static void printf_dataseq(sdp_data_t * pData, - struct attrib_context *context, - int indent) +static void printf_dataseq(sdp_data_t * pData, struct attrib_context *context, int indent) { sdp_data_t *sdpdata = NULL; @@ -363,9 +359,7 @@ static void printf_dataseq(sdp_data_t * pData, * Parse a single data element (either in the attribute or in a data * sequence). */ -static void sdp_data_printf(sdp_data_t *sdpdata, - struct attrib_context *context, - int indent) +static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, int indent) { char *member_name = NULL; @@ -392,11 +386,10 @@ static void sdp_data_printf(sdp_data_t *sdpdata, case SDP_INT128: if (member_name) { printf("%.*s%s (Integer) : 0x%x\n", - indent, indent_spaces, - member_name, sdpdata->val.uint32); + indent, indent_spaces, member_name, sdpdata->val.uint32); } else { printf("%.*sInteger : 0x%x\n", indent, indent_spaces, - sdpdata->val.uint32); + sdpdata->val.uint32); } break; @@ -417,14 +410,12 @@ static void sdp_data_printf(sdp_data_t *sdpdata, printf(" %02x", (unsigned char) sdpdata->val.str[i]); printf("\n"); } else - printf("%.*sText : \"%s\"\n", indent, indent_spaces, - sdpdata->val.str); + printf("%.*sText : \"%s\"\n", indent, indent_spaces, sdpdata->val.str); break; case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: - printf("%.*sURL : %s\n", indent, indent_spaces, - sdpdata->val.str); + printf("%.*sURL : %s\n", indent, indent_spaces, sdpdata->val.str); break; case SDP_SEQ8: @@ -464,9 +455,8 @@ static void sdp_attr_printf_func(void *value, void *userData) break; } /* Search amongst the specific attributes of this service */ - if ((attrDef == NULL) && - (service->service != NULL) && - (service->service->attribs != NULL)) { + if ((attrDef == NULL) && (service->service != NULL) && + (service->service->attribs != NULL)) { struct attrib_def *svc_attribs = service->service->attribs; int svc_attrib_max = service->service->attrib_max; for (i = 0; i < svc_attrib_max; i++) @@ -477,8 +467,7 @@ static void sdp_attr_printf_func(void *value, void *userData) } if (attrDef) - printf("Attribute Identifier : 0x%x - %s\n", - attrId, attrDef->name); + printf("Attribute Identifier : 0x%x - %s\n", attrId, attrDef->name); else printf("Attribute Identifier : 0x%x\n", attrId); /* Build context */ @@ -534,7 +523,7 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha value_int = strtoul(value + 3, NULL, 16); sdp_uuid16_create(&value_uuid, value_int); printf("Adding attrib 0x%X uuid16 0x%X to record 0x%X\n", - attrib, value_int, handle); + attrib, value_int, handle); sdp_attr_add_new(rec, attrib, SDP_UUID16, &value_uuid.value.uuid16); } else if (!strncasecmp(value, "0x", 2)) { @@ -542,13 +531,13 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha uint32_t value_int; value_int = strtoul(value + 2, NULL, 16); printf("Adding attrib 0x%X int 0x%X to record 0x%X\n", - attrib, value_int, handle); + attrib, value_int, handle); sdp_attr_add_new(rec, attrib, SDP_UINT32, &value_int); } else { /* String */ printf("Adding attrib 0x%X string \"%s\" to record 0x%X\n", - attrib, value, handle); + attrib, value, handle); /* Add/Update our attribute to the record */ sdp_attr_add_new(rec, attrib, SDP_TEXT_STR8, value); @@ -651,8 +640,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri allocArray[i] = value_uuid; sdp_uuid16_create(value_uuid, value_int); - printf("Adding uuid16 0x%X to record 0x%X\n", - value_int, handle); + printf("Adding uuid16 0x%X to record 0x%X\n", value_int, handle); dtdArray[i] = &uuid16; valueArray[i] = &value_uuid->value.uuid16; } else if (!strncasecmp(argv[i], "0x", 2)) { @@ -661,14 +649,12 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri allocArray[i] = value_int; *value_int = strtoul((argv[i]) + 2, NULL, 16); - printf("Adding int 0x%X to record 0x%X\n", - *value_int, handle); + printf("Adding int 0x%X to record 0x%X\n", *value_int, handle); dtdArray[i] = &uint32; valueArray[i] = value_int; } else { /* String */ - printf("Adding string \"%s\" to record 0x%X\n", - argv[i], handle); + printf("Adding string \"%s\" to record 0x%X\n", argv[i], handle); dtdArray[i] = &str8; valueArray[i] = argv[i]; } @@ -1566,16 +1552,6 @@ end: return ret; } -static int add_hid(sdp_session_t *sess, svc_info_t *si) -{ - return -1; -} - -static int add_cip(sdp_session_t *sess, svc_info_t *si) -{ - return -1; -} - static int add_ctp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1751,30 +1727,30 @@ done: } struct { - char *name; - uint16_t class; - int (*add)(sdp_session_t *sess, svc_info_t *si); + char *name; + uint16_t class; + int (*add)(sdp_session_t *sess, svc_info_t *si); } service[] = { - { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, - { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, - { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, - { "FAX", FAX_SVCLASS_ID, add_fax }, - { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, - { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, + { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, + { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, + { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, + { "FAX", FAX_SVCLASS_ID, add_fax }, + { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, + { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, - { "HS", HEADSET_SVCLASS_ID, add_headset }, - { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, - { "SAP", SAP_SVCLASS_ID, add_simaccess }, + { "HS", HEADSET_SVCLASS_ID, add_headset }, + { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, + { "SAP", SAP_SVCLASS_ID, add_simaccess }, - { "NAP", NAP_SVCLASS_ID, add_nap }, - { "GN", GN_SVCLASS_ID, add_gn }, + { "NAP", NAP_SVCLASS_ID, add_nap }, + { "GN", GN_SVCLASS_ID, add_gn }, - { "HID", HID_SVCLASS_ID, add_hid }, - { "CIP", CIP_SVCLASS_ID, add_cip }, - { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, + { "HID", HID_SVCLASS_ID, NULL }, + { "CIP", CIP_SVCLASS_ID, NULL }, + { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, - { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source }, - { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, + { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source}, + { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, { 0 } }; @@ -1788,9 +1764,11 @@ static int add_service(bdaddr_t *bdaddr, svc_info_t *si) if (!sess) return -1; if (si->name) - for (i=0; service[i].name; i++) + for (i = 0; service[i].name; i++) if (!strcasecmp(service[i].name, si->name)) { - int ret = service[i].add(sess, si); + int ret = -1; + if (service[i].add) + ret = service[i].add(sess, si); free(si->name); sdp_close(sess); return ret; @@ -1919,7 +1897,7 @@ static void inquiry(handler_t handler, void *arg) printf("Inquiry failed\n"); return; } - for (i=0; i Date: Tue, 7 Dec 2004 12:31:26 +0000 Subject: Add support for Device ID --- tools/sdptool.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index fb657a3d..358fbb42 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -170,6 +170,16 @@ static struct attrib_def browse_attrib_names[] = { { 0x200, "GroupID", NULL, 0 }, }; +/* Name of the various Device ID attributes. See Device Id spec. */ +static struct attrib_def did_attrib_names[] = { + { 0x200, "SpecificationID", NULL, 0 }, + { 0x201, "VendorID", NULL, 0 }, + { 0x202, "ProductID", NULL, 0 }, + { 0x203, "Version", NULL, 0 }, + { 0x204, "PrimaryRecord", NULL, 0 }, + { 0x205, "VendorIDSource", NULL, 0 }, +}; + /* Name of the various PAN attributes. See BT assigned numbers */ /* Note : those need to be double checked - Jean II */ static struct attrib_def pan_attrib_names[] = { @@ -262,7 +272,8 @@ static struct uuid_def uuid16_names[] = { { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, { 0x112d, "SIM Access (SAP)", NULL, 0 }, /* ... */ - { 0x1200, "PnPInformation", NULL, 0 }, + { 0x1200, "PnPInformation", + did_attrib_names, sizeof(did_attrib_names)/sizeof(struct attrib_def) }, { 0x1201, "GenericNetworking", NULL, 0 }, { 0x1202, "GenericFileTransfer", NULL, 0 }, { 0x1203, "GenericAudio", @@ -1143,7 +1154,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) apseq = sdp_list_append(apseq, proto[1]); features = sdp_data_alloc(SDP_UINT16, &u16); - sdp_attr_add(&record, SDP_SUPPORTED_FEATURES, features); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); @@ -1205,7 +1216,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) apseq = sdp_list_append(apseq, proto[1]); features = sdp_data_alloc(SDP_UINT16, &u16); - sdp_attr_add(&record, SDP_SUPPORTED_FEATURES, features); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); @@ -1589,7 +1600,7 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); - sdp_attr_add(&record, SDP_EXTERNAL_NETWORK, network); + sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network); sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); @@ -1731,6 +1742,8 @@ struct { uint16_t class; int (*add)(sdp_session_t *sess, svc_info_t *si); } service[] = { + { "DID", PNP_INFO_SVCLASS_ID, NULL, }, + { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, @@ -2074,7 +2087,7 @@ static int cmd_search(int argc, char **argv) } else { /* Convert class name to an UUID */ - for (i=0; service[i].name; i++) + for (i = 0; service[i].name; i++) if (strcasecmp(context.svc, service[i].name) == 0) { class = service[i].class; break; -- cgit From a4a063c607c0d2693f253af261b6d8a0bf221f9c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Dec 2004 12:50:50 +0000 Subject: Add support for HID attribute descriptions --- tools/sdptool.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 358fbb42..6ceb0bd9 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -180,6 +180,25 @@ static struct attrib_def did_attrib_names[] = { { 0x205, "VendorIDSource", NULL, 0 }, }; +/* Name of the various HID attributes. See HID spec. */ +static struct attrib_def hid_attrib_names[] = { + { 0x200, "DeviceReleaseNum", NULL, 0 }, + { 0x201, "ParserVersion", NULL, 0 }, + { 0x202, "DeviceSubclass", NULL, 0 }, + { 0x203, "CountryCode", NULL, 0 }, + { 0x204, "VirtualCable", NULL, 0 }, + { 0x205, "ReconnectInitiate", NULL, 0 }, + { 0x206, "DescriptorList", NULL, 0 }, + { 0x207, "LangIDBaseList", NULL, 0 }, + { 0x208, "SDPDisable", NULL, 0 }, + { 0x209, "BatteryPower", NULL, 0 }, + { 0x20a, "RemoteWakeup", NULL, 0 }, + { 0x20b, "ProfileVersion", NULL, 0 }, + { 0x20c, "SupervisionTimeout", NULL, 0 }, + { 0x20d, "NormallyConnectable", NULL, 0 }, + { 0x20e, "BootDevice", NULL, 0 }, +}; + /* Name of the various PAN attributes. See BT assigned numbers */ /* Note : those need to be double checked - Jean II */ static struct attrib_def pan_attrib_names[] = { @@ -264,7 +283,8 @@ static struct uuid_def uuid16_names[] = { { 0x1121, "ReflectedUI (BPP)", NULL, 0 }, { 0x1122, "BasicPrinting (BPP)", NULL, 0 }, { 0x1123, "PrintingStatus (BPP)", NULL, 0 }, - { 0x1124, "HumanInterfaceDeviceService (HID)", NULL, 0 }, + { 0x1124, "HumanInterfaceDeviceService (HID)", + hid_attrib_names, sizeof(hid_attrib_names)/sizeof(struct attrib_def) }, { 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 }, { 0x1126, "HCR_Print (HCR)", NULL, 0 }, { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, -- cgit From 19812023eacc4a912db4adb92c040a02a50cdff7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 10 Dec 2004 09:06:36 +0000 Subject: Also translate UUID-32 to string --- tools/sdptool.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 6ceb0bd9..cfbe2bba 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -318,8 +318,8 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in struct uuid_def *uuidDef = NULL; int i; - for(i = 0; i < uuid16_max; i++) - if(uuid16_names[i].num == uuidNum) { + for (i = 0; i < uuid16_max; i++) + if (uuid16_names[i].num == uuidNum) { uuidDef = &uuid16_names[i]; break; } @@ -330,15 +330,31 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in context->service = uuidDef; } - if(uuidDef) + if (uuidDef) printf("%.*sUUID16 : 0x%.4x - %s\n", indent, indent_spaces, uuidNum, uuidDef->name); else printf("%.*sUUID16 : 0x%.4x\n", indent, indent_spaces, uuidNum); } else if (uuid->type == SDP_UUID32) { - printf("%.*sUUID32 : 0x%.8x\n", - indent, indent_spaces, uuid->value.uuid32); + struct uuid_def *uuidDef = NULL; + int i; + + if (!(uuid->value.uuid32 & 0xffff0000)) { + uint16_t uuidNum = uuid->value.uuid32; + for (i = 0; i < uuid16_max; i++) + if (uuid16_names[i].num == uuidNum) { + uuidDef = &uuid16_names[i]; + break; + } + } + + if (uuidDef) + printf("%.*sUUID32 : 0x%.8x - %s\n", + indent, indent_spaces, uuid->value.uuid32, uuidDef->name); + else + printf("%.*sUUID32 : 0x%.8x\n", + indent, indent_spaces, uuid->value.uuid32); } else if (uuid->type == SDP_UUID128) { unsigned int data0; unsigned short data1; -- cgit From bbda499067067aefc8e642a2784d247ac0331eae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 25 Dec 2004 17:43:16 +0000 Subject: Add memset() to different places to initialize the structures --- tools/ciptool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index d0b6625d..7c952cf4 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -146,9 +146,9 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne exit(1); } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, src); - addr.l2_psm = 0; if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Can't bind L2CAP socket"); @@ -156,7 +156,9 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne exit(1); } + memset(&opts, 0, sizeof(opts)); size = sizeof(opts); + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) { perror("Can't get L2CAP options"); close(sk); @@ -173,6 +175,7 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne exit(1); } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); addr.l2_psm = htobs(psm); -- cgit From 018d2a9255e4015860825bd4957d5bd41ba7cecc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 13:21:30 +0000 Subject: Whitespace cleanup and make more code static --- tools/hciconfig.c | 293 ++++++++++++++++++++++++++++-------------------------- tools/hcitool.c | 154 +++++++++++++--------------- 2 files changed, 225 insertions(+), 222 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 22aaeda7..11590b97 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,17 +33,11 @@ #endif #include -#include -#include -#include -#include -#include #include #include +#include +#include #include - -#include -#include #include #include @@ -53,56 +47,54 @@ #include "csr.h" -extern int optind,opterr,optopt; -extern char *optarg; - static struct hci_dev_info di; static int all; -void print_dev_hdr(struct hci_dev_info *di); -void print_dev_info(int ctl, struct hci_dev_info *di); +static void print_dev_hdr(struct hci_dev_info *di); +static void print_dev_info(int ctl, struct hci_dev_info *di); -void print_dev_list(int ctl, int flags) +static void print_dev_list(int ctl, int flags) { struct hci_dev_list_req *dl; struct hci_dev_req *dr; int i; - if( !(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t))) ) { + if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) { perror("Can't allocate memory"); exit(1); } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if( ioctl(ctl, HCIGETDEVLIST, (void*)dl) ) { + if (ioctl(ctl, HCIGETDEVLIST, (void *) dl)) { perror("Can't get device list"); exit(1); } - for(i=0; i< dl->dev_num; i++) { + + for (i = 0; i< dl->dev_num; i++) { di.dev_id = (dr+i)->dev_id; - if( ioctl(ctl, HCIGETDEVINFO, (void*)&di) ) + if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) continue; print_dev_info(ctl, &di); } } -void print_pkt_type(struct hci_dev_info *di) +static void print_pkt_type(struct hci_dev_info *di) { printf("\tPacket type: %s\n", hci_ptypetostr(di->pkt_type)); } -void print_link_policy(struct hci_dev_info *di) +static void print_link_policy(struct hci_dev_info *di) { printf("\tLink policy: %s\n", hci_lptostr(di->link_policy)); } -void print_link_mode(struct hci_dev_info *di) +static void print_link_mode(struct hci_dev_info *di) { printf("\tLink mode: %s\n", hci_lmtostr(di->link_mode)); } -void print_dev_features(struct hci_dev_info *di, int format) +static void print_dev_features(struct hci_dev_info *di, int format) { if (!format) { printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", @@ -120,17 +112,17 @@ void print_dev_features(struct hci_dev_info *di, int format) } } -void cmd_rstat(int ctl, int hdev, char *opt) +static void cmd_rstat(int ctl, int hdev, char *opt) { /* Reset HCI device stat counters */ - if( ioctl(ctl, HCIDEVRESTAT, hdev) < 0 ) { - printf("Can't reset stats counters hci%d. %s(%d)\n", hdev, - strerror(errno), errno); + if (ioctl(ctl, HCIDEVRESTAT, hdev) < 0) { + fprintf(stderr, "Can't reset stats counters hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_scan(int ctl, int hdev, char *opt) +static void cmd_scan(int ctl, int hdev, char *opt) { struct hci_dev_req dr; @@ -143,18 +135,20 @@ void cmd_scan(int ctl, int hdev, char *opt) else if( !strcmp(opt, "piscan") ) dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; - if( ioctl(ctl, HCISETSCAN, (unsigned long)&dr) < 0 ) { - printf("Can't set scan mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_iac(int ctl, int hdev, char *opt) +static void cmd_iac(int ctl, int hdev, char *opt) { int s = hci_open_dev(hdev); if (s < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { @@ -193,7 +187,7 @@ void cmd_iac(int ctl, int hdev, char *opt) close(s); } -void cmd_auth(int ctl, int hdev, char *opt) +static void cmd_auth(int ctl, int hdev, char *opt) { struct hci_dev_req dr; @@ -204,12 +198,13 @@ void cmd_auth(int ctl, int hdev, char *opt) dr.dev_opt = AUTH_DISABLED; if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) { - printf("Can't set auth on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't set auth on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_encrypt(int ctl, int hdev, char *opt) +static void cmd_encrypt(int ctl, int hdev, char *opt) { struct hci_dev_req dr; @@ -220,12 +215,13 @@ void cmd_encrypt(int ctl, int hdev, char *opt) dr.dev_opt = ENCRYPT_DISABLED; if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) { - printf("Can't set encrypt on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't set encrypt on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_secmgr(int ctl, int hdev, char *opt) +static void cmd_secmgr(int ctl, int hdev, char *opt) { int val, s = hci_open_dev(hdev); @@ -235,13 +231,14 @@ void cmd_secmgr(int ctl, int hdev, char *opt) val = 0; if (ioctl(s, HCISETSECMGR, val) < 0) { - printf("Can't set security manager on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't set security manager on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } close(s); } -void cmd_up(int ctl, int hdev, char *opt) +static void cmd_up(int ctl, int hdev, char *opt) { int ret; @@ -249,42 +246,47 @@ void cmd_up(int ctl, int hdev, char *opt) if( (ret = ioctl(ctl, HCIDEVUP, hdev)) < 0 ) { if( errno == EALREADY ) return; - printf("Can't init device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't init device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } cmd_scan(ctl, hdev, "piscan"); } -void cmd_down(int ctl, int hdev, char *opt) +static void cmd_down(int ctl, int hdev, char *opt) { /* Stop HCI device */ if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) { - printf("Can't down device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't down device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_reset(int ctl, int hdev, char *opt) +static void cmd_reset(int ctl, int hdev, char *opt) { - /* Reset HCI device - if( ioctl(ctl, HCIDEVRESET, hdev) < 0 ){ - printf("Reset failed hci%d. %s(%d)\n", hdev, strerror(errno), errno); - exit(1); + /* Reset HCI device */ +#if 0 + if (ioctl(ctl, HCIDEVRESET, hdev) < 0 ){ + fprintf(stderr, "Reset failed for device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); } - */ +#endif cmd_down(ctl, hdev, "down"); cmd_up(ctl, hdev, "up"); } -void cmd_ptype(int ctl, int hdev, char *opt) +static void cmd_ptype(int ctl, int hdev, char *opt) { struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtoptype(opt, &dr.dev_opt)) { - if (ioctl(ctl, HCISETPTYPE, (unsigned long)&dr) < 0) { - printf("Can't set pkttype on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETPTYPE, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set pkttype on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { @@ -293,16 +295,16 @@ void cmd_ptype(int ctl, int hdev, char *opt) } } -void cmd_lp(int ctl, int hdev, char *opt) +static void cmd_lp(int ctl, int hdev, char *opt) { struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtolp(opt, &dr.dev_opt)) { - if (ioctl(ctl, HCISETLINKPOL, (unsigned long)&dr) < 0) { - printf("Can't set link policy on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETLINKPOL, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set link policy on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { @@ -311,16 +313,16 @@ void cmd_lp(int ctl, int hdev, char *opt) } } -void cmd_lm(int ctl, int hdev, char *opt) +static void cmd_lm(int ctl, int hdev, char *opt) { struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtolm(opt, &dr.dev_opt)) { - if (ioctl(ctl, HCISETLINKMODE, (unsigned long)&dr) < 0) { - printf("Can't set default link mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETLINKMODE, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set default link mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { @@ -329,7 +331,7 @@ void cmd_lm(int ctl, int hdev, char *opt) } } -void cmd_aclmtu(int ctl, int hdev, char *opt) +static void cmd_aclmtu(int ctl, int hdev, char *opt) { struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; @@ -343,14 +345,14 @@ void cmd_aclmtu(int ctl, int hdev, char *opt) *((uint16_t *)&dr.dev_opt + 1) = mtu; *((uint16_t *)&dr.dev_opt + 0) = mpkt; - if (ioctl(ctl, HCISETACLMTU, (unsigned long)&dr) < 0) { - printf("Can't set ACL mtu on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_scomtu(int ctl, int hdev, char *opt) +static void cmd_scomtu(int ctl, int hdev, char *opt) { struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; @@ -365,38 +367,39 @@ void cmd_scomtu(int ctl, int hdev, char *opt) *((uint16_t *)&dr.dev_opt + 0) = mpkt; if (ioctl(ctl, HCISETSCOMTU, (unsigned long)&dr) < 0) { - printf("Can't set SCO mtu on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_features(int ctl, int hdev, char *opt) +static void cmd_features(int ctl, int hdev, char *opt) { print_dev_hdr(&di); print_dev_features(&di, 1); } -void cmd_name(int ctl, int hdev, char *opt) +static void cmd_name(int ctl, int hdev, char *opt) { int s = hci_open_dev(hdev); if (s < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { - if (hci_write_local_name(s, opt, 1000) < 0) { - printf("Can't change local name on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (hci_write_local_name(s, opt, 2000) < 0) { + fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { char name[248]; int i; if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { - printf("Can't read local name on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } for (i = 0; i < 248 && name[i]; i++) @@ -540,7 +543,7 @@ static char *get_minor_device_name(int major, int minor) return "Unknown (reserved) minor device class"; } -void cmd_class(int ctl, int hdev, char *opt) +static void cmd_class(int ctl, int hdev, char *opt) { static char *services[] = { "Positioning", "Networking", @@ -561,21 +564,22 @@ void cmd_class(int ctl, int hdev, char *opt) int s = hci_open_dev(hdev); if (s < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { uint32_t cod = strtoul(opt, NULL, 16); - if (hci_write_class_of_dev(s, cod, 1000) < 0) { - printf("Can't write local class of device on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (hci_write_class_of_dev(s, cod, 2000) < 0) { + fprintf(stderr, "Can't write local class of device on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { uint8_t cls[3]; if (hci_read_class_of_dev(s, cls, 1000) < 0) { - printf("Can't read class of device on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read class of device on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } print_dev_hdr(&di); @@ -601,7 +605,7 @@ void cmd_class(int ctl, int hdev, char *opt) } } -void cmd_voice(int ctl, int hdev, char *opt) +static void cmd_voice(int ctl, int hdev, char *opt) { static char *icf[] = { "Linear", "u-Law", "A-Law", "Reserved" }; static char *idf[] = { "1's complement", "2's complement", "Sign-Magnitude", "Reserved" }; @@ -610,22 +614,23 @@ void cmd_voice(int ctl, int hdev, char *opt) int s = hci_open_dev(hdev); if (s < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { uint16_t vs = htobs(strtoul(opt, NULL, 16)); - if (0 > hci_write_voice_setting(s, vs, 1000)) { - printf("Can't write voice setting on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (hci_write_voice_setting(s, vs, 2000) < 0) { + fprintf(stderr, "Can't write voice setting on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { uint16_t vs; uint8_t ic; - if (0 > hci_read_voice_setting(s, &vs, 1000)) { - printf("Can't read voice setting on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (hci_read_voice_setting(s, &vs, 1000) < 0) { + fprintf(stderr, "Can't read voice setting on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } vs = htobs(vs); @@ -643,46 +648,48 @@ void cmd_voice(int ctl, int hdev, char *opt) } } -void cmd_version(int ctl, int hdev, char *opt) +static void cmd_version(int ctl, int hdev, char *opt) { struct hci_version ver; int dd; dd = hci_open_dev(hdev); if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (hci_read_local_version(dd, &ver, 1000) < 0) { - printf("Can't read version info hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read version info hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } print_dev_hdr(&di); - printf( "\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n" + printf("\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n" "\tManufacturer: %s (%d)\n", - hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, - lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, + hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, + lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, bt_compidtostr(ver.manufacturer), ver.manufacturer); } -void cmd_inq_mode(int ctl, int hdev, char *opt) +static void cmd_inq_mode(int ctl, int hdev, char *opt) { int dd; dd = hci_open_dev(hdev); if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { uint8_t mode = atoi(opt); - if (hci_write_inquiry_mode(dd, mode, 1000) < 0) { - printf("Can't set inquiry mode on hci%d. %s(%d)\n", + if (hci_write_inquiry_mode(dd, mode, 2000) < 0) { + fprintf(stderr, "Can't set inquiry mode on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -690,8 +697,8 @@ void cmd_inq_mode(int ctl, int hdev, char *opt) uint8_t mode; if (hci_read_inquiry_mode(dd, &mode, 1000) < 0) { - printf("Can't read inquiry mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read inquiry mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -701,12 +708,14 @@ void cmd_inq_mode(int ctl, int hdev, char *opt) } } -void cmd_inq_parms(int ctl, int hdev, char *opt) +static void cmd_inq_parms(int ctl, int hdev, char *opt) { struct hci_request rq; int s; + if ((s = hci_open_dev(hdev)) < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -735,8 +744,8 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) if (interval < 0x12 || interval > 0x1000) printf("Warning: inquiry interval out of range!\n"); - if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't set inquiry parameters name on hci%d. %s(%d)\n", + if (hci_send_req(s, &rq, 2000) < 0) { + fprintf(stderr, "Can't set inquiry parameters name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -750,12 +759,12 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) rq.rlen = READ_INQ_ACTIVITY_RP_SIZE; if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't read inquiry parameters on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read inquiry parameters on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (rp.status) { - printf("Read inquiry parameters on hci%d returned status %d\n", + printf("Read inquiry parameters on hci%d returned status %d\n", hdev, rp.status); exit(1); } @@ -768,12 +777,14 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) } } -void cmd_page_parms(int ctl, int hdev, char *opt) +static void cmd_page_parms(int ctl, int hdev, char *opt) { struct hci_request rq; int s; + if ((s = hci_open_dev(hdev)) < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -802,8 +813,8 @@ void cmd_page_parms(int ctl, int hdev, char *opt) if (interval < 0x12 || interval > 0x1000) printf("Warning: page interval out of range!\n"); - if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't set page parameters name on hci%d. %s(%d)\n", + if (hci_send_req(s, &rq, 2000) < 0) { + fprintf(stderr, "Can't set page parameters name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -817,12 +828,12 @@ void cmd_page_parms(int ctl, int hdev, char *opt) rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE; if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't read page parameters on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read page parameters on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (rp.status) { - printf("Read page parameters on hci%d returned status %d\n", + printf("Read page parameters on hci%d returned status %d\n", hdev, rp.status); exit(1); } @@ -835,12 +846,14 @@ void cmd_page_parms(int ctl, int hdev, char *opt) } } -void cmd_page_to(int ctl, int hdev, char *opt) +static void cmd_page_to(int ctl, int hdev, char *opt) { struct hci_request rq; int s; + if ((s = hci_open_dev(hdev)) < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -865,8 +878,8 @@ void cmd_page_to(int ctl, int hdev, char *opt) if (timeout < 0x01 || timeout > 0xFFFF) printf("Warning: page timeout out of range!\n"); - if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't set page timeout on hci%d. %s(%d)\n", + if (hci_send_req(s, &rq, 2000) < 0) { + fprintf(stderr, "Can't set page timeout on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -880,12 +893,12 @@ void cmd_page_to(int ctl, int hdev, char *opt) rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE; if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't read page timeout on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read page timeout on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (rp.status) { - printf("Read page timeout on hci%d returned status %d\n", + printf("Read page timeout on hci%d returned status %d\n", hdev, rp.status); exit(1); } @@ -897,21 +910,22 @@ void cmd_page_to(int ctl, int hdev, char *opt) } } -void cmd_afh_mode(int ctl, int hdev, char *opt) +static void cmd_afh_mode(int ctl, int hdev, char *opt) { int dd; dd = hci_open_dev(hdev); if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { uint8_t mode = atoi(opt); - if (hci_write_afh_mode(dd, mode, 1000) < 0) { - printf("Can't set AFH mode on hci%d. %s(%d)\n", + if (hci_write_afh_mode(dd, mode, 2000) < 0) { + fprintf(stderr, "Can't set AFH mode on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -919,8 +933,8 @@ void cmd_afh_mode(int ctl, int hdev, char *opt) uint8_t mode; if (hci_read_afh_mode(dd, &mode, 1000) < 0) { - printf("Can't read AFH mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read AFH mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -943,7 +957,7 @@ static void print_rev_ericsson(int dd) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\nCan't read revision info. %s(%d)\n", strerror(errno), errno); + printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno); return; } @@ -989,7 +1003,7 @@ static void print_rev_digianswer(int dd) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\nCan't read revision info. %s(%d)\n", strerror(errno), errno); + printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno); return; } @@ -1016,13 +1030,14 @@ static void cmd_revision(int ctl, int hdev, char *opt) dd = hci_open_dev(hdev); if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); return; } if (hci_read_local_version(dd, &ver, 1000) < 0) { - printf("Can't read version info hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + hdev, strerror(errno), errno); return; } @@ -1051,7 +1066,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) return; } -void print_dev_hdr(struct hci_dev_info *di) +static void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; char addr[18]; @@ -1068,7 +1083,7 @@ void print_dev_hdr(struct hci_dev_info *di) di->sco_mtu, di->sco_pkts); } -void print_dev_info(int ctl, struct hci_dev_info *di) +static void print_dev_info(int ctl, struct hci_dev_info *di) { struct hci_dev_stats *st = &di->stat; @@ -1098,7 +1113,7 @@ void print_dev_info(int ctl, struct hci_dev_info *di) printf("\n"); } -struct { +static struct { char *cmd; void (*func)(int ctl, int hdev, char *opt); char *opt; @@ -1138,7 +1153,7 @@ struct { { NULL, NULL, 0 } }; -void usage(void) +static void usage(void) { int i; @@ -1194,7 +1209,7 @@ int main(int argc, char **argv, char **env) di.dev_id = atoi(argv[0] + 3); argc--; argv++; - if (ioctl(ctl, HCIGETDEVINFO, (void*)&di)) { + if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) { perror("Can't get device info"); exit(1); } diff --git a/tools/hcitool.c b/tools/hcitool.c index 8bb68427..99262f41 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,36 +33,24 @@ #endif #include -#include -#include -#include -#include -#include #include -#include - -#include -#include +#include +#include #include -#include #include #include -#include #include #include #include -extern int optind,opterr,optopt; -extern char *optarg; - #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) static void usage(void); static int dev_info(int s, int dev_id, long arg) { - struct hci_dev_info di = {dev_id: dev_id}; + struct hci_dev_info di = { dev_id: dev_id }; char addr[18]; if (ioctl(s, HCIGETDEVINFO, (void *) &di)) @@ -155,11 +143,11 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) /* Display local devices */ static struct option dev_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + {0, 0, 0, 0 } }; -static char *dev_help = +static char *dev_help = "Usage:\n" "\tdev\n"; @@ -181,14 +169,14 @@ static void cmd_dev(int dev_id, int argc, char **argv) /* Inquiry */ static struct option inq_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } }; -static char *inq_help = +static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" "\t [--numrsp=N] specify maximum number of inquiry responses\n" @@ -246,14 +234,14 @@ static void cmd_inq(int dev_id, int argc, char **argv) /* Device scanning */ static struct option scan_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } }; -static char *scan_help = +static char *scan_help = "Usage:\n" "\tscan [--length=N] [--numrsp=N] [--flush]\n"; @@ -326,8 +314,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) /* Remote name */ static struct option name_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; static char *name_help = @@ -380,11 +368,11 @@ static void cmd_name(int dev_id, int argc, char **argv) /* Info about remote device */ static struct option info_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *info_help = +static char *info_help = "Usage:\n" "\tinfo \n"; @@ -494,11 +482,11 @@ static void cmd_info(int dev_id, int argc, char **argv) /* Send arbitrary HCI commands */ static struct option cmd_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *cmd_help = +static char *cmd_help = "Usage:\n" "\tcmd [parameters]\n" "Example:\n" @@ -584,11 +572,11 @@ static void cmd_cmd(int dev_id, int argc, char **argv) /* Display active connections */ static struct option con_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *con_help = +static char *con_help = "Usage:\n" "\tcon\n"; @@ -611,13 +599,13 @@ static void cmd_con(int dev_id, int argc, char **argv) /* Create connection */ static struct option cc_options[] = { - {"help", 0,0, 'h'}, - {"role", 1,0, 'r'}, - {"ptype", 1,0, 'p'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "role", 1, 0, 'r' }, + { "ptype", 1, 0, 'p' }, + { 0, 0, 0, 0 } }; -static char *cc_help = +static char *cc_help = "Usage:\n" "\tcc [--role=m|s] [--ptype=pkt_types] \n" "Example:\n" @@ -682,11 +670,11 @@ static void cmd_cc(int dev_id, int argc, char **argv) /* Close connection */ static struct option dc_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *dc_help = +static char *dc_help = "Usage:\n" "\tdc \n"; @@ -749,11 +737,11 @@ static void cmd_dc(int dev_id, int argc, char **argv) /* Role switch */ static struct option sr_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *sr_help = +static char *sr_help = "Usage:\n" "\tsr \n"; @@ -816,11 +804,11 @@ static void cmd_sr(int dev_id, int argc, char **argv) /* Read RSSI */ static struct option rssi_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *rssi_help = +static char *rssi_help = "Usage:\n" "\trssi \n"; @@ -904,11 +892,11 @@ static void cmd_rssi(int dev_id, int argc, char **argv) /* Get link quality */ static struct option lq_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *lq_help = +static char *lq_help = "Usage:\n" "\tlq \n"; @@ -992,11 +980,11 @@ static void cmd_lq(int dev_id, int argc, char **argv) /* Get transmit power level */ static struct option tpl_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *tpl_help = +static char *tpl_help = "Usage:\n" "\ttpl [type]\n"; @@ -1081,11 +1069,11 @@ static void cmd_tpl(int dev_id, int argc, char **argv) /* Get AFH channel map */ static struct option afh_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *afh_help = +static char *afh_help = "Usage:\n" "\tafh \n"; @@ -1162,11 +1150,11 @@ static void cmd_afh(int dev_id, int argc, char **argv) /* Set connection packet type */ static struct option cpt_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *cpt_help = +static char *cpt_help = "Usage:\n" "\tcpt \n"; @@ -1246,11 +1234,11 @@ static void cmd_cpt(int dev_id, int argc, char **argv) /* Get/Set link supervision timeout */ static struct option lst_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *lst_help = +static char *lst_help = "Usage:\n" "\tlst [new value in slots]\n"; @@ -1355,11 +1343,11 @@ static void cmd_lst(int dev_id, int argc, char **argv) /* Request authentication */ static struct option auth_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *auth_help = +static char *auth_help = "Usage:\n" "\tauth \n"; @@ -1423,11 +1411,11 @@ static void cmd_auth(int dev_id, int argc, char **argv) /* Activate encryption */ static struct option enc_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *enc_help = +static char *enc_help = "Usage:\n" "\tenc [encrypt enable]\n"; @@ -1494,11 +1482,11 @@ static void cmd_enc(int dev_id, int argc, char **argv) /* Change connection link key */ static struct option key_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *key_help = +static char *key_help = "Usage:\n" "\tkey \n"; @@ -1606,9 +1594,9 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } }; int main(int argc, char **argv) -- cgit From 9a25e71b182ed141be638d5ccf618ecbf6d1d836 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 13:33:14 +0000 Subject: More cleanups --- tools/hciconfig.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 11590b97..1a8f35d8 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -66,14 +66,14 @@ static void print_dev_list(int ctl, int flags) dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(ctl, HCIGETDEVLIST, (void *) dl)) { + if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) { perror("Can't get device list"); exit(1); } for (i = 0; i< dl->dev_num; i++) { di.dev_id = (dr+i)->dev_id; - if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) + if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) continue; print_dev_info(ctl, &di); } @@ -128,11 +128,11 @@ static void cmd_scan(int ctl, int hdev, char *opt) dr.dev_id = hdev; dr.dev_opt = SCAN_DISABLED; - if( !strcmp(opt, "iscan") ) + if (!strcmp(opt, "iscan")) dr.dev_opt = SCAN_INQUIRY; - else if( !strcmp(opt, "pscan") ) + else if (!strcmp(opt, "pscan")) dr.dev_opt = SCAN_PAGE; - else if( !strcmp(opt, "piscan") ) + else if (!strcmp(opt, "piscan")) dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) { @@ -240,11 +240,9 @@ static void cmd_secmgr(int ctl, int hdev, char *opt) static void cmd_up(int ctl, int hdev, char *opt) { - int ret; - /* Start HCI device */ - if( (ret = ioctl(ctl, HCIDEVUP, hdev)) < 0 ) { - if( errno == EALREADY ) + if (ioctl(ctl, HCIDEVUP, hdev) < 0) { + if (errno == EALREADY) return; fprintf(stderr, "Can't init device hci%d: %s (%d)\n", hdev, strerror(errno), errno); @@ -366,7 +364,7 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) *((uint16_t *)&dr.dev_opt + 1) = mtu; *((uint16_t *)&dr.dev_opt + 0) = mpkt; - if (ioctl(ctl, HCISETSCOMTU, (unsigned long)&dr) < 0) { + if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); @@ -1215,7 +1213,7 @@ int main(int argc, char **argv, char **env) } while (argc > 0) { - for (i=0; command[i].cmd; i++) { + for (i = 0; command[i].cmd; i++) { if (strncmp(command[i].cmd, *argv, 5)) continue; -- cgit From f0e34fdbb90a899cca2ae6b1d75549d2050f9855 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 18:46:46 +0000 Subject: Add Sitecom CN-504 Bluetooth PCMCIA card --- tools/hciattach.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index ac94c41e..e730ab7d 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,21 +33,18 @@ #endif #include -#include +#include +#include #include +#include #include #include -#include #include -#include -#include #include -#include - +#include +#include #include #include -#include -#include #include #include @@ -845,6 +842,8 @@ struct uart_t uart[] = { /* Zoom Bluetooth PCMCIA Card */ { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + /* Sitecom CN-504 PCMCIA Card */ + { "sitecom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, { NULL, 0 } }; -- cgit From 818f37527b66b1bd8c177759a8c7710882030093 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 20:21:51 +0000 Subject: Use library functions for RSSI and link quality --- tools/hcitool.c | 48 +++++++----------------------------------------- 1 file changed, 7 insertions(+), 41 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 99262f41..ffa98536 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -815,10 +815,8 @@ static char *rssi_help = static void cmd_rssi(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_rssi_rp rp; bdaddr_t bdaddr; - uint16_t handle; + int8_t rssi; int opt, dd; for_each_opt(opt, rssi_options, NULL) { @@ -863,27 +861,12 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_RSSI_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_rssi(dd, htobs(cr->conn_info->handle), &rssi, 1000) < 0) { perror("Read RSSI failed"); exit(1); } - if (rp.status) { - printf("Read RSSI returned (error) status 0x%2.2X\n", - rp.status); - exit(1); - } - printf("RSSI return value: %d\n", rp.rssi); + printf("RSSI return value: %d\n", rssi); close(dd); free(cr); @@ -903,10 +886,8 @@ static char *lq_help = static void cmd_lq(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - get_link_quality_rp rp; bdaddr_t bdaddr; - uint16_t handle; + uint8_t lq; int opt, dd; for_each_opt(opt, lq_options, NULL) { @@ -951,27 +932,12 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_GET_LINK_QUALITY; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = GET_LINK_QUALITY_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { - perror("HCI get_link_quality request failed"); + if (hci_read_link_quality(dd, htobs(cr->conn_info->handle), &lq, 1000) < 0) { + perror("HCI read_link_quality request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } - printf("Link quality: %d\n", rp.link_quality); + printf("Link quality: %d\n", lq); close(dd); free(cr); -- cgit From 1b71ff969ad17bd4e1265b6cc1d06ca38afc6c27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:48:24 +0000 Subject: Use library function for link supervision timeout --- tools/hcitool.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index ffa98536..8aef142b 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1211,11 +1211,8 @@ static char *lst_help = static void cmd_lst(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_link_supervision_timeout_rp rp; - write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; - uint16_t handle; + uint16_t timeout; int opt, dd; for_each_opt(opt, lst_options, NULL) { @@ -1260,43 +1257,23 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - if (argc == 1) { - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), &timeout, 1000) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_link_supervision_timeout failed (0x%2.2X)\n", - rp.status); - exit(1); - } - if (rp.link_sup_to) + timeout = btohs(timeout); + + if (timeout) printf("Link supervision timeout: %u slots (%.2f msec)\n", - rp.link_sup_to, (float)rp.link_sup_to * 0.625); + timeout, (float) timeout * 0.625); else printf("Link supervision timeout never expires\n"); } else { - cp.handle = htobs(cr->conn_info->handle); - cp.link_sup_to = strtol(argv[1], NULL, 10); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &cp; - rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + timeout = btohs(strtol(argv[1], NULL, 10)); - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), timeout, 1000) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); } -- cgit From cbbc9f09bb9b41caa5ee9fa751a80d16d34a4bda Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:58:13 +0000 Subject: Use library function for reading the transmit power level --- tools/hcitool.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8aef142b..7d965dd6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -957,10 +957,8 @@ static char *tpl_help = static void cmd_tpl(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_transmit_power_level_cp cp; - read_transmit_power_level_rp rp; bdaddr_t bdaddr; + uint8_t type, level; int opt, dd; for_each_opt(opt, tpl_options, NULL) { @@ -979,7 +977,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) } str2ba(argv[0], &bdaddr); - cp.type = (argc > 1) ? atoi(argv[1]) : 0; + type = (argc > 1) ? atoi(argv[1]) : 0; if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -1005,28 +1003,14 @@ static void cmd_tpl(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - cp.handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; - rq.cparam = &cp; - rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; - rq.rparam = &rp; - rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_transmit_power_level(dd, htobs(cr->conn_info->handle), type, &level, 1000) < 0) { perror("HCI read transmit power level request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_transmit_power_level cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } printf("%s transmit power level: %d\n", - (cp.type == 0) ? "Current" : "Maximum", rp.level); + (type == 0) ? "Current" : "Maximum", level); close(dd); free(cr); -- cgit From 76b0ca8e1c813892561ddae4593e024659783068 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Jan 2005 00:14:50 +0000 Subject: Fix security filter definitions --- tools/hcisecfilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index fd296afd..d3c658c8 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -116,7 +116,7 @@ int main(void) memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); hci_set_bit(OCF_RESET_FAILED_CONTACT_COUNTER, ocf_mask); - hci_set_bit(OCF_GET_LINK_QUALITY, ocf_mask); + hci_set_bit(OCF_READ_LINK_QUALITY, ocf_mask); hci_set_bit(OCF_READ_RSSI, ocf_mask); printf("OGF_STATUS_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", -- cgit From fefb12aae57e186c00a50a87a3725f8657fd95e2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Jan 2005 02:46:59 +0000 Subject: Add command for reading the clock offset --- tools/hcitool.1 | 4 +++ tools/hcitool.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 95 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index c4c69b87..07f41421 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -170,6 +170,10 @@ Enable or disable the encryption for the device with Bluetooth address .BI key " " Change the connection link key for the device with Bluetooth address .IR bdaddr . +.TP +.BI clkoff " " +Read the clock offset for the device with Bluetooth address +.IR bdaddr . .SH AUTHORS Written by Maxim Krasnyansky and Marcel Holtmann .PP diff --git a/tools/hcitool.c b/tools/hcitool.c index 7d965dd6..9f69ed01 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1474,30 +1474,102 @@ static void cmd_key(int dev_id, int argc, char **argv) free(cr); } +/* Read clock offset */ + +static struct option clkoff_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *clkoff_help = + "Usage:\n" + "\tclkoff \n"; + +static void cmd_clkoff(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t offset; + int opt, dd; + + for_each_opt(opt, clkoff_options, NULL) { + switch (opt) { + default: + printf(clkoff_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(clkoff_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_read_clock_offset(dd, htobs(cr->conn_info->handle), &offset, 1000) < 0) { + perror("Reading clock offset failed"); + exit(1); + } + + printf("Clock offset: 0x%4.4x\n", btohs(offset)); + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, "Display local devices" }, - { "inq", cmd_inq, "Inquire remote devices" }, - { "scan", cmd_scan, "Scan for remote devices" }, - { "name", cmd_name, "Get name from remote device" }, - { "info", cmd_info, "Get information from remote device" }, - { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, - { "con", cmd_con, "Display active connections" }, - { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, - { "sr", cmd_sr, "Switch master/slave role" }, - { "cpt", cmd_cpt, "Change connection packet type" }, - { "rssi", cmd_rssi, "Display connection RSSI" }, - { "lq", cmd_lq, "Display link quality" }, - { "tpl", cmd_tpl, "Display transmit power level" }, - { "afh", cmd_afh, "Display AFH channel map" }, - { "lst", cmd_lst, "Set/display link supervision timeout" }, - { "auth", cmd_auth, "Request authentication" }, - { "enc", cmd_enc, "Set connection encryption" }, - { "key", cmd_key, "Change connection link key" }, + { "dev", cmd_dev, "Display local devices" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, + { "cpt", cmd_cpt, "Change connection packet type" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_lq, "Display link quality" }, + { "tpl", cmd_tpl, "Display transmit power level" }, + { "afh", cmd_afh, "Display AFH channel map" }, + { "lst", cmd_lst, "Set/display link supervision timeout" }, + { "auth", cmd_auth, "Request authentication" }, + { "enc", cmd_enc, "Set connection encryption" }, + { "key", cmd_key, "Change connection link key" }, + { "clkoff", cmd_clkoff, "Read clock offset" }, { NULL, NULL, 0 } }; -- cgit From 30fa99ad8cc79b6e4cb4620a31510d5a6cd31acd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Jan 2005 21:41:40 +0000 Subject: Add command for reading the clock --- tools/hcitool.1 | 9 +++++++ tools/hcitool.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index 07f41421..d863e7d1 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -174,6 +174,15 @@ Change the connection link key for the device with Bluetooth address .BI clkoff " " Read the clock offset for the device with Bluetooth address .IR bdaddr . +.TP +.BI clock " [which clock]" +Read the clock for the device with Bluetooth address +.IR bdaddr . +The clock can be +.BR 0 +for the local clock or +.BR 1 +for the piconet clock (which is default). .SH AUTHORS Written by Maxim Krasnyansky and Marcel Holtmann .PP diff --git a/tools/hcitool.c b/tools/hcitool.c index 9f69ed01..8b7131a0 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1545,6 +1545,84 @@ static void cmd_clkoff(int dev_id, int argc, char **argv) free(cr); } +/* Read clock */ + +static struct option clock_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *clock_help = + "Usage:\n" + "\tclock [which clock]\n"; + +static void cmd_clock(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint8_t which; + uint32_t clock; + uint16_t accuracy; + int opt, dd; + + for_each_opt(opt, clock_options, NULL) { + switch (opt) { + default: + printf(clock_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(clock_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + which = (argc > 1) ? atoi(argv[1]) : 0x01; + + if (hci_read_clock(dd, htobs(cr->conn_info->handle), which, &clock, &accuracy, 1000) < 0) { + perror("Reading clock failed"); + exit(1); + } + + accuracy = btohs(accuracy); + + printf("Clock: 0x%4.4x\n", btohl(clock)); + printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1570,6 +1648,7 @@ static struct { { "enc", cmd_enc, "Set connection encryption" }, { "key", cmd_key, "Change connection link key" }, { "clkoff", cmd_clkoff, "Read clock offset" }, + { "clock", cmd_clock, "Read local or remote clock" }, { NULL, NULL, 0 } }; -- cgit From d06620c3403ca50e6d8f9f0cba4e6e8c0486438e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Jan 2005 03:15:10 +0000 Subject: Add the build ids for the sniffer firmwares --- tools/csr.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index ca28ef2f..d7bb65ae 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -266,6 +266,47 @@ static struct { { 1734, "HCI 18.3" }, { 1735, "HCI 18.3" }, { 1737, "HCI 18.3" }, + { 195, "Sniff 1 (2001-11-27)" }, + { 220, "Sniff 2 (2002-01-03)" }, + { 269, "Sniff 3 (2002-02-22)" }, + { 270, "Sniff 4 (2002-02-26)" }, + { 284, "Sniff 5 (2002-03-12)" }, + { 292, "Sniff 6 (2002-03-20)" }, + { 305, "Sniff 7 (2002-04-12)" }, + { 306, "Sniff 8 (2002-04-12)" }, + { 343, "Sniff 9 (2002-05-02)" }, + { 346, "Sniff 10 (2002-05-03)" }, + { 355, "Sniff 11 (2002-05-16)" }, + { 256, "Sniff 11 (2002-05-16)" }, + { 390, "Sniff 12 (2002-06-26)" }, + { 450, "Sniff 13 (2002-08-16)" }, + { 451, "Sniff 13 (2002-08-16)" }, + { 533, "Sniff 14 (2002-10-11)" }, + { 580, "Sniff 15 (2002-11-14)" }, + { 623, "Sniff 16 (2002-12-12)" }, + { 678, "Sniff 17 (2003-01-29)" }, + { 847, "Sniff 18 (2003-04-17)" }, + { 876, "Sniff 19 (2003-06-10)" }, + { 997, "Sniff 22 (2003-09-05)" }, + { 1027, "Sniff 23 (2003-10-03)" }, + { 1029, "Sniff 24 (2003-10-03)" }, + { 1112, "Sniff 25 (2003-12-03)" }, + { 1113, "Sniff 25 (2003-12-03)" }, + { 1133, "Sniff 26 (2003-12-18)" }, + { 1134, "Sniff 26 (2003-12-18)" }, + { 1223, "Sniff 27 (2004-03-08)" }, + { 1224, "Sniff 27 (2004-03-08)" }, + { 1319, "Sniff 31 (2004-04-22)" }, + { 1320, "Sniff 31 (2004-04-22)" }, + { 1427, "Sniff 34 (2004-06-16)" }, + { 1508, "Sniff 35 (2004-07-19)" }, + { 1509, "Sniff 35 (2004-07-19)" }, + { 1587, "Sniff 36 (2004-08-18)" }, + { 1588, "Sniff 36 (2004-08-18)" }, + { 1641, "Sniff 37 (2004-09-16)" }, + { 1642, "Sniff 37 (2004-09-16)" }, + { 1699, "Sniff 38 (2004-10-07)" }, + { 1700, "Sniff 38 (2004-10-07)" }, { 0, } }; -- cgit From c15fb910d23b698af183312eb05f1d1038e88259 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Jan 2005 17:05:35 +0000 Subject: Don't set inquiry scan or page scan on raw devices --- tools/hciconfig.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1a8f35d8..d24faf73 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -248,6 +248,10 @@ static void cmd_up(int ctl, int hdev, char *opt) hdev, strerror(errno), errno); exit(1); } + if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) + return; + if (hci_test_bit(HCI_RAW, &di.flags)) + return; cmd_scan(ctl, hdev, "piscan"); } -- cgit From 7a23b4eeb7f7fe7b2becd884fa1e9c5db5deedea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Jan 2005 17:43:16 +0000 Subject: Support data sizes bigger than 2048 bytes --- tools/l2ping.c | 123 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 51 deletions(-) (limited to 'tools') diff --git a/tools/l2ping.c b/tools/l2ping.c index 45ddbe92..0e7a4be1 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,37 +33,32 @@ #endif #include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include - #include +#include +#include #include /* Defaults */ -bdaddr_t bdaddr; -int size = 20; -int ident = 200; -int delay = 1; -int count = -1; -int timeout = 10; +static bdaddr_t bdaddr; +static int size = 20; +static int ident = 200; +static int delay = 1; +static int count = -1; +static int timeout = 10; /* Stats */ -int sent_pkt = 0, recv_pkt = 0; +static int sent_pkt = 0; +static int recv_pkt = 0; static float tv2fl(struct timeval tv) { @@ -79,53 +74,77 @@ static void stat(int sig) static void ping(char *svr) { - struct sockaddr_l2 addr; struct sigaction sa; - char buf[2048]; + struct sockaddr_l2 addr; + socklen_t optlen; + unsigned char *buf; char str[18]; - int s, i, opt, lost; + int i, sk, lost; uint8_t id; memset(&sa, 0, sizeof(sa)); sa.sa_handler = stat; sigaction(SIGINT, &sa, NULL); - if ((s = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { - perror("Can't create socket."); + buf = malloc(L2CAP_CMD_HDR_SIZE + size); + if (!buf) { + perror("Can't allocate buffer"); + exit(1); + } + + /* Create socket */ + sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); + if (sk < 0) { + perror("Can't create socket"); + free(buf); exit(1); } + /* Bind to local address */ memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; - addr.l2_bdaddr = bdaddr; - if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Can't bind socket."); + bacpy(&addr.l2_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't bind socket"); + close(sk); + free(buf); exit(1); } + /* Connect to remote device */ + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; str2ba(svr, &addr.l2_bdaddr); - if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Can't connect."); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't connect"); + close(sk); + free(buf); exit(1); } /* Get local address */ - opt = sizeof(addr); - if (getsockname(s, (struct sockaddr *)&addr, &opt) < 0) { - perror("Can't get local address."); + memset(&addr, 0, sizeof(addr)); + optlen = sizeof(addr); + + if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) { + perror("Can't get local address"); + close(sk); + free(buf); exit(1); } - ba2str(&addr.l2_bdaddr, str); + ba2str(&addr.l2_bdaddr, str); printf("Ping: %s from %s (data size %d) ...\n", svr, str, size); /* Initialize buffer */ - for (i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) - buf[i] = (i % 40) + 'A'; + for (i = 0; i < size; i++) + buf[L2CAP_CMD_HDR_SIZE + i] = (i % 40) + 'A'; id = ident; - while( count == -1 || count-- > 0 ){ + while (count == -1 || count-- > 0) { struct timeval tv_send, tv_recv, tv_diff; l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; @@ -137,7 +156,7 @@ static void ping(char *svr) gettimeofday(&tv_send, NULL); /* Send Echo Request */ - if (send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0) { + if (send(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0) <= 0) { perror("Send failed"); exit(1); } @@ -146,9 +165,11 @@ static void ping(char *svr) lost = 0; while (1) { struct pollfd pf[1]; - register int err; + int err; + + pf[0].fd = sk; + pf[0].events = POLLIN; - pf[0].fd = s; pf[0].events = POLLIN; if ((err = poll(pf, 1, timeout * 1000)) < 0) { perror("Poll failed"); exit(1); @@ -159,7 +180,7 @@ static void ping(char *svr) break; } - if ((err = recv(s, buf, sizeof(buf), 0)) < 0) { + if ((err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0)) < 0) { perror("Recv failed"); exit(1); } @@ -210,21 +231,25 @@ static void usage(void) { printf("l2ping - L2CAP ping\n"); printf("Usage:\n"); - printf("\tl2ping [-S source addr] [-s size] [-c count] [-t timeout] [-f] \n"); + printf("\tl2ping [-i device] [-s size] [-c count] [-t timeout] [-f] \n"); } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc, char *argv[]) { - register int opt; + int opt; /* Default options */ bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"s:c:t:fS:")) != EOF) { + while ((opt=getopt(argc,argv,"i:s:c:t:f")) != EOF) { switch(opt) { + case 'i': + if (!strncasecmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); + break; + case 'f': /* Kinda flood ping */ delay = 0; @@ -242,10 +267,6 @@ int main(int argc, char *argv[]) size = atoi(optarg); break; - case 'S': - str2ba(optarg, &bdaddr); - break; - default: usage(); exit(1); -- cgit From 591e892366b6ccf2d7c765c47741794cb8a30e42 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 30 Jan 2005 20:38:04 +0000 Subject: Add Billionton PCMCIA card --- tools/hciattach.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index e730ab7d..33ecdf03 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -796,54 +796,58 @@ static int st(int fd, struct uart_t *u, struct termios *ti) } struct uart_t uart[] = { - { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, - { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, - { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, digi }, - { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, texas}, + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, digi }, + { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, texas }, - { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ - { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ - { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, /* BrainBoxes PCMCIA card (BL620) */ - { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 115200, 460800, FLOW_CTL, csr }, + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 115200, 460800, FLOW_CTL, csr }, /* Silicon Wave kits */ - { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, /* ST Microelectronics minikits based on STLC2410/STLC2415 */ - { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, st }, + { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, st }, /* Sphinx Electronics PICO Card */ - { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* Inventel BlueBird Module */ - { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* COM One Platinium Bluetooth PC Card */ - { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* TDK Bluetooth PC Card and IBM Bluetooth PC Card II */ - { "tdk", 0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "tdk", 0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* Socket Bluetooth CF Card (Rev G) */ - { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, + { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, /* 3Com Bluetooth Card (Version 3.0) */ - { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, /* AmbiCom BT2000C Bluetooth PC/CF Card */ - { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, + { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, /* Zoom Bluetooth PCMCIA Card */ - { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* Sitecom CN-504 PCMCIA Card */ - { "sitecom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "sitecom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + + /* Billionton PCBTC1 PCMCIA Card */ + { "billionton", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { NULL, 0 } }; -- cgit From 4ee1f291862c7bc69e5099908f5f5dd619921975 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Jan 2005 05:45:39 +0000 Subject: Don't show extended information for raw devices --- tools/hciconfig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index d24faf73..61e4d3cd 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1099,7 +1099,8 @@ static void print_dev_info(int ctl, struct hci_dev_info *di) printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n", st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); - if (all) { + if (all && !hci_test_bit(HCI_RAW, &di->flags) && + bacmp(&di->bdaddr, BDADDR_ANY)) { print_dev_features(di, 0); print_pkt_type(di); print_link_policy(di); -- cgit From e4b4cf97715729084740673c44dfabcf8b29fcfe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Feb 2005 11:37:23 +0000 Subject: Fix ident calculation --- tools/l2ping.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/l2ping.c b/tools/l2ping.c index 0e7a4be1..01b1f21b 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -193,7 +193,7 @@ static void ping(char *svr) cmd->len = btohs(cmd->len); /* Check for our id */ - if( cmd->ident != id ) + if (cmd->ident != id) continue; /* Check type */ @@ -218,7 +218,7 @@ static void ping(char *svr) if (delay) sleep(delay); } else { - printf("no response from %s: id %d\n", svr, id); + printf("no response from %s: id %d\n", svr, id - ident); } if (++id > 254) -- cgit From 508afd448b78e3d4c0b531c4696c5e906f259787 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 21:08:29 +0000 Subject: Update display of Broadcom firmware version --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 61e4d3cd..1cc698d8 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1014,7 +1014,7 @@ static void print_rev_digianswer(int dd) static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) { - printf("\tFirmware %d.%d.%03d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); + printf("\tFirmware %d.%d / %d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); } static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver) -- cgit From d67817be8163beb8d69d97934eb998d269221a14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Feb 2005 04:17:52 +0000 Subject: Use the clock offset when getting the remote names --- tools/hcitool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 8b7131a0..57d23e6a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -301,7 +301,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, + htobs((info+i)->clock_offset), sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); @@ -662,7 +663,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) } if (hci_create_connection(dd, &bdaddr, htobs(ptype), - 0, role, &handle, 25000) < 0) + htobs(0x0000), role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From 8aebcde5f68394bc2cd27855971d26ce52da0500 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Feb 2005 05:02:24 +0000 Subject: Handle the valid bit of the clock offset --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 57d23e6a..766c084e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -223,7 +223,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", - addr, (info+i)->clock_offset, + addr, btohs((info+i)->clock_offset), (info+i)->dev_class[2], (info+i)->dev_class[1], (info+i)->dev_class[0]); @@ -302,7 +302,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - htobs((info+i)->clock_offset), sizeof(name), name, 100000) < 0) + (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); -- cgit From 8fb7ab625a24c48e7176b7e6995456080f997bf0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 17 Feb 2005 01:30:41 +0000 Subject: Update build ids for HCI 19.2 --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index d7bb65ae..e55b48a5 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -266,6 +266,8 @@ static struct { { 1734, "HCI 18.3" }, { 1735, "HCI 18.3" }, { 1737, "HCI 18.3" }, + { 1915, "HCI 19.2" }, + { 1916, "HCI 19.2" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 337a9c4da82ea321a6613dd7c44e451e681a4a4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:39:41 +0000 Subject: Add build ids for new sniffer firmwares --- tools/csr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index e55b48a5..e3353cdc 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -309,6 +309,11 @@ static struct { { 1642, "Sniff 37 (2004-09-16)" }, { 1699, "Sniff 38 (2004-10-07)" }, { 1700, "Sniff 38 (2004-10-07)" }, + { 1752, "Sniff 39 (2004-11-02)" }, + { 1753, "Sniff 39 (2004-11-02)" }, + { 1759, "Sniff 40 (2004-11-03)" }, + { 1760, "Sniff 40 (2004-11-03)" }, + { 1761, "Sniff 40 (2004-11-03)" }, { 0, } }; -- cgit From 05ec11bf58edbacb68ebf4cd4b629df697224d6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:41:02 +0000 Subject: The transmit power level is a signed integer value --- tools/hcitool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 766c084e..225977b7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -959,7 +959,8 @@ static void cmd_tpl(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; - uint8_t type, level; + uint8_t type; + int8_t level; int opt, dd; for_each_opt(opt, tpl_options, NULL) { -- cgit From 354b825e585790a15fc07ca382540739cbb3c155 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 15:11:32 +0000 Subject: Use pscan_rep_mode for the name resolve --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 225977b7..27ac78b7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -302,7 +302,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); -- cgit From d05333281217cd6623de9cc27b90448d7fd5d81a Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 28 Feb 2005 11:58:54 +0000 Subject: free protocol descriptor list properly --- tools/sdptool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index cfbe2bba..a3c3c551 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -892,7 +892,8 @@ static void print_service_attr(sdp_record_t *rec) if (sdp_get_access_protos(rec, &proto) == 0) { printf("Protocol Descriptor List:\n"); sdp_list_foreach(proto, print_access_protos, 0); - sdp_list_free(proto, (sdp_free_func_t)sdp_data_free); + sdp_list_foreach(proto, (sdp_list_func_t)sdp_list_free, 0); + sdp_list_free(proto, 0); } if (sdp_get_lang_attr(rec, &list) == 0) { printf("Language Base Attr List:\n"); -- cgit From 4eaf4a6acc09c87c010f31b169dac5a7b99cc1c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 28 Feb 2005 14:09:08 +0000 Subject: Call it SIM Access --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index a3c3c551..bed5e90e 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1265,7 +1265,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } - printf("Handsfree service registered\n"); + printf("SIM Access service registered\n"); end: sdp_data_free(channel); sdp_list_free(proto[0], 0); -- cgit From d9689662976b6e83f4c6ac9baacae98cb32700a1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Mar 2005 11:18:59 +0000 Subject: Add example for browsing the local services --- tools/sdptool.1 | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 8f938f92..91a28a84 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -99,6 +99,8 @@ Displays help on using sdptool. .PP sdptool browse 00:80:98:24:15:6D .PP +sdptool browse local +.PP sdptool add DUN .PP sdptool del LAN -- cgit From 64386bf323447b173ed9e6cb444d26af4b7f8db6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Mar 2005 16:06:25 +0000 Subject: Read BD_ADDR if not set and if it is a raw device --- tools/hciconfig.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1cc698d8..d8c40e8f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -75,6 +75,12 @@ static void print_dev_list(int ctl, int flags) di.dev_id = (dr+i)->dev_id; if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) continue; + if (hci_test_bit(HCI_RAW, &di.flags) && + !bacmp(&di.bdaddr, BDADDR_ANY)) { + int dd = hci_open_dev(di.dev_id); + hci_read_bd_addr(dd, &di.bdaddr, 1000); + hci_close_dev(dd); + } print_dev_info(ctl, &di); } } @@ -1217,6 +1223,13 @@ int main(int argc, char **argv, char **env) exit(1); } + if (hci_test_bit(HCI_RAW, &di.flags) && + !bacmp(&di.bdaddr, BDADDR_ANY)) { + int dd = hci_open_dev(di.dev_id); + hci_read_bd_addr(dd, &di.bdaddr, 1000); + hci_close_dev(dd); + } + while (argc > 0) { for (i = 0; command[i].cmd; i++) { if (strncmp(command[i].cmd, *argv, 5)) -- cgit From 210da6834b4b6f219b0331cddacdd6e915dbb8fe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Mar 2005 17:01:54 +0000 Subject: Add language attributes --- tools/sdptool.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index bed5e90e..5c93dd69 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -920,6 +920,20 @@ typedef struct { unsigned int channel; } svc_info_t; +static void add_lang_attr(sdp_record_t *r) +{ + sdp_lang_attr_t base_lang; + sdp_list_t *langs = 0; + + /* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */ + base_lang.code_ISO639 = (0x65 << 8) | 0x6e; + base_lang.encoding = 106; + base_lang.base_offset = SDP_PRIMARY_LANG_BASE; + langs = sdp_list_append(0, &base_lang); + sdp_set_lang_attr(r, langs); + sdp_list_free(langs, 0); +} + static int add_sp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto; @@ -961,7 +975,9 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); - sdp_set_info_attr(&record, "Serial Port", 0, 0); + add_lang_attr(&record); + + sdp_set_info_attr(&record, "Serial Port", 0, "COM Port"); if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); -- cgit From ac2daf48298cb601d1a57b0e00e38887b5e0a675 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 17 Mar 2005 19:03:58 +0000 Subject: Add support for reading CSR panic and fault codes --- tools/csr.h | 3 +++ tools/hciconfig.c | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index b96dd0f7..f29fc764 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -31,6 +31,9 @@ #define CSR_VARID_CHIPREV 0x281b #define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c +#define CSR_VARID_PANIC_ARG 0x6805 +#define CSR_VARID_FAULT_ARG 0x6806 + #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab char *csr_buildidtostr(uint16_t id); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index d8c40e8f..defe59c9 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -974,7 +974,7 @@ static void print_rev_ericsson(int dd) static void print_rev_csr(int dd, uint16_t rev) { - uint16_t buildid, chipver, chiprev, maxkeylen, mapsco; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, error; if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { printf("\t%s\n", csr_buildidtostr(rev)); @@ -994,6 +994,16 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); + + if (!csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error)) { + if (error < 0x0100) + printf("\tPanic code: 0x%02x\n", error); + } + + if (!csr_read_varid_uint16(dd, 6, CSR_VARID_FAULT_ARG, &error)) { + if (error < 0x0100) + printf("\tFault code: 0x%02x\n", error); + } } static void print_rev_digianswer(int dd) -- cgit From d3511a69c4be601fbe4c5c3d1f0cf1a8bb499a63 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 18 Mar 2005 13:49:49 +0000 Subject: Change default ping size to 44 bytes --- tools/l2ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/l2ping.c b/tools/l2ping.c index 01b1f21b..9741dc0e 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -50,7 +50,7 @@ /* Defaults */ static bdaddr_t bdaddr; -static int size = 20; +static int size = 44; static int ident = 200; static int delay = 1; static int count = -1; -- cgit From da77c34ef4276ad800498f76a707478add8b0a69 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 14:22:16 +0000 Subject: Update copyright year --- tools/csr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index f29fc764..513a2cf2 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From f5434ca84a250bbe6a7fe7baffdc53fb79d482f9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 18:40:59 +0000 Subject: Whitespace cleanup --- tools/hciconfig.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index defe59c9..e66c9aa1 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -608,7 +608,7 @@ static void cmd_class(int ctl, int hdev, char *opt) if ((cls[1] & 0x1f) > sizeof(*major_devices)) printf("Invalid Device Class!\n"); else - printf("%s, %s\n", major_devices[cls[1] & 0x1f], + printf("%s, %s\n", major_devices[cls[1] & 0x1f], get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); } } @@ -743,8 +743,8 @@ static void cmd_inq_parms(int ctl, int hdev, char *opt) rq.cparam = &cp; rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; - cp.window = htobs((uint16_t)window); - cp.interval = htobs((uint16_t)interval); + cp.window = htobs((uint16_t) window); + cp.interval = htobs((uint16_t) interval); if (window < 0x12 || window > 0x1000) printf("Warning: inquiry window out of range!\n"); @@ -812,8 +812,8 @@ static void cmd_page_parms(int ctl, int hdev, char *opt) rq.cparam = &cp; rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE; - cp.window = htobs((uint16_t)window); - cp.interval = htobs((uint16_t)interval); + cp.window = htobs((uint16_t) window); + cp.interval = htobs((uint16_t) interval); if (window < 0x12 || window > 0x1000) printf("Warning: page window out of range!\n"); @@ -881,7 +881,7 @@ static void cmd_page_to(int ctl, int hdev, char *opt) rq.cparam = &cp; rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE; - cp.timeout = htobs((uint16_t)timeout); + cp.timeout = htobs((uint16_t) timeout); if (timeout < 0x01 || timeout > 0xFFFF) printf("Warning: page timeout out of range!\n"); -- cgit From 8e8b4632526b90c9a8a86d1829ee5b71033d3fbb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 19:19:52 +0000 Subject: Add new search command and OUI support --- tools/hcitool.c | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- tools/oui.c | 100 ++++++++++++++++++ tools/oui.h | 30 ++++++ 3 files changed, 440 insertions(+), 4 deletions(-) create mode 100644 tools/oui.c create mode 100644 tools/oui.h (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 27ac78b7..9c4dc468 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -44,6 +44,8 @@ #include #include +#include "oui.h" + #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) static void usage(void); @@ -224,8 +226,8 @@ static void cmd_inq(int dev_id, int argc, char **argv) ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", addr, btohs((info+i)->clock_offset), - (info+i)->dev_class[2], - (info+i)->dev_class[1], + (info+i)->dev_class[2], + (info+i)->dev_class[1], (info+i)->dev_class[0]); } free(info); @@ -250,7 +252,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) inquiry_info *info = NULL; int num_rsp, length, flags; char addr[18]; - char name[248]; + char name[249]; int i, opt, dd; length = 8; /* ~10 seconds */ @@ -383,7 +385,7 @@ static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; - char name[248]; + char name[249], oui[9], *comp; unsigned char features[8]; struct hci_version version; struct hci_dev_info di; @@ -454,6 +456,13 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tBD Address: %s\n", argv[0]); + ba2oui(&bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("\tOUI Company: %s (%s)\n", comp, oui); + free(comp); + } + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); @@ -482,6 +491,302 @@ static void cmd_info(int dev_id, int argc, char **argv) close(dd); } +/* Find remote devices */ + +static struct option find_options[] = { + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } +}; + +static char *find_help = + "Usage:\n" + "\tfind [--length=N] [--numrsp=N] [--flush]\n"; + +static char *get_minor_device_name(int major, int minor) +{ + switch (major) { + case 0: /* misc */ + return ""; + case 1: /* computer */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2: /* phone */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3: /* lan access */ + if (minor == 0) + return "Uncategorized"; + switch(minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4: /* audio/video */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5: /* peripheral */ + switch(minor) { + case 16: + return "Keyboard"; + case 32: + return "Pointing device"; + case 48: + return "Combo keyboard/pointing device"; + } + break; + case 6: /* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 63: /* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + +static char *major_classes[] = { + "Miscellaneous", "Computer", "Phone", "LAN Access", + "Audio/Video", "Peripheral", "Imaging", "Uncategorized" +}; + +static void cmd_find(int dev_id, int argc, char **argv) +{ + inquiry_info *info = NULL; + int num_rsp, length, flags; + uint8_t cls[3]; + uint16_t handle; + char addr[18], name[249], oui[9], *comp; + unsigned char features[8]; + struct hci_version version; + struct hci_dev_info di; + struct hci_conn_info_req *cr; + int i, opt, dd, cc = 0; + + length = 8; /* ~10 seconds */ + num_rsp = 100; + flags = 0; + + for_each_opt(opt, find_options, NULL) { + switch (opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; + + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(find_help); + return; + } + } + + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { + perror("Device is not available"); + exit(1); + } + } + + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + + printf("Searching ...\n"); + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { + perror("Inquiry failed"); + exit(1); + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + free(info); + exit(1); + } + + printf("\n"); + + for (i = 0; i < num_rsp; i++) { + ba2str(&(info+i)->bdaddr, addr); + printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, + (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); + + ba2oui(&(info+i)->bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("OUI company:\t%s (%s)\n", comp, oui); + free(comp); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (cr) { + bacpy(&cr->bdaddr, &(info+i)->bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + if (hci_create_connection(dd, &(info+i)->bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + (info+i)->clock_offset | 0x8000, + 0x01, &handle, 25000) < 0) + handle = 0; + else + cc = 1; + } else + handle = htobs(cr->conn_info->handle); + } else + handle = 0; + + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + printf("Device name:\t%s\n", name); + + memcpy(cls, (info+i)->dev_class, 3); + printf("Device class:\t"); + if ((cls[1] & 0x1f) > sizeof(*major_classes)) + printf("Invalid"); + else + printf("%s, %s", major_classes[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); + printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); + + if (handle > 0) { + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("Manufacturer:\t%s (%d)\n", + bt_compidtostr(version.manufacturer), + version.manufacturer); + printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", + lmp_vertostr(version.lmp_ver), + version.lmp_ver, version.lmp_subver); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + features[0], features[1], + features[2], features[3], + features[4], features[5], + features[6], features[7]); + printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + } + + if (cc) { + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } + } + + printf("\n"); + + if (cr) + free(cr); + } + + close(dd); + free(info); +} + /* Send arbitrary HCI commands */ static struct option cmd_options[] = { @@ -1637,6 +1942,7 @@ static struct { { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, + { "find", cmd_find, "Search for remote devices" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, diff --git a/tools/oui.c b/tools/oui.c new file mode 100644 index 00000000..7dff358b --- /dev/null +++ b/tools/oui.c @@ -0,0 +1,100 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "oui.h" + +/* http://standards.ieee.org/regauth/oui/oui.txt */ + +#define OUIFILE "/usr/share/misc/oui.txt" + +#define AWKCMD "/usr/bin/awk" +#define TRCMD "/usr/bin/tr" + +char *ouitocomp(const char *oui) +{ + struct stat st; + FILE *input; + char cmd[512]; + char *str; + size_t len; + + if (stat(OUIFILE, &st) < 0) + return NULL; + + if (stat(AWKCMD, &st) < 0) + return NULL; + + if (stat(TRCMD, &st) < 0) + return NULL; + + str = malloc(128); + if (!str) + return NULL; + + memset(str, 0, 128); + + snprintf(cmd, sizeof(cmd) - 1, "%s -F'\\t' '/^" + "%s.*\\(hex\\).*/{ print $3 }' %s" + " | %s -d '\\n\\r'", AWKCMD, oui, OUIFILE, TRCMD); + + input = popen(cmd, "r"); + if (!input) { + free(str); + return NULL; + } + + len = fread(str, 127, 1, input); + pclose(input); + + return str; +} + +int oui2comp(const char *oui, char *comp, size_t size) +{ + char *tmp; + + tmp = ouitocomp(oui); + if (!tmp) + return -1; + + snprintf(comp, size, "%s", tmp); + + free(tmp); + + return 0; +} diff --git a/tools/oui.h b/tools/oui.h new file mode 100644 index 00000000..918a248b --- /dev/null +++ b/tools/oui.h @@ -0,0 +1,30 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +char *ouitocomp(const char *oui); +int oui2comp(const char *oui, char *comp, size_t size); -- cgit From 44b78feaa5e08e10d3d61404cc8ce8de416f70c3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 28 Mar 2005 20:00:34 +0000 Subject: Add support registering PANU service record --- tools/sdptool.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 5c93dd69..962c9ce9 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1616,6 +1616,68 @@ end: return ret; } +static int add_panu(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint16_t lp = 0x000f, ver = 0x0100; + sdp_data_t *psm, *version; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + sdp_list_free(root, NULL); + + sdp_uuid16_create(&ftrn_uuid, PANU_SVCLASS_ID); + svclass_id = sdp_list_append(NULL, &ftrn_uuid); + sdp_set_service_classes(&record, svclass_id); + sdp_list_free(svclass_id, NULL); + + sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + sdp_list_free(pfseq, NULL); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(NULL, &l2cap_uuid); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(NULL, proto[0]); + + sdp_uuid16_create(&bnep_uuid, BNEP_UUID); + proto[1] = sdp_list_append(NULL, &bnep_uuid); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(NULL, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "PAN User", NULL, NULL); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("PANU service registered\n"); +end: + sdp_data_free(version); + sdp_data_free(psm); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + static int add_ctp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1810,6 +1872,7 @@ struct { { "NAP", NAP_SVCLASS_ID, add_nap }, { "GN", GN_SVCLASS_ID, add_gn }, + { "PANU", PANU_SVCLASS_ID, add_panu }, { "HID", HID_SVCLASS_ID, NULL }, { "CIP", CIP_SVCLASS_ID, NULL }, -- cgit From b0f097c96eed5c5227973a48d8ad30bb5c18703e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Apr 2005 15:20:10 +0000 Subject: Add support for browsing the L2CAP group --- tools/sdptool.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 962c9ce9..980778ea 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2096,12 +2096,13 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) static struct option browse_options[] = { { "help", 0,0, 'h' }, { "tree", 0,0, 't' }, + { "l2cap", 0,0, 'l' }, { 0, 0, 0, 0 } }; static char *browse_help = "Usage:\n" - "\tbrowse [--tree] [bdaddr]\n"; + "\tbrowse [--tree] [--l2cap] [bdaddr]\n"; /* * Browse the full SDP database (i.e. list all services starting from the @@ -2115,13 +2116,16 @@ static int cmd_browse(int argc, char **argv) /* Initialise context */ memset(&context, '\0', sizeof(struct search_context)); /* We want to browse the top-level/root */ - sdp_uuid16_create(&(context.group), PUBLIC_BROWSE_GROUP); + sdp_uuid16_create(&context.group, PUBLIC_BROWSE_GROUP); for_each_opt(opt, browse_options, 0) { switch(opt) { case 't': context.tree = 1; break; + case 'l': + sdp_uuid16_create(&context.group, L2CAP_UUID); + break; default: printf(browse_help); return -1; -- cgit From 7271d875a003eab4af74e0304b2902c36fe86996 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Apr 2005 15:22:13 +0000 Subject: Include oui.[ch] for hcitool --- tools/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 6470a8a9..b07f2b19 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -20,6 +20,8 @@ hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ +hcitool_SOURCES = hcitool.c oui.h oui.c + hcitool_LDADD = @BLUEZ_LIBS@ l2ping_LDADD = @BLUEZ_LIBS@ -- cgit From 9f02be3e3b3d9af1e11e158c6cf386228e12d41f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 7 Apr 2005 13:43:23 +0000 Subject: Add support to browse various UUIDs --- tools/sdptool.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 980778ea..d3da429d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2094,15 +2094,16 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) } static struct option browse_options[] = { - { "help", 0,0, 'h' }, - { "tree", 0,0, 't' }, - { "l2cap", 0,0, 'l' }, + { "help", 0, 0, 'h' }, + { "tree", 0, 0, 't' }, + { "uuid", 1, 0, 'u' }, + { "l2cap", 0, 0, 'l' }, { 0, 0, 0, 0 } }; static char *browse_help = "Usage:\n" - "\tbrowse [--tree] [--l2cap] [bdaddr]\n"; + "\tbrowse [--tree] [--uuid uuid] [--l2cap] [bdaddr]\n"; /* * Browse the full SDP database (i.e. list all services starting from the @@ -2111,7 +2112,7 @@ static char *browse_help = static int cmd_browse(int argc, char **argv) { struct search_context context; - int opt; + int opt, num; /* Initialise context */ memset(&context, '\0', sizeof(struct search_context)); @@ -2123,6 +2124,13 @@ static int cmd_browse(int argc, char **argv) case 't': context.tree = 1; break; + case 'u': + if (sscanf(optarg, "%i", &num) != 1 || num < 0 || num > 0xffff) { + printf("Invalid uuid %s\n", optarg); + return -1; + } + sdp_uuid16_create(&context.group, num); + break; case 'l': sdp_uuid16_create(&context.group, L2CAP_UUID); break; -- cgit From 7637f1adf0fa094d07379965169b7444e3ebba4d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 7 Apr 2005 15:58:44 +0000 Subject: Add build id for BlueCore4-ROM with HCI 19.2 firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index e3353cdc..27a6a9a4 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -268,6 +268,7 @@ static struct { { 1737, "HCI 18.3" }, { 1915, "HCI 19.2" }, { 1916, "HCI 19.2" }, + { 1958, "HCI 19.2" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From f1a83659170a8f324991061c9ed14f39393e7c10 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Apr 2005 16:06:45 +0000 Subject: Integrate find options into scan command --- tools/hcitool.c | 572 ++++++++++++++++++++++++++------------------------------ 1 file changed, 269 insertions(+), 303 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 9c4dc468..9ac890fd 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -142,6 +142,140 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) printf("\n"); } +static char *get_minor_device_name(int major, int minor) +{ + switch (major) { + case 0: /* misc */ + return ""; + case 1: /* computer */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2: /* phone */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3: /* lan access */ + if (minor == 0) + return "Uncategorized"; + switch(minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4: /* audio/video */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5: /* peripheral */ + switch(minor) { + case 16: + return "Keyboard"; + case 32: + return "Pointing device"; + case 48: + return "Combo keyboard/pointing device"; + } + break; + case 6: /* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 63: /* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + +static char *major_classes[] = { + "Miscellaneous", "Computer", "Phone", "LAN Access", + "Audio/Video", "Peripheral", "Imaging", "Uncategorized" +}; + /* Display local devices */ static struct option dev_options[] = { @@ -240,20 +374,31 @@ static struct option scan_options[] = { { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, { "flush", 0, 0, 'f' }, + { "class", 0, 0, 'c' }, + { "info", 0, 0, 'i' }, + { "oui", 0, 0, 'o' }, + { "all", 0, 0, 'a' }, + { "ext", 0, 0, 'a' }, { 0, 0, 0, 0 } }; static char *scan_help = "Usage:\n" - "\tscan [--length=N] [--numrsp=N] [--flush]\n"; + "\tscan [--length=N] [--numrsp=N] [--flush] [--class] [--info] [--oui]\n"; static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - char addr[18]; - char name[249]; - int i, opt, dd; + uint8_t cls[3]; + uint16_t handle; + char addr[18], name[249], oui[9], *comp; + unsigned char features[8]; + struct hci_version version; + struct hci_dev_info di; + struct hci_conn_info_req *cr; + int extcls = 0, extinf = 0, extoui = 0; + int i, opt, dd, cc; length = 8; /* ~10 seconds */ num_rsp = 100; @@ -273,6 +418,24 @@ static void cmd_scan(int dev_id, int argc, char **argv) flags |= IREQ_CACHE_FLUSH; break; + case 'c': + extcls = 1; + break; + + case 'i': + extinf = 1; + break; + + case 'o': + extoui = 1; + break; + + case 'a': + extcls = 1; + extinf = 1; + extoui = 1; + break; + default: printf(scan_help); return; @@ -287,6 +450,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { @@ -301,15 +469,110 @@ static void cmd_scan(int dev_id, int argc, char **argv) exit(1); } + if (extcls || extinf || extoui) + printf("\n"); + for (i = 0; i < num_rsp; i++) { + if (!extcls && !extinf && !extoui) { + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, + &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); + continue; + } + + ba2str(&(info+i)->bdaddr, addr); + printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, + (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); + + if (extoui) { + ba2oui(&(info+i)->bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("OUI company:\t%s (%s)\n", comp, oui); + free(comp); + } + } + + cc = 0; + + if (extinf) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (cr) { + bacpy(&cr->bdaddr, &(info+i)->bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + handle = 0; + cc = 1; + } else { + handle = htobs(cr->conn_info->handle); + cc = 0; + } + free(cr); + } + + if (cc) { + if (hci_create_connection(dd, &(info+i)->bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + (info+i)->clock_offset | 0x8000, + 0x01, &handle, 25000) < 0) { + handle = 0; + cc = 0; + } + } + } + memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - ba2str(&(info+i)->bdaddr, addr); - printf("\t%s\t%s\n", addr, name); + printf("Device name:\t%s\n", name); + + if (extcls) { + memcpy(cls, (info+i)->dev_class, 3); + printf("Device class:\t"); + if ((cls[1] & 0x1f) > sizeof(*major_classes)) + printf("Invalid"); + else + printf("%s, %s", major_classes[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); + printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); + } + + if (extinf && handle > 0) { + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("Manufacturer:\t%s (%d)\n", + bt_compidtostr(version.manufacturer), + version.manufacturer); + printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", + lmp_vertostr(version.lmp_ver), + version.lmp_ver, version.lmp_subver); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + features[0], features[1], + features[2], features[3], + features[4], features[5], + features[6], features[7]); + printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + } + + if (cc) { + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } + } + + printf("\n"); } close(dd); @@ -491,302 +754,6 @@ static void cmd_info(int dev_id, int argc, char **argv) close(dd); } -/* Find remote devices */ - -static struct option find_options[] = { - { "help", 0, 0, 'h' }, - { "length", 1, 0, 'l' }, - { "numrsp", 1, 0, 'n' }, - { "flush", 0, 0, 'f' }, - { 0, 0, 0, 0 } -}; - -static char *find_help = - "Usage:\n" - "\tfind [--length=N] [--numrsp=N] [--flush]\n"; - -static char *get_minor_device_name(int major, int minor) -{ - switch (major) { - case 0: /* misc */ - return ""; - case 1: /* computer */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Desktop workstation"; - case 2: - return "Server"; - case 3: - return "Laptop"; - case 4: - return "Handheld"; - case 5: - return "Palm"; - case 6: - return "Wearable"; - } - break; - case 2: /* phone */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Cellular"; - case 2: - return "Cordless"; - case 3: - return "Smart phone"; - case 4: - return "Wired modem or voice gateway"; - case 5: - return "Common ISDN Access"; - case 6: - return "Sim Card Reader"; - } - break; - case 3: /* lan access */ - if (minor == 0) - return "Uncategorized"; - switch(minor / 8) { - case 0: - return "Fully available"; - case 1: - return "1-17% utilized"; - case 2: - return "17-33% utilized"; - case 3: - return "33-50% utilized"; - case 4: - return "50-67% utilized"; - case 5: - return "67-83% utilized"; - case 6: - return "83-99% utilized"; - case 7: - return "No service available"; - } - break; - case 4: /* audio/video */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Device conforms to the Headset profile"; - case 2: - return "Hands-free"; - /* 3 is reserved */ - case 4: - return "Microphone"; - case 5: - return "Loudspeaker"; - case 6: - return "Headphones"; - case 7: - return "Portable Audio"; - case 8: - return "Car Audio"; - case 9: - return "Set-top box"; - case 10: - return "HiFi Audio Device"; - case 11: - return "VCR"; - case 12: - return "Video Camera"; - case 13: - return "Camcorder"; - case 14: - return "Video Monitor"; - case 15: - return "Video Display and Loudspeaker"; - case 16: - return "Video Conferencing"; - /* 17 is reserved */ - case 18: - return "Gaming/Toy"; - } - break; - case 5: /* peripheral */ - switch(minor) { - case 16: - return "Keyboard"; - case 32: - return "Pointing device"; - case 48: - return "Combo keyboard/pointing device"; - } - break; - case 6: /* imaging */ - if (minor & 4) - return "Display"; - if (minor & 8) - return "Camera"; - if (minor & 16) - return "Scanner"; - if (minor & 32) - return "Printer"; - break; - case 63: /* uncategorised */ - return ""; - } - return "Unknown (reserved) minor device class"; -} - -static char *major_classes[] = { - "Miscellaneous", "Computer", "Phone", "LAN Access", - "Audio/Video", "Peripheral", "Imaging", "Uncategorized" -}; - -static void cmd_find(int dev_id, int argc, char **argv) -{ - inquiry_info *info = NULL; - int num_rsp, length, flags; - uint8_t cls[3]; - uint16_t handle; - char addr[18], name[249], oui[9], *comp; - unsigned char features[8]; - struct hci_version version; - struct hci_dev_info di; - struct hci_conn_info_req *cr; - int i, opt, dd, cc = 0; - - length = 8; /* ~10 seconds */ - num_rsp = 100; - flags = 0; - - for_each_opt(opt, find_options, NULL) { - switch (opt) { - case 'l': - length = atoi(optarg); - break; - - case 'n': - num_rsp = atoi(optarg); - break; - - case 'f': - flags |= IREQ_CACHE_FLUSH; - break; - - default: - printf(find_help); - return; - } - } - - if (dev_id < 0) { - dev_id = hci_get_route(NULL); - if (dev_id < 0) { - perror("Device is not available"); - exit(1); - } - } - - if (hci_devinfo(dev_id, &di) < 0) { - perror("Can't get device info"); - exit(1); - } - - printf("Searching ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); - if (num_rsp < 0) { - perror("Inquiry failed"); - exit(1); - } - - dd = hci_open_dev(dev_id); - if (dd < 0) { - perror("HCI device open failed"); - free(info); - exit(1); - } - - printf("\n"); - - for (i = 0; i < num_rsp; i++) { - ba2str(&(info+i)->bdaddr, addr); - printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, - (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); - - ba2oui(&(info+i)->bdaddr, oui); - comp = ouitocomp(oui); - if (comp) { - printf("OUI company:\t%s (%s)\n", comp, oui); - free(comp); - } - - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (cr) { - bacpy(&cr->bdaddr, &(info+i)->bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &(info+i)->bdaddr, - htobs(di.pkt_type & ACL_PTYPE_MASK), - (info+i)->clock_offset | 0x8000, - 0x01, &handle, 25000) < 0) - handle = 0; - else - cc = 1; - } else - handle = htobs(cr->conn_info->handle); - } else - handle = 0; - - memset(name, 0, sizeof(name)); - if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->pscan_rep_mode, - (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); - printf("Device name:\t%s\n", name); - - memcpy(cls, (info+i)->dev_class, 3); - printf("Device class:\t"); - if ((cls[1] & 0x1f) > sizeof(*major_classes)) - printf("Invalid"); - else - printf("%s, %s", major_classes[cls[1] & 0x1f], - get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); - printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); - - if (handle > 0) { - if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { - printf("Manufacturer:\t%s (%d)\n", - bt_compidtostr(version.manufacturer), - version.manufacturer); - printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", - lmp_vertostr(version.lmp_ver), - version.lmp_ver, version.lmp_subver); - } - - if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" - " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", - features[0], features[1], - features[2], features[3], - features[4], features[5], - features[6], features[7]); - printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); - } - - if (cc) { - usleep(10000); - hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); - } - } - - printf("\n"); - - if (cr) - free(cr); - } - - close(dd); - free(info); -} - /* Send arbitrary HCI commands */ static struct option cmd_options[] = { @@ -1942,7 +1909,6 @@ static struct { { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, - { "find", cmd_find, "Search for remote devices" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, -- cgit From 304b8bb466c0b015d30f9dfbc785d2a7c0a2ef79 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:46:13 +0000 Subject: Make use of the device name cache --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 9ac890fd..947da44e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -34,9 +34,12 @@ #include #include +#include #include #include #include +#include +#include #include #include @@ -276,6 +279,63 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; +#define DEVPATH "/var/lib/bluetooth/" + +static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +{ + char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int fd, pos, err = 0; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_SH) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + + if (!bacmp(&bdaddr, peer)) { + snprintf(name, 249, "%s", str); + break; + } + + ptr += pos; + }; + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + return err; +} + /* Display local devices */ static struct option dev_options[] = { @@ -398,7 +458,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, opt, dd, cc; + int i, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 100; @@ -473,7 +533,17 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("\n"); for (i = 0; i < num_rsp; i++) { + memset(name, 0, sizeof(name)); + nc = read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) < 0 ? 0 : 1; + if (!extcls && !extinf && !extoui) { + ba2str(&(info+i)->bdaddr, addr); + + if (nc) { + printf("\t%s\t%s\n", addr, name); + continue; + } + memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, @@ -481,7 +551,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); continue; } @@ -527,13 +597,16 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } - memset(name, 0, sizeof(name)); - if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->pscan_rep_mode, - (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); - printf("Device name:\t%s\n", name); + if (handle > 0 || !nc) { + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, + &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + } + printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); if (extcls) { memcpy(cls, (info+i)->dev_class, 3); -- cgit From 91ec71874613cf65ab0abdaaf62c0b4e6a56a40e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:52:36 +0000 Subject: Fix the name cache state --- tools/hcitool.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 947da44e..a17fe8bc 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -544,7 +544,6 @@ static void cmd_scan(int dev_id, int argc, char **argv) continue; } - memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, @@ -598,13 +597,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (handle > 0 || !nc) { - memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); + sizeof(name), name, 100000) < 0) { + if (!nc) + strcpy(name, "n/a"); + } else + nc = 0; } printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); -- cgit From 12513fafd320f210190ab574383efe9591ce6c6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:58:53 +0000 Subject: Fix the case if device isn't found in the name cache --- tools/hcitool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index a17fe8bc..5106f664 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -286,7 +286,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; bdaddr_t bdaddr; struct stat st; - int fd, pos, err = 0; + int fd, pos, err = -ENOENT; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); @@ -321,6 +321,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n if (!bacmp(&bdaddr, peer)) { snprintf(name, 249, "%s", str); + err = 0; break; } @@ -534,7 +535,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - nc = read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) < 0 ? 0 : 1; + nc = (read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) == 0); if (!extcls && !extinf && !extoui) { ba2str(&(info+i)->bdaddr, addr); -- cgit From 24793e9a7eb16ed4f749b32419154bc2a58bbc1d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 01:05:27 +0000 Subject: Improve reading device names from cache --- tools/hcitool.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 5106f664..6da3d3c1 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -316,8 +316,10 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n ptr = buf; + memset(str, 0, sizeof(str)); while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); + str[sizeof(str) - 1] = '\0'; if (!bacmp(&bdaddr, peer)) { snprintf(name, 249, "%s", str); @@ -325,7 +327,10 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n break; } + memset(str, 0, sizeof(str)); ptr += pos; + if (ptr - buf >= st.st_size) + break; }; } -- cgit From 096a5b39b0956d1a2ef02ceda6015b4c4edb59c4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:20:31 +0000 Subject: Add support for supported commands and extended features --- tools/hciconfig.8 | 3 ++ tools/hciconfig.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 88 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 5340978d..dabfeb36 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -187,6 +187,9 @@ bytes and SCO buffer size to .I pkt packets. .TP +.BI commands +Display supported commands. +.TP .BI features Display device features. .TP diff --git a/tools/hciconfig.c b/tools/hciconfig.c index e66c9aa1..a1232c6c 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -102,20 +102,14 @@ static void print_link_mode(struct hci_dev_info *di) static void print_dev_features(struct hci_dev_info *di, int format) { - if (!format) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", - di->features[0], di->features[1], - di->features[2], di->features[3], - di->features[4], di->features[5], - di->features[6], di->features[7] ); - } else { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", - di->features[0], di->features[1], - di->features[2], di->features[3], - di->features[4], di->features[5], - di->features[6], di->features[7], - lmp_featurestostr(di->features, "\t\t", 63)); - } + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + di->features[0], di->features[1], di->features[2], + di->features[3], di->features[4], di->features[5], + di->features[6], di->features[7]); + + if (format) + printf("%s\n", lmp_featurestostr(di->features, "\t\t", 63)); } static void cmd_rstat(int ctl, int hdev, char *opt) @@ -383,8 +377,47 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) static void cmd_features(int ctl, int hdev, char *opt) { + uint8_t max_page, features[8]; + int i, dd; + + if (!(di.features[7] & 0x80)) { + print_dev_hdr(&di); + print_dev_features(&di, 1); + return; + } + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_ext_features(dd, 0, &max_page, features, 1000) < 0) { + fprintf(stderr, "Can't read extended features hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + print_dev_hdr(&di); - print_dev_features(&di, 1); + printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + (max_page > 0) ? " page 0" : "", + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7]); + printf("%s\n", lmp_featurestostr(di.features, "\t\t", 63)); + + for (i = 1; i <= max_page; i++) { + if (hci_read_local_ext_features(dd, 1, &max_page, features, 1000) < 0) + continue; + + printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i, + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7]); + } + + hci_close_dev(dd); } static void cmd_name(int ctl, int hdev, char *opt) @@ -656,6 +689,40 @@ static void cmd_voice(int ctl, int hdev, char *opt) } } +static void cmd_commands(int ctl, int hdev, char *opt) +{ + uint8_t cmds[64]; + int i, n, dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_commands(dd, cmds, 1000) < 0) { + fprintf(stderr, "Can't read support commands hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + for (i = 0; i < 64; i++) { + if (!cmds[i]) + continue; + + printf("%s Octet %-2d = 0x%02x (Bit", + i ? "\t\t ": "\tCommands:", i, cmds[i]); + for (n = 0; n < 8; n++) + if (hci_test_bit(n, &cmds[i])) + printf(" %d", n); + printf(")\n"); + } + + hci_close_dev(dd); +} + static void cmd_version(int ctl, int hdev, char *opt) { struct hci_version ver; @@ -680,6 +747,8 @@ static void cmd_version(int ctl, int hdev, char *opt) hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, bt_compidtostr(ver.manufacturer), ver.manufacturer); + + hci_close_dev(dd); } static void cmd_inq_mode(int ctl, int hdev, char *opt) @@ -1166,6 +1235,7 @@ static struct { { "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" }, { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, + { "commands", cmd_commands, 0, "Display supported commands" }, { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, { "revision", cmd_revision, 0, "Display revision information" }, -- cgit From c3881e06e2262909d8e1c190622002c5e02d724f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:34:20 +0000 Subject: Check the number of pages for extended features --- tools/hcitool.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 6da3d3c1..e02cb93f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -456,10 +456,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - uint8_t cls[3]; + uint8_t cls[3], features[8]; uint16_t handle; char addr[18], name[249], oui[9], *comp; - unsigned char features[8]; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -728,8 +727,8 @@ static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; + uint8_t max_page, features[8]; char name[249], oui[9], *comp; - unsigned char features[8]; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -826,6 +825,12 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } + if (features[7] & 0x80) { + if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) + if (max_page > 0) + printf("\tExtended features: %d pages\n", max_page); + } + if (cc) { usleep(10000); hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); -- cgit From 089583df538a11302e504659e7652389fdfa9aeb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 12:19:26 +0000 Subject: Use mmap() for reading the OUI company name --- tools/oui.c | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/oui.c b/tools/oui.c index 7dff358b..985e6e20 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -32,9 +32,12 @@ #include #include +#include +#include #include #include #include +#include #include "oui.h" @@ -42,44 +45,50 @@ #define OUIFILE "/usr/share/misc/oui.txt" -#define AWKCMD "/usr/bin/awk" -#define TRCMD "/usr/bin/tr" - char *ouitocomp(const char *oui) { struct stat st; - FILE *input; - char cmd[512]; - char *str; - size_t len; + char *str, *map, *off, *end; + int fd; - if (stat(OUIFILE, &st) < 0) - return NULL; - if (stat(AWKCMD, &st) < 0) + fd = open(OUIFILE, O_RDONLY); + if (fd < 0) return NULL; - if (stat(TRCMD, &st) < 0) + if (fstat(fd, &st) < 0) { + close(fd); return NULL; + } str = malloc(128); - if (!str) + if (!str) { + close(fd); return NULL; + } memset(str, 0, 128); - snprintf(cmd, sizeof(cmd) - 1, "%s -F'\\t' '/^" - "%s.*\\(hex\\).*/{ print $3 }' %s" - " | %s -d '\\n\\r'", AWKCMD, oui, OUIFILE, TRCMD); - - input = popen(cmd, "r"); - if (!input) { + map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { free(str); + close(fd); return NULL; } - len = fread(str, 127, 1, input); - pclose(input); + off = strstr(map, oui); + if (off) { + off += 18; + end = strpbrk(off, "\r\n"); + strncpy(str, off, end - off); + } else { + free(str); + str = NULL; + } + + munmap(map, st.st_size); + + close(fd); return str; } -- cgit From bb30c261fcdb833bf5cac02f671822bbe443ff27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 21:09:59 +0000 Subject: Use LMP_EXT_FEAT constant --- tools/hciconfig.c | 2 +- tools/hcitool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index a1232c6c..df9b211e 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -380,7 +380,7 @@ static void cmd_features(int ctl, int hdev, char *opt) uint8_t max_page, features[8]; int i, dd; - if (!(di.features[7] & 0x80)) { + if (!(di.features[7] & LMP_EXT_FEAT)) { print_dev_hdr(&di); print_dev_features(&di, 1); return; diff --git a/tools/hcitool.c b/tools/hcitool.c index e02cb93f..0b35b1ac 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -825,7 +825,7 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } - if (features[7] & 0x80) { + if (features[7] & LMP_EXT_FEAT) { if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) if (max_page > 0) printf("\tExtended features: %d pages\n", max_page); -- cgit From be0264a76e5658b41a23ed7a9228eb27490abf58 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 22:23:55 +0000 Subject: Use unlimited inquiry responses as default --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 0b35b1ac..453ef2e3 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -392,7 +392,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) int i, opt; length = 8; /* ~10 seconds */ - num_rsp = 100; + num_rsp = 0; flags = 0; for_each_opt(opt, inq_options, NULL) { @@ -466,7 +466,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int i, opt, dd, cc, nc; length = 8; /* ~10 seconds */ - num_rsp = 100; + num_rsp = 0; flags = 0; for_each_opt(opt, scan_options, NULL) { -- cgit From bf3f55de5b9e3c95aa53e9bd5e0a19c9655e50f5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 19 Apr 2005 11:29:19 +0000 Subject: Add build id for BlueCore3-ROM with HCI 18.4 firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 27a6a9a4..8c07fabb 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -269,6 +269,7 @@ static struct { { 1915, "HCI 19.2" }, { 1916, "HCI 19.2" }, { 1958, "HCI 19.2" }, + { 1989, "HCI 18.4" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 47a63f33131e0cbc19e51d7d4f8a27dcf3fcc6a9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 19 Apr 2005 13:55:29 +0000 Subject: Add build id for BlueCore3-MM with HCI 19.2 firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 8c07fabb..c646ebde 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -269,6 +269,7 @@ static struct { { 1915, "HCI 19.2" }, { 1916, "HCI 19.2" }, { 1958, "HCI 19.2" }, + { 1981, "HCI 19.2" }, { 1989, "HCI 18.4" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, -- cgit From 303a8bfd8c49de19c482b047c9a95b94e585c1cb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 13:03:48 +0000 Subject: Read the boot mode on CSR devices --- tools/csr.h | 1 + tools/hciconfig.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index 513a2cf2..72d4cc4a 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -35,6 +35,7 @@ #define CSR_VARID_FAULT_ARG 0x6806 #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab +#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index df9b211e..20ef065c 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1043,7 +1043,7 @@ static void print_rev_ericsson(int dd) static void print_rev_csr(int dd, uint16_t rev) { - uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, error; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, bootmode, error; if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { printf("\t%s\n", csr_buildidtostr(rev)); @@ -1064,6 +1064,9 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); + if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_INITIAL_BOOTMODE, &bootmode)) + printf("\tBoot mode: %d%s\n", bootmode, bootmode ? "" : " (HCI)"); + if (!csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error)) { if (error < 0x0100) printf("\tPanic code: 0x%02x\n", error); -- cgit From ba621583ce85d01708420f8d8ea2f6f26b336b30 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 16:06:07 +0000 Subject: Add support for writing PS key values --- tools/csr.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- tools/csr.h | 2 ++ 2 files changed, 59 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index c646ebde..a155efcb 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -374,6 +374,18 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) } } +char *csr_pskeytostr(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: + return "Map SCO over PCM"; + case CSR_PSKEY_INITIAL_BOOTMODE: + return "Initial device bootmode"; + default: + return "Unknown"; + } +} + int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, @@ -404,8 +416,10 @@ int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *val return -1; } - if ((rp[9] + (rp[10] << 8)) != 0) + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; return -1; + } *value = rp[11] + (rp[12] << 8); @@ -442,10 +456,51 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *val return -1; } - if ((rp[9] + (rp[10] << 8)) != 0) + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; return -1; + } *value = rp[17] + (rp[18] << 8); return 0; } + +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, + pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, + value & 0xff, value >> 8 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} diff --git a/tools/csr.h b/tools/csr.h index 72d4cc4a..79795be0 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -39,6 +39,8 @@ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); +char *csr_pskeytostr(uint16_t pskey); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); -- cgit From 7cc4137b299169997e45e07614966adc55f6f5eb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 16:56:29 +0000 Subject: Add pskey utility for changing PCM mapping and boot mode --- tools/Makefile.am | 6 +- tools/pskey.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 tools/pskey.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index b07f2b19..3dd69b68 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -14,7 +14,7 @@ sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool -noinst_PROGRAMS = ppporc hcisecfilter +noinst_PROGRAMS = hcisecfilter ppporc pskey hciconfig_SOURCES = hciconfig.c csr.h csr.c @@ -32,6 +32,10 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ +pskey_SOURCES = pskey.c csr.h csr.c + +pskey_LDADD = @BLUEZ_LIBS@ + if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif diff --git a/tools/pskey.c b/tools/pskey.c new file mode 100644 index 00000000..01aa921d --- /dev/null +++ b/tools/pskey.c @@ -0,0 +1,204 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + +#define CSR_TYPE_NULL 0 +#define CSR_TYPE_UINT16 1 + +static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) +{ + uint16_t value; + int err; + + if (type != CSR_TYPE_UINT16) { + errno = EFAULT; + return -1; + } + + if (argc != 1) { + errno = E2BIG; + return -1; + } + + value = atoi(argv[0]); + + err = csr_write_pskey_uint16(dd, 0x4711, pskey, value); + + return err; +} + +static int read_pskey(int dd, uint16_t pskey, int type) +{ + uint16_t value; + int err; + + if (type != CSR_TYPE_UINT16) { + errno = EFAULT; + return -1; + } + + err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); + if (err < 0) + return err; + + printf("%s: %d\n", csr_pskeytostr(pskey), value); + + return err; +} + +static struct { + uint16_t pskey; + int type; + char *str; +} storage[] = { + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, + { 0x0000, CSR_TYPE_NULL, NULL }, +}; + +static void usage(void) +{ + int i; + + printf("pskey - Utility for changing CSR persistent storage\n\n"); + printf("Usage:\n" + "\tpskey [-i ] [value]\n\n"); + + printf("Keys:\n\t"); + for (i = 0; storage[i].pskey; i++) + printf("%s ", storage[i].str); + printf("\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct hci_dev_info di; + struct hci_version ver; + int i, err, dd, opt, dev = 0; + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + exit(1); + } + + if (hci_devinfo(dev, &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (ver.manufacturer != 10) { + fprintf(stderr, "Unsupported manufacturer\n"); + hci_close_dev(dd); + exit(1); + } + + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + if (argc > 1) + err = write_pskey(dd, storage[i].pskey, + storage[i].type, argc - 1, argv + 1); + else + err = read_pskey(dd, storage[i].pskey, storage[i].type); + + hci_close_dev(dd); + + if (err < 0) { + fprintf(stderr, "Can't %s persistent storage: %s (%d)\n", + argc > 1 ? "write" : "read", strerror(errno), errno); + exit(1); + } + + exit(0); + } + + fprintf(stderr, "Unsupported persistent storage\n"); + + hci_close_dev(dd); + + exit(1); +} -- cgit From 1487aa2f7c8a1bd0633d3f959699b1ccb1a5031c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 22:30:36 +0000 Subject: Support adding of Nokia ID and PC Suite service records --- tools/sdptool.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index d3da429d..83e86fb5 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * Copyright (C) 2002-2003 Jean Tourrilhes * @@ -1423,7 +1423,7 @@ end: return ret; } -static int add_file_trans(sdp_session_t *session, svc_info_t *si) +static int add_ftp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, ftrn_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; @@ -1852,6 +1852,83 @@ done: return ret; } +static unsigned char nokid_uuid[] = { 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + +static int add_nokia_id(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass; + uuid_t root_uuid, svclass_uuid; + uint16_t verid = 0x005f; + sdp_data_t *version = sdp_data_alloc(SDP_UINT16, &verid); + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) nokid_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_attr_add(&record, SDP_ATTR_SERVICE_VERSION, version); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + sdp_data_free(version); + return -1; + } + + printf("Nokia ID service record registered\n"); + + return 0; +} + +static unsigned char pcsuite_uuid[] = { 0x00, 0x00, 0x50, 0x02, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + +static int add_pcsuite(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel? si->channel: 14; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid128_create(&svclass_uuid, (void *) pcsuite_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "Nokia PC Suite", NULL, NULL); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Nokia PC Suite service registered\n"); + + return 0; +} + struct { char *name; uint16_t class; @@ -1864,7 +1941,7 @@ struct { { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, { "FAX", FAX_SVCLASS_ID, add_fax }, { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, - { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, + { "FTP", OBEX_FILETRANS_SVCLASS_ID, add_ftp }, { "HS", HEADSET_SVCLASS_ID, add_headset }, { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, @@ -1881,6 +1958,9 @@ struct { { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source}, { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, + { "NOKID", 0, add_nokia_id }, + { "PCSUITE", 0, add_pcsuite }, + { 0 } }; @@ -2339,7 +2419,7 @@ static struct { static void usage(void) { - int i; + int i, pos = 0; printf("sdptool - SDP tool v%s\n", VERSION); printf("Usage:\n" @@ -2353,8 +2433,14 @@ static void usage(void) printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc); printf("\nServices:\n\t"); - for (i = 0; service[i].name; i++) + for (i = 0; service[i].name; i++) { printf("%s ", service[i].name); + pos += strlen(service[i].name) + 1; + if (pos > 60) { + printf("\n\t"); + pos = 0; + } + } printf("\n"); } -- cgit From 62d4836a2e0449e381e2a1c757bf37e39826d660 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 23:16:43 +0000 Subject: Add definitions for host interface and USB vendor/product ids --- tools/csr.c | 6 ++++++ tools/csr.h | 3 +++ 2 files changed, 9 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index a155efcb..75507c41 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -379,6 +379,12 @@ char *csr_pskeytostr(uint16_t pskey) switch (pskey) { case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; + case CSR_PSKEY_HOST_INTERFACE: + return "Host interface"; + case CSR_PSKEY_USB_VENDOR_ID: + return "USB vendor identifier"; + case CSR_PSKEY_USB_PRODUCT_ID: + return "USB product identifier"; case CSR_PSKEY_INITIAL_BOOTMODE: return "Initial device bootmode"; default: diff --git a/tools/csr.h b/tools/csr.h index 79795be0..c8ac5cd3 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -35,6 +35,9 @@ #define CSR_VARID_FAULT_ARG 0x6806 #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab +#define CSR_PSKEY_HOST_INTERFACE 0x01f9 +#define CSR_PSKEY_USB_VENDOR_ID 0x02be +#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf #define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd char *csr_buildidtostr(uint16_t id); -- cgit From d354ddf51aae1d6b5315888dda3a693b7c817388 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 23:18:23 +0000 Subject: Support changing the host interface and USB vendor/product ids --- tools/pskey.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 01aa921d..2dd10c77 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -81,7 +81,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) if (err < 0) return err; - printf("%s: %d\n", csr_pskeytostr(pskey), value); + printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); return err; } @@ -92,6 +92,9 @@ static struct { char *str; } storage[] = { { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, { 0x0000, CSR_TYPE_NULL, NULL }, }; -- cgit From 975d3e774555963b829dee6985c1698f291f01ce Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 23:45:11 +0000 Subject: Add definition for the UART baud rate --- tools/csr.c | 4 ++++ tools/csr.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 75507c41..45324d3e 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -379,12 +379,16 @@ char *csr_pskeytostr(uint16_t pskey) switch (pskey) { case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; + case CSR_PSKEY_UART_BAUDRATE: + return "UART Baud rate"; case CSR_PSKEY_HOST_INTERFACE: return "Host interface"; case CSR_PSKEY_USB_VENDOR_ID: return "USB vendor identifier"; case CSR_PSKEY_USB_PRODUCT_ID: return "USB product identifier"; + case CSR_PSKEY_USB_DFU_PRODUCT_ID: + return "USB DFU product ID"; case CSR_PSKEY_INITIAL_BOOTMODE: return "Initial device bootmode"; default: diff --git a/tools/csr.h b/tools/csr.h index c8ac5cd3..7aa90c31 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -35,9 +35,11 @@ #define CSR_VARID_FAULT_ARG 0x6806 #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab +#define CSR_PSKEY_UART_BAUDRATE 0x01be #define CSR_PSKEY_HOST_INTERFACE 0x01f9 #define CSR_PSKEY_USB_VENDOR_ID 0x02be #define CSR_PSKEY_USB_PRODUCT_ID 0x02bf +#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb #define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd char *csr_buildidtostr(uint16_t id); -- cgit From acea732b00a0f48d1e4414b303f6b2c49e71cbbe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 23:46:00 +0000 Subject: Support changing the UART baud rate (HCI 18.x and later) --- tools/pskey.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 2dd10c77..edf78e8d 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -92,9 +92,11 @@ static struct { char *str; } storage[] = { { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, { 0x0000, CSR_TYPE_NULL, NULL }, }; -- cgit From f5a214f76f2d93702b5bc3b0b168389d8f8b34f2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 20:18:09 +0000 Subject: Set the storage directory through ${localstatedir} --- tools/hcitool.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 453ef2e3..fb189760 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -279,8 +279,6 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; -#define DEVPATH "/var/lib/bluetooth/" - static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; @@ -289,7 +287,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n int fd, pos, err = -ENOENT; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); fd = open(filename, O_RDONLY); if (fd < 0) -- cgit From 1514cc3fbace6793f002737b08f9cfcb140bed70 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 21:53:11 +0000 Subject: Add the firmware upgrade utility --- tools/Makefile.am | 23 +- tools/dfu.c | 169 ++++++++++++ tools/dfu.h | 108 ++++++++ tools/dfutool.1 | 53 ++++ tools/dfutool.c | 763 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1110 insertions(+), 6 deletions(-) create mode 100644 tools/dfu.c create mode 100644 tools/dfu.h create mode 100644 tools/dfutool.1 create mode 100644 tools/dfutool.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 3dd69b68..9756a8d8 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -10,18 +10,24 @@ hid2hci_programs = hid2hci_manfiles = endif +if DFUTOOL +dfutool_programs = dfutool +dfutool_manfiles = dfutool.1 +else +dfutool_programs = +dfutool_manfiles = +endif + sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) -bin_PROGRAMS = hcitool l2ping sdptool ciptool +bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) noinst_PROGRAMS = hcisecfilter ppporc pskey hciconfig_SOURCES = hciconfig.c csr.h csr.c - hciconfig_LDADD = @BLUEZ_LIBS@ hcitool_SOURCES = hcitool.c oui.h oui.c - hcitool_LDADD = @BLUEZ_LIBS@ l2ping_LDADD = @BLUEZ_LIBS@ @@ -33,17 +39,22 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ pskey_SOURCES = pskey.c csr.h csr.c - pskey_LDADD = @BLUEZ_LIBS@ if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif +if DFUTOOL +dfutool_SOURCES = dfutool.c dfu.h dfu.c +dfutool_LDADD = @USB_LIBS@ +endif + AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 $(hid2hci_manfiles) +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ + $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) hid2hci.8 hid2hci.c +EXTRA_DIST = $(man_MANS) hid2hci.8 dfutool.1 MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/dfu.c b/tools/dfu.c new file mode 100644 index 00000000..08e256b9 --- /dev/null +++ b/tools/dfu.c @@ -0,0 +1,169 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "dfu.h" + +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif + +#ifndef USB_DIR_IN +#define USB_DIR_IN 0x80 +#endif + +#ifndef USB_DT_DFU +#define USB_DT_DFU 0x21 +#endif + +#define DFU_PACKETSIZE 0x03ff /* CSR default value: 1023 */ +#define DFU_TIMEOUT 10000 + +static uint32_t dfu_crc32_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +uint32_t crc32_init(void) +{ + return 0xffffffff; +} + +uint32_t crc32_byte(uint32_t accum, uint8_t delta) +{ + return dfu_crc32_table[(accum ^ delta) & 0xff] ^ (accum >> 8); +} + +int dfu_detach(struct usb_dev_handle *udev, int intf) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + DFU_DETACH, 0x1388, intf, NULL, 0, DFU_TIMEOUT); +} + +int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_UPLOAD, block, intf, buffer, size, DFU_TIMEOUT); +} + +int dfu_download(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, + DFU_DNLOAD, block, intf, buffer, size, DFU_TIMEOUT); +} + +int dfu_get_status(struct usb_dev_handle *udev, int intf, struct dfu_status *status) +{ + if (!udev || !status) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_GETSTATUS, 0, intf, (unsigned char *) status, DFU_STATUS_SIZE, DFU_TIMEOUT); +} + +int dfu_clear_status(struct usb_dev_handle *udev, int intf) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_CLRSTATUS, 0, intf, NULL, 0, DFU_TIMEOUT); +} + +int dfu_get_state(struct usb_dev_handle *udev, int intf, uint8_t *state) +{ + if (!udev || !state) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_GETSTATE, 0, intf, (unsigned char *) state, 1, DFU_TIMEOUT); +} + +int dfu_abort(struct usb_dev_handle *udev, int intf) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_ABORT, 0, intf, NULL, 0, DFU_TIMEOUT); +} diff --git a/tools/dfu.h b/tools/dfu.h new file mode 100644 index 00000000..1a253505 --- /dev/null +++ b/tools/dfu.h @@ -0,0 +1,108 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * $Id$ + */ + +#include + +/* CRC interface */ +uint32_t crc32_init(void); +uint32_t crc32_byte(uint32_t accum, uint8_t delta); + +/* DFU descriptor */ +struct usb_dfu_descriptor { + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int8_t bmAttributes; + u_int16_t wDetachTimeout; + u_int16_t wTransferSize; +}; + +/* DFU commands */ +#define DFU_DETACH 0 +#define DFU_DNLOAD 1 +#define DFU_UPLOAD 2 +#define DFU_GETSTATUS 3 +#define DFU_CLRSTATUS 4 +#define DFU_GETSTATE 5 +#define DFU_ABORT 6 + +/* DFU status */ +struct dfu_status { + uint8_t bStatus; + uint8_t bwPollTimeout[3]; + uint8_t bState; + uint8_t iString; +} __attribute__ ((packed)); +#define DFU_STATUS_SIZE 6 + +/* DFU status */ +#define DFU_OK 0x00 +#define DFU_ERR_TARGET 0x01 +#define DFU_ERR_FILE 0x02 +#define DFU_ERR_WRITE 0x03 +#define DFU_ERR_ERASE 0x04 +#define DFU_ERR_CHECK_ERASED 0x05 +#define DFU_ERR_PROG 0x06 +#define DFU_ERR_VERIFY 0x07 +#define DFU_ERR_ADDRESS 0x08 +#define DFU_ERR_NOTDONE 0x09 +#define DFU_ERR_FIRMWARE 0x0a +#define DFU_ERR_VENDOR 0x0b +#define DFU_ERR_USBR 0x0c +#define DFU_ERR_POR 0x0d +#define DFU_ERR_UNKNOWN 0x0e +#define DFU_ERR_STALLEDPKT 0x0f + +/* DFU state */ +#define DFU_STATE_APP_IDLE 0 +#define DFU_STATE_APP_DETACH 1 +#define DFU_STATE_DFU_IDLE 2 +#define DFU_STATE_DFU_DNLOAD_SYNC 3 +#define DFU_STATE_DFU_DNLOAD_BUSY 4 +#define DFU_STATE_DFU_DNLOAD_IDLE 5 +#define DFU_STATE_DFU_MANIFEST_SYNC 6 +#define DFU_STATE_DFU_MANIFEST 7 +#define DFU_STATE_MANIFEST_WAIT_RESET 8 +#define DFU_STATE_UPLOAD_IDLE 9 +#define DFU_STATE_ERROR 10 + +/* DFU suffix */ +struct dfu_suffix { + uint16_t bcdDevice; + uint16_t idProduct; + uint16_t idVendor; + uint16_t bcdDFU; + uint8_t ucDfuSignature[3]; + uint8_t bLength; + uint32_t dwCRC; +} __attribute__ ((packed)); +#define DFU_SUFFIX_SIZE 16 + +/* DFU interface */ +int dfu_detach(struct usb_dev_handle *udev, int intf); +int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size); +int dfu_download(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size); +int dfu_get_status(struct usb_dev_handle *udev, int intf, struct dfu_status *status); +int dfu_clear_status(struct usb_dev_handle *udev, int intf); +int dfu_get_state(struct usb_dev_handle *udev, int intf, uint8_t *state); +int dfu_abort(struct usb_dev_handle *udev, int intf); diff --git a/tools/dfutool.1 b/tools/dfutool.1 new file mode 100644 index 00000000..78b1fe7f --- /dev/null +++ b/tools/dfutool.1 @@ -0,0 +1,53 @@ +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH DFUTOOL 1 "APRIL 21, 2005" "" "" + +.SH NAME +dfutool \- Device Firmware Upgrade utility +.SH SYNOPSIS +.BR "dfutool +[ +.I options +] < +.I command +> +.SH DESCRIPTION +.B dfutool +is used to verify, archive and upgrade firmware files. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands. +.TP +.BI -d " " +The command specifies the device to use. +.SH COMMANDS +.TP +.BI verify " " +Display information about the firmware file. +.TP +.BI modify " " +Change DFU specific values in the firmware file. +.TP +.BI upgrade " " +Upgrade the device with a new firmware. +.TP +.BI archive " " +Archive the current firmware of the device. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/dfutool.c b/tools/dfutool.c new file mode 100644 index 00000000..47510cef --- /dev/null +++ b/tools/dfutool.c @@ -0,0 +1,763 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dfu.h" + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifndef USB_CLASS_WIRELESS +#define USB_CLASS_WIRELESS 0xe0 +#endif + +#ifndef USB_CLASS_APPLICATION +#define USB_CLASS_APPLICATION 0xfe +#endif + +static int get_interface_number(struct usb_device *dev) +{ + int c, i, a; + + for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { + struct usb_config_descriptor *config = &dev->config[c]; + + for (i = 0; i < config->bNumInterfaces; i++) { + struct usb_interface *interface = &config->interface[i]; + + for (a = 0; a < interface->num_altsetting; a++) { + struct usb_interface_descriptor *desc = &interface->altsetting[a]; + + if (desc->bInterfaceClass != USB_CLASS_APPLICATION) + continue; + if (desc->bInterfaceSubClass != 0x01) + continue; + if (desc->bInterfaceProtocol != 0x00) + continue; + + return desc->bInterfaceNumber; + } + } + } + + return -1; +} + +static void print_device(struct usb_device *dev) +{ + printf("Bus %s Device %s: ID %04x:%04x Interface %d%s\n", + dev->bus->dirname, dev->filename, + dev->descriptor.idVendor, dev->descriptor.idProduct, + get_interface_number(dev), + dev->descriptor.bDeviceClass == USB_CLASS_APPLICATION ? " (DFU mode)" : ""); +} + +static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffix) +{ + struct usb_bus *bus; + struct usb_device *dev, *dfu_dev[10]; + struct usb_dev_handle *udev; + struct dfu_status status; + char str[8]; + int i, intf, sel, num = 0, try = 5, bus_id = -1, dev_id = -1; + + printf("Scanning USB busses ... "); + fflush(stdout); + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) { + if (bus_id > 0) { + snprintf(str, sizeof(str) - 1, "%03i", bus_id); + if (strcmp(str, bus->dirname)) + continue; + } + + for (dev = bus->devices; dev; dev = dev->next) { + if (bus_id > 0 && dev_id > 0) { + snprintf(str, sizeof(str) - 1, "%03i", dev_id); + if (strcmp(str, dev->filename)) + continue; + } + + if (dev->descriptor.bDeviceClass == USB_CLASS_HUB) + continue; + + if (num > 9 || get_interface_number(dev) < 0) + continue; + + dfu_dev[num++] = dev; + } + } + + if (num < 1) { + printf("\rCan't find any DFU devices\n"); + return NULL; + } + + printf("\rAvailable devices with DFU support:\n\n"); + for (i = 0; i < num; i++) { + printf("\t%2d) ", i + 1); + print_device(dfu_dev[i]); + } + printf("\n"); + + do { + printf("\rSelect device (abort with 0): "); + fflush(stdout); + memset(str, 0, sizeof(str)); + fgets(str, sizeof(str) - 1, stdin); + sel = atoi(str); + } while (!isdigit(str[0]) || sel < 0 || sel > num ); + + if (sel < 1) + return NULL; + + sel--; + intf = get_interface_number(dfu_dev[sel]); + printf("\n"); + + udev = usb_open(dfu_dev[sel]); + if (!udev) { + printf("Can't open device: %s (%d)\n", strerror(errno), errno); + return NULL; + } + + if (usb_claim_interface(udev, intf) < 0) { + printf("Can't claim interface: %s (%d)\n", strerror(errno), errno); + usb_close(udev); + return NULL; + } + + if (dfu_get_status(udev, intf, &status) < 0) { + printf("Can't get status: %s (%d)\n", strerror(errno), errno); + goto error; + } + + if (status.bState == DFU_STATE_ERROR) { + if (dfu_clear_status(udev, intf) < 0) { + printf("Can't clear status: %s (%d)\n", strerror(errno), errno); + goto error; + } + if (dfu_abort(udev, intf) < 0) { + printf("Can't abort previous action: %s (%d)\n", strerror(errno), errno); + goto error; + } + if (dfu_get_status(udev, intf, &status) < 0) { + printf("Can't get status: %s (%d)\n", strerror(errno), errno); + goto error; + } + } + + if (status.bState == DFU_STATE_DFU_IDLE) { + if (suffix) { + suffix->idVendor = 0x0000; + suffix->idProduct = 0x0000; + suffix->bcdDevice = 0x0000; + } + return udev; + } + + if (status.bState != DFU_STATE_APP_IDLE) { + printf("Device is not idle, can't detach it (state %d)\n", status.bState); + goto error; + } + + printf("Switching device into DFU mode ... "); + fflush(stdout); + + if (suffix) { + suffix->idVendor = dfu_dev[sel]->descriptor.idVendor; + suffix->idProduct = dfu_dev[sel]->descriptor.idProduct; + suffix->bcdDevice = dfu_dev[sel]->descriptor.bcdDevice; + } + + if (dfu_detach(udev, intf) < 0) { + printf("\rCan't detach device: %s (%d)\n", strerror(errno), errno); + goto error; + } + + if (dfu_get_status(udev, intf, &status) < 0) { + printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); + goto error; + } + + if (status.bState != DFU_STATE_APP_DETACH) { + printf("\rDevice is not in detach mode, try again\n"); + goto error; + } + + usb_release_interface(udev, intf); + usb_reset(udev); + usb_close(udev); + + bus = dfu_dev[sel]->bus; + num = 0; + + while (num != 1 && try-- > 0) { + sleep(1); + usb_find_devices(); + + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.bDeviceClass != USB_CLASS_APPLICATION) + continue; + + if (suffix && dev->descriptor.idVendor != suffix->idVendor) + continue; + + if (num > 9 || get_interface_number(dev) != 0) + continue; + + dfu_dev[num++] = dev; + } + } + + if (num != 1) { + printf("\rCan't identify device with DFU mode\n"); + goto error; + } + + printf("\r"); + + intf = 0; + + udev = usb_open(dfu_dev[0]); + if (!udev) { + printf("Can't open device: %s (%d)\n", strerror(errno), errno); + return NULL; + } + + if (usb_claim_interface(udev, intf) < 0) { + printf("Can't claim interface: %s (%d)\n", strerror(errno), errno); + usb_close(udev); + return NULL; + } + + if (dfu_get_status(udev, intf, &status) < 0) { + printf("Can't get status: %s (%d)\n", strerror(errno), errno); + goto error; + } + + if (status.bState != DFU_STATE_DFU_IDLE) { + printf("Device is not in DFU mode, can't use it\n"); + goto error; + } + + return udev; + +error: + usb_release_interface(udev, intf); + usb_close(udev); + return NULL; +} + +static void usage(void); + +static void cmd_verify(char *device, int argc, char **argv) +{ + struct stat st; + struct dfu_suffix *suffix; + uint32_t crc; + char str[16]; + unsigned char *buf; + unsigned long size; + char *filename; + int i, fd, len; + + if (argc < 2) { + usage(); + exit(1); + } + + filename = argv[1]; + + if (stat(filename, &st) < 0) { + perror("Can't access firmware"); + exit(1); + } + + size = st.st_size; + + if (!(buf = malloc(size))) { + perror("Unable to allocate file buffer"); + exit(1); + } + + if ((fd = open(filename, O_RDONLY)) < 0) { + perror("Can't open firmware"); + free(buf); + exit(1); + } + + if (read(fd, buf, size) < size) { + perror("Can't load firmware"); + free(buf); + close(fd); + exit(1); + } + + printf("Filename\t%s\n", basename(filename)); + printf("Filesize\t%ld\n", size); + + crc = crc32_init(); + for (i = 0; i < size - 4; i++) + crc = crc32_byte(crc, buf[i]); + printf("Checksum\t%08x\n", crc); + + printf("\n"); + len = buf[size - 5]; + printf("DFU suffix\t"); + for (i = 0; i < len; i++) { + printf("%02x ", buf[size - len + i]); + } + printf("\n\n"); + + suffix = (struct dfu_suffix *) (buf + size - DFU_SUFFIX_SIZE); + + printf("idVendor\t%04x\n", suffix->idVendor); + printf("idProduct\t%04x\n", suffix->idProduct); + printf("bcdDevice\t%x\n", suffix->bcdDevice); + + printf("\n"); + + printf("bcdDFU\t\t%x.%x\n", suffix->bcdDFU >> 8, suffix->bcdDFU & 0xff); + printf("ucDfuSignature\t%c%c%c\n", suffix->ucDfuSignature[2], + suffix->ucDfuSignature[1], suffix->ucDfuSignature[0]); + printf("bLength\t\t%d\n", suffix->bLength); + printf("dwCRC\t\t%08x\n", suffix->dwCRC); + printf("\n"); + + memset(str, 0, sizeof(str)); + memcpy(str, buf, 8); + + if (!strcmp(str, "CSR-dfu1") || !strcmp(str, "CSR-dfu2")) { + crc = crc32_init(); + for (i = 0; i < size - DFU_SUFFIX_SIZE; i++) + crc = crc32_byte(crc, buf[i]); + + printf("Firmware type\t%s\n", str); + printf("Firmware check\t%s checksum\n", crc == 0 ? "valid" : "corrupt"); + printf("\n"); + } + + free(buf); + + close(fd); +} + +static void cmd_modify(char *device, int argc, char **argv) +{ +} + +static void cmd_upgrade(char *device, int argc, char **argv) +{ + struct usb_dev_handle *udev; + struct dfu_status status; + struct dfu_suffix suffix; + struct stat st; + unsigned char *buf; + unsigned long filesize, count, timeout = 0; + char *filename; + uint32_t crc; + int fd, i, block, len, size, sent = 0, try = 10; + + if (argc < 2) { + usage(); + exit(1); + } + + filename = argv[1]; + + if (stat(filename, &st) < 0) { + perror("Can't access firmware"); + exit(1); + } + + filesize = st.st_size; + + if (!(buf = malloc(filesize))) { + perror("Unable to allocate file buffer"); + exit(1); + } + + if ((fd = open(filename, O_RDONLY)) < 0) { + perror("Can't open firmware"); + free(buf); + exit(1); + } + + if (read(fd, buf, filesize) < filesize) { + perror("Can't load firmware"); + free(buf); + close(fd); + exit(1); + } + + memcpy(&suffix, buf + filesize - DFU_SUFFIX_SIZE, sizeof(suffix)); + + printf("Filename\t%s\n", basename(filename)); + printf("Filesize\t%ld\n", filesize); + + crc = crc32_init(); + for (i = 0; i < filesize - 4; i++) + crc = crc32_byte(crc, buf[i]); + printf("Checksum\t%08x (%s)\n", crc, + crc == suffix.dwCRC ? "valid" : "corrupt"); + + if (crc != suffix.dwCRC) { + free(buf); + close(fd); + exit(1); + } + + printf("\n"); + + udev = open_device(device, &suffix); + if (!udev) + exit(1); + + printf("\r" " " " " " " " " " "); + printf("\rFirmware download ... "); + fflush(stdout); + + count = filesize - DFU_SUFFIX_SIZE; + block = 0; + + while (count) { + size = (count > 1023) ? 1023 : count; + + if (dfu_get_status(udev, 0, &status) < 0) { + if (try-- > 0) { + sleep(1); + continue; + } + printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); + goto done; + } + + if (status.bStatus != DFU_OK) { + if (try-- > 0) { + dfu_clear_status(udev, 0); + sleep(1); + continue; + } + printf("\rFirmware download ... aborting (status %d state %d)\n", + status.bStatus, status.bState); + goto done; + } + + if (status.bState != DFU_STATE_DFU_IDLE && + status.bState != DFU_STATE_DFU_DNLOAD_IDLE) { + sleep(1); + continue; + } + + timeout = (status.bwPollTimeout[2] << 16) | + (status.bwPollTimeout[1] << 8) | + status.bwPollTimeout[0]; + + usleep(timeout * 1000); + + len = dfu_download(udev, 0, block, buf + sent, size); + if (len < 0) { + if (try-- > 0) { + sleep(1); + continue; + } + printf("\rCan't upload next block: %s (%d)\n", strerror(errno), errno); + goto done; + } + + printf("\rFirmware download ... %d bytes ", block * 1023 + len); + fflush(stdout); + + sent += len; + count -= len; + block++; + } + + printf("\r" " " " " " " " " " "); + printf("\rFinishing firmware download ... "); + fflush(stdout); + + sleep(1); + + if (dfu_get_status(udev, 0, &status) < 0) { + printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); + goto done; + } + + timeout = (status.bwPollTimeout[2] << 16) | + (status.bwPollTimeout[1] << 8) | + status.bwPollTimeout[0]; + + usleep(timeout * 1000); + + if (count == 0) { + len = dfu_download(udev, 0, block, NULL, 0); + if (len < 0) { + printf("\rCan't send final block: %s (%d)\n", strerror(errno), errno); + goto done; + } + } + + printf("\r" " " " " " " " " " "); + printf("\rWaiting for device ... "); + fflush(stdout); + + sleep(10); + + printf("\n"); + +done: + free(buf); + close(fd); + + usb_release_interface(udev, 0); + usb_reset(udev); + usb_close(udev); +} + +static void cmd_archive(char *device, int argc, char **argv) +{ + struct usb_dev_handle *udev; + struct dfu_status status; + struct dfu_suffix suffix; + unsigned char buf[2048]; + unsigned long timeout = 0; + char *filename; + uint32_t crc; + int fd, i, n, len, try = 8; + + if (argc < 2) { + usage(); + exit(1); + } + + filename = argv[1]; + + udev = open_device(device, &suffix); + if (!udev) + exit(1); + + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + printf("Can't open firmware file: %s (%d)\n", strerror(errno), errno); + goto done; + } + + printf("\r" " " " " " " " " " "); + printf("\rFirmware upload ... "); + fflush(stdout); + + crc = crc32_init(); + n = 0; + while (1) { + if (dfu_get_status(udev, 0, &status) < 0) { + if (try-- > 0) { + sleep(1); + continue; + } + printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); + goto done; + } + + if (status.bStatus != DFU_OK) { + if (try-- > 0) { + dfu_clear_status(udev, 0); + sleep(1); + continue; + } + printf("\rFirmware upload ... aborting (status %d state %d)\n", + status.bStatus, status.bState); + goto done; + } + + if (status.bState != DFU_STATE_DFU_IDLE && + status.bState != DFU_STATE_UPLOAD_IDLE) { + sleep(1); + continue; + } + + timeout = (status.bwPollTimeout[2] << 16) | + (status.bwPollTimeout[1] << 8) | + status.bwPollTimeout[0]; + + usleep(timeout * 1000); + + len = dfu_upload(udev, 0, n, buf, 1023); + if (len < 0) { + if (try-- > 0) { + sleep(1); + continue; + } + printf("\rCan't upload next block: %s (%d)\n", strerror(errno), errno); + goto done; + } + + printf("\rFirmware upload ... %d bytes ", n * 1023 + len); + fflush(stdout); + + for (i = 0; i < len; i++) + crc = crc32_byte(crc, buf[i]); + + if (len > 0) + write(fd, buf, len); + + n++; + if (len != 1023) + break; + } + printf("\n"); + + suffix.bcdDFU = 0x0100; + suffix.ucDfuSignature[0] = 'U'; + suffix.ucDfuSignature[1] = 'F'; + suffix.ucDfuSignature[2] = 'D'; + suffix.bLength = DFU_SUFFIX_SIZE; + + memcpy(buf, &suffix, DFU_SUFFIX_SIZE); + for (i = 0; i < DFU_SUFFIX_SIZE - 4; i++) + crc = crc32_byte(crc, buf[i]); + + suffix.dwCRC = crc; + + write(fd, &suffix, DFU_SUFFIX_SIZE); + +done: + close(fd); + + usb_release_interface(udev, 0); + usb_reset(udev); + usb_close(udev); +} + +struct { + char *cmd; + char *alt; + void (*func)(char *device, int argc, char **argv); + char *opt; + char *doc; +} command[] = { + { "verify", "check", cmd_verify, "", "Check firmware file" }, + { "modify", "change", cmd_modify, "", "Change firmware attributes" }, + { "upgrade", "download", cmd_upgrade, "", "Download a new firmware" }, + { "archive", "upload", cmd_archive, "", "Upload the current firmware" }, + { NULL, NULL, NULL, 0, 0 } +}; + +static void usage(void) +{ + int i; + + printf("dfutool - Device Firmware Upgrade utility ver %s\n\n", VERSION); + + printf("Usage:\n" + "\tdfutool [options] \n" + "\n"); + + printf("Options:\n" + "\t-d, --device USB device\n" + "\t-h, --help Display help\n" + "\n"); + + printf("Commands:\n"); + for (i = 0; command[i].cmd; i++) + printf("\t%-8s %-10s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); + printf("\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'd' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + char *device = NULL; + int i, opt; + + while ((opt = getopt_long(argc, argv, "+d:h", main_options, NULL)) != -1) { + switch(opt) { + case 'd': + device = strdup(optarg); + break; + + case 'h': + usage(); + exit(0); + + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + usb_init(); + + for (i = 0; command[i].cmd; i++) { + if (strcmp(command[i].cmd, argv[0]) && strcmp(command[i].alt, argv[0])) + continue; + command[i].func(device, argc, argv); + exit(0); + } + + usage(); + exit(1); +} -- cgit From 70e5fac9bd0fb2294eb7e585c005eb096ae84f5d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Apr 2005 11:52:29 +0000 Subject: Include sys/param.h for PATH_MAX --- tools/hcitool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index fb189760..a30e7098 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include -- cgit From cb079810a52ebbc4ec46c33b2a0f31a6b9c8c778 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Apr 2005 12:18:52 +0000 Subject: Use the new textfile library --- tools/Makefile.am | 4 +++- tools/hcitool.c | 71 ++++++++++--------------------------------------------- 2 files changed, 16 insertions(+), 59 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 9756a8d8..1743771b 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -28,7 +28,7 @@ hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ hcitool_SOURCES = hcitool.c oui.h oui.c -hcitool_LDADD = @BLUEZ_LIBS@ +hcitool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a l2ping_LDADD = @BLUEZ_LIBS@ @@ -52,6 +52,8 @@ endif AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ +INCLUDES = -I$(top_srcdir)/common + man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ $(hid2hci_manfiles) $(dfutool_manfiles) diff --git a/tools/hcitool.c b/tools/hcitool.c index a30e7098..6e225cee 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include #include @@ -48,6 +46,7 @@ #include #include +#include "textfile.h" #include "oui.h" #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) @@ -280,65 +279,15 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; -static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer) { - char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int fd, pos, err = -ENOENT; + char filename[PATH_MAX + 1], addr[18]; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); - fd = open(filename, O_RDONLY); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_SH) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - if (!bacmp(&bdaddr, peer)) { - snprintf(name, 249, "%s", str); - err = 0; - break; - } - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - } - -unlock: - flock(fd, LOCK_UN); - -close: - close(fd); - return err; + ba2str(peer, addr); + return textfile_get(filename, addr); } /* Display local devices */ @@ -457,7 +406,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int num_rsp, length, flags; uint8_t cls[3], features[8]; uint16_t handle; - char addr[18], name[249], oui[9], *comp; + char addr[18], name[249], oui[9], *comp, *tmp; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -538,7 +487,13 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - nc = (read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) == 0); + tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr); + if (tmp) { + strncpy(name, tmp, 249); + free(tmp); + nc = 1; + } else + nc = 0; if (!extcls && !extinf && !extoui) { ba2str(&(info+i)->bdaddr, addr); -- cgit From be773ea1ce058211345171cff8c0ff3590ad0f9f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 23 Apr 2005 19:13:03 +0000 Subject: The pskey tool should be used for reading the boot mode --- tools/hciconfig.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 20ef065c..df9b211e 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1043,7 +1043,7 @@ static void print_rev_ericsson(int dd) static void print_rev_csr(int dd, uint16_t rev) { - uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, bootmode, error; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, error; if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { printf("\t%s\n", csr_buildidtostr(rev)); @@ -1064,9 +1064,6 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); - if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_INITIAL_BOOTMODE, &bootmode)) - printf("\tBoot mode: %d%s\n", bootmode, bootmode ? "" : " (HCI)"); - if (!csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error)) { if (error < 0x0100) printf("\tPanic code: 0x%02x\n", error); -- cgit From c5a582daf8c31440da7ddcfcde2ae0af6dcf7da8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Apr 2005 19:02:57 +0000 Subject: Add build id for BlueCore3-MM with HCI 19.2 firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 45324d3e..7b783da9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -270,6 +270,7 @@ static struct { { 1916, "HCI 19.2" }, { 1958, "HCI 19.2" }, { 1981, "HCI 19.2" }, + { 1982, "HCI 19.2" }, { 1989, "HCI 18.4" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, -- cgit From 2cd3e62a5415f9a0aa895ea4222606012e23d744 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 30 Apr 2005 11:48:00 +0000 Subject: Update for the Unified 20 firmware releases --- tools/csr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 7b783da9..b5691afa 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -269,9 +269,11 @@ static struct { { 1915, "HCI 19.2" }, { 1916, "HCI 19.2" }, { 1958, "HCI 19.2" }, - { 1981, "HCI 19.2" }, - { 1982, "HCI 19.2" }, + { 1981, "Unified 20a" }, + { 1982, "Unified 20a" }, { 1989, "HCI 18.4" }, + { 2062, "Unified 20a1" }, + { 2063, "Unified 20a1" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From d4dc3014bb2b70bee8504ed4b1a8348acef7da74 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 1 May 2005 14:54:11 +0000 Subject: Support storing and deleting of stored link keys --- tools/Makefile.am | 2 +- tools/hciconfig.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 1743771b..e9574f3e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -25,7 +25,7 @@ bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) noinst_PROGRAMS = hcisecfilter ppporc pskey hciconfig_SOURCES = hciconfig.c csr.h csr.c -hciconfig_LDADD = @BLUEZ_LIBS@ +hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a hcitool_SOURCES = hcitool.c oui.h oui.c hcitool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a diff --git a/tools/hciconfig.c b/tools/hciconfig.c index df9b211e..5f72ce66 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -45,6 +45,7 @@ #include #include +#include "textfile.h" #include "csr.h" static struct hci_dev_info di; @@ -689,6 +690,101 @@ static void cmd_voice(int ctl, int hdev, char *opt) } } +static int get_link_key(const bdaddr_t *local, const bdaddr_t *peer, uint8_t *key) +{ + char filename[PATH_MAX + 1], addr[18], tmp[3], *str; + int i; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); + + ba2str(peer, addr); + str = textfile_get(filename, addr); + if (!str) + return -EIO; + + memset(tmp, 0, sizeof(tmp)); + for (i = 0; i < 16; i++) { + memcpy(tmp, str + (i * 2), 2); + key[i] = (uint8_t) strtol(tmp, NULL, 16); + } + + free(str); + + return 0; +} + +static void cmd_putkey(int ctl, int hdev, char *opt) +{ + struct hci_dev_info di; + bdaddr_t bdaddr; + uint8_t key[16]; + int dd; + + if (!opt) + return; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (hci_devinfo(hdev, &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + str2ba(opt, &bdaddr); + if (get_link_key(&di.bdaddr, &bdaddr, key) < 0) { + fprintf(stderr, "Can't find link key for %s on hci%d\n", opt, hdev); + exit(1); + } + + if (hci_write_stored_link_key(dd, &bdaddr, key, 1000) < 0) { + fprintf(stderr, "Can't write stored link key on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + hci_close_dev(dd); +} + +static void cmd_delkey(int ctl, int hdev, char *opt) +{ + bdaddr_t bdaddr; + uint8_t all; + int dd; + + if (!opt) + return; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (!strcasecmp(opt, "all")) { + bacpy(&bdaddr, BDADDR_ANY); + all = 1; + } else { + str2ba(opt, &bdaddr); + all = 0; + } + + if (hci_delete_stored_link_key(dd, &bdaddr, all, 1000) < 0) { + fprintf(stderr, "Can't delete stored link key on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + hci_close_dev(dd); +} + static void cmd_commands(int ctl, int hdev, char *opt) { uint8_t cmds[64]; @@ -702,7 +798,7 @@ static void cmd_commands(int ctl, int hdev, char *opt) } if (hci_read_local_commands(dd, cmds, 1000) < 0) { - fprintf(stderr, "Can't read support commands hci%d: %s (%d)\n", + fprintf(stderr, "Can't read support commands on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -1235,6 +1331,8 @@ static struct { { "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" }, { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, + { "putkey", cmd_putkey, "", "Store link key on the device" }, + { "delkey", cmd_delkey, "", "Delete link key from the device" }, { "commands", cmd_commands, 0, "Display supported commands" }, { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, -- cgit From 3f8f26bc831ca52caa7cc8ca500ae814818977a8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 2 May 2005 15:45:57 +0000 Subject: Add support for Toshiba SR-1 service record --- tools/sdptool.c | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 83e86fb5..c7e58ac9 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1734,7 +1734,7 @@ end: return ret; } -static int add_audio_source(sdp_session_t *session, svc_info_t *si) +static int add_a2source(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, l2cap, avdtp, a2src; @@ -1793,7 +1793,7 @@ done: return ret; } -static int add_audio_sink(sdp_session_t *session, svc_info_t *si) +static int add_a2sink(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, l2cap, avdtp, a2snk; @@ -1855,7 +1855,7 @@ done: static unsigned char nokid_uuid[] = { 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; -static int add_nokia_id(sdp_session_t *session, svc_info_t *si) +static int add_nokiaid(sdp_session_t *session, svc_info_t *si) { sdp_record_t record; sdp_list_t *root, *svclass; @@ -1929,6 +1929,38 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) return 0; } +static unsigned char sr1_uuid[] = { 0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0, + 0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 }; + +static int add_sr1(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass; + uuid_t root_uuid, svclass_uuid; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) sr1_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Toshiba Speech Recognition SR-1 service record registered\n"); + + return 0; +} + struct { char *name; uint16_t class; @@ -1955,11 +1987,12 @@ struct { { "CIP", CIP_SVCLASS_ID, NULL }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, - { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source}, - { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, + { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, + { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, - { "NOKID", 0, add_nokia_id }, + { "NOKID", 0, add_nokiaid }, { "PCSUITE", 0, add_pcsuite }, + { "SR1", 0, add_sr1 }, { 0 } }; -- cgit From 25886ef5728f16533735b778d9fb5d1ab685768e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 12:40:56 +0000 Subject: Add service registration for SyncML Client --- tools/sdptool.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index c7e58ac9..51c13e09 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1852,6 +1852,51 @@ done: return ret; } +static unsigned char syncml_uuid[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 }; + +static int add_syncml(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; + uint8_t channel = si->channel? si->channel: 15; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) syncml_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_uuid16_create(&obex_uuid, OBEX_UUID); + proto = sdp_list_append(proto, sdp_list_append(NULL, &obex_uuid)); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_set_info_attr(&record, "SyncML Client", NULL, NULL); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("SyncML Client service record registered\n"); + + return 0; +} + static unsigned char nokid_uuid[] = { 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; @@ -1990,6 +2035,8 @@ struct { { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, + { "SYNCML", 0, add_syncml }, + { "NOKID", 0, add_nokiaid }, { "PCSUITE", 0, add_pcsuite }, { "SR1", 0, add_sr1 }, -- cgit From cc2dd8a3670f68984f324d6861a344cb68728a1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 13:28:15 +0000 Subject: Support searching for services with UUID-128 --- tools/sdptool.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 51c13e09..b81273cb 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2010,6 +2010,7 @@ struct { char *name; uint16_t class; int (*add)(sdp_session_t *sess, svc_info_t *si); + unsigned char *uuid; } service[] = { { "DID", PNP_INFO_SVCLASS_ID, NULL, }, @@ -2035,11 +2036,10 @@ struct { { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, - { "SYNCML", 0, add_syncml }, - - { "NOKID", 0, add_nokiaid }, - { "PCSUITE", 0, add_pcsuite }, - { "SR1", 0, add_sr1 }, + { "SYNCML", 0, add_syncml, syncml_uuid }, + { "NOKID", 0, add_nokiaid, nokid_uuid }, + { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, + { "SR1", 0, add_sr1, sr1_uuid }, { 0 } }; @@ -2333,6 +2333,7 @@ static char *search_help = static int cmd_search(int argc, char **argv) { struct search_context context; + unsigned char *uuid = NULL; uint16_t class = 0; bdaddr_t bdaddr; int has_addr = 0; @@ -2363,6 +2364,7 @@ static int cmd_search(int argc, char **argv) printf(search_help); return -1; } + /* Note : we need to find a way to support search combining * multiple services - Jean II */ context.svc = strdup(argv[0]); @@ -2378,19 +2380,24 @@ static int cmd_search(int argc, char **argv) for (i = 0; service[i].name; i++) if (strcasecmp(context.svc, service[i].name) == 0) { class = service[i].class; + uuid = service[i].uuid; break; } - if (!class) { + if (!class && !uuid) { printf("Unknown service %s\n", context.svc); return -1; } - } + } - sdp_uuid16_create(&context.group, class); + if (class) + sdp_uuid16_create(&context.group, class); + else + sdp_uuid128_create(&context.group, uuid); if (has_addr) return do_search(&bdaddr, &context); - return do_search(0, &context); + + return do_search(NULL, &context); } /* -- cgit From 18cb95673231d41455528a782b168ee05f32fe2b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 14:13:41 +0000 Subject: Add command for retrieving possible service records --- tools/sdptool.1 | 2 ++ tools/sdptool.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 86 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 91a28a84..c4f248eb 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -73,6 +73,8 @@ FTRN, NAP, GN, HID, CIP. .IP "\fBbrowse [--tree] [bdaddr]\fP" 10 Browse all available services on the device specified by a Bluetooth address as a parameter. +.IP "\fBrecords [--tree] bdaddr\fP" 10 +Retrieve all possible service records. .IP "\fBadd [ --channel=N ]\fP" 10 Add a service to the local \fBsdpd\fR. diff --git a/tools/sdptool.c b/tools/sdptool.c index b81273cb..64e3a464 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2085,7 +2085,7 @@ static int cmd_add(int argc, char **argv) memset(&si, 0, sizeof(si)); for_each_opt(opt, add_options, 0) { - switch(opt) { + switch (opt) { case 'c': si.channel = atoi(optarg); break; @@ -2103,11 +2103,12 @@ static int cmd_add(int argc, char **argv) } si.name = strdup(argv[0]); + return add_service(0, &si); } /* Delete local service */ -static int del_service(bdaddr_t *bdaddr, void *arg) +static int del_service(bdaddr_t *bdaddr, void *arg) { uint32_t handle, range = 0x0000ffff; sdp_list_t *attr; @@ -2118,11 +2119,13 @@ static int del_service(bdaddr_t *bdaddr, void *arg) printf("Record handle was not specified.\n"); return -1; } + sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); if (!sess) { printf("No local SDP server!\n"); return -1; } + handle = strtoul((char *)arg, 0, 16); attr = sdp_list_append(0, &range); rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr); @@ -2132,11 +2135,13 @@ static int del_service(bdaddr_t *bdaddr, void *arg) sdp_close(sess); return -1; } + if (sdp_record_unregister(sess, rec)) { printf("Failed to unregister service record: %s\n", strerror(errno)); sdp_close(sess); return -1; } + printf("Service Record deleted.\n"); sdp_close(sess); return 0; @@ -2156,7 +2161,7 @@ static int cmd_del(int argc, char **argv) int opt; for_each_opt(opt, del_options, 0) { - switch(opt) { + switch (opt) { default: printf(del_help); return -1; @@ -2169,7 +2174,8 @@ static int cmd_del(int argc, char **argv) printf(del_help); return -1; } - return del_service(0, argv[0]); + + return del_service(NULL, argv[0]); } /* @@ -2186,6 +2192,7 @@ static void inquiry(handler_t handler, void *arg) printf("Inquiry failed\n"); return; } + for (i = 0; i < count; i++) handler(&ii[i].bdaddr, arg); } @@ -2204,12 +2211,14 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) inquiry(do_search, context); return 0; } + sess = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY); ba2str(bdaddr, str); if (!sess) { printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno)); return -1; } + if (context->svc) printf("Searching for %s on %s ...\n", context->svc, str); else @@ -2249,6 +2258,7 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) free(seq); sdp_record_free(rec); } + sdp_close(sess); return 0; } @@ -2280,7 +2290,7 @@ static int cmd_browse(int argc, char **argv) sdp_uuid16_create(&context.group, PUBLIC_BROWSE_GROUP); for_each_opt(opt, browse_options, 0) { - switch(opt) { + switch (opt) { case 't': context.tree = 1; break; @@ -2307,7 +2317,8 @@ static int cmd_browse(int argc, char **argv) estr2ba(argv[0], &bdaddr); return do_search(&bdaddr, &context); } - return do_search(0, &context); + + return do_search(NULL, &context); } static struct option search_options[] = { @@ -2344,7 +2355,7 @@ static int cmd_search(int argc, char **argv) memset(&context, '\0', sizeof(struct search_context)); for_each_opt(opt, search_options, 0) { - switch(opt) { + switch (opt) { case 'b': estr2ba(optarg, &bdaddr); has_addr = 1; @@ -2405,7 +2416,7 @@ static int cmd_search(int argc, char **argv) * Not really useful to the user, just show how it can be done... * Jean II */ -static int get_service(bdaddr_t *bdaddr, struct search_context *context) +static int get_service(bdaddr_t *bdaddr, struct search_context *context, int quite) { sdp_list_t *attrid; uint32_t range = 0x0000ffff; @@ -2418,14 +2429,17 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context) printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno)); return -1; } + attrid = sdp_list_append(0, &range); rec = sdp_service_attr_req(session, context->handle, SDP_ATTR_REQ_RANGE, attrid); sdp_list_free(attrid, 0); sdp_close(session); if (!rec) { - printf("Service get request failed.\n"); + if (!quite) + printf("Service get request failed.\n"); return -1; } + if (context->tree) { /* Display full tree */ sdp_printf_service_attr(rec); @@ -2434,14 +2448,68 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context) print_service_attr(rec); } printf("\n"); + sdp_record_free(rec); return 0; } +static struct option records_options[] = { + { "help", 0, 0, 'h' }, + { "tree", 0, 0, 't' }, + { 0, 0, 0, 0 } +}; + +static char *records_help = + "Usage:\n" + "\trecords [--tree] bdaddr\n"; + +/* + * Request possible SDP service records + */ +static int cmd_records(int argc, char **argv) +{ + struct search_context context; + uint32_t base[] = { 0x10000, 0x1002e }; + bdaddr_t bdaddr; + int i, n, opt, num = 32; + + /* Initialise context */ + memset(&context, '\0', sizeof(struct search_context)); + + for_each_opt(opt, records_options, 0) { + switch (opt) { + case 't': + context.tree = 1; + break; + default: + printf(records_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(records_help); + return -1; + } + + /* Convert command line parameters */ + estr2ba(argv[0], &bdaddr); + + for (i = 0; i < sizeof(base) / sizeof(uint32_t); i++) + for (n = 0; n < num; n++) { + context.handle = base[i] + n; + get_service(&bdaddr, &context, 1); + } + + return 0; +} + static struct option get_options[] = { - { "help", 0,0, 'h' }, - { "bdaddr", 1,0, 'b' }, - { "tree", 0,0, 't' }, + { "help", 0,0, 'h' }, + { "bdaddr", 1,0, 'b' }, + { "tree", 0,0, 't' }, { 0, 0, 0, 0 } }; @@ -2463,7 +2531,7 @@ static int cmd_get(int argc, char **argv) memset(&context, '\0', sizeof(struct search_context)); for_each_opt(opt, get_options, 0) { - switch(opt) { + switch (opt) { case 'b': estr2ba(optarg, &bdaddr); has_addr = 1; @@ -2483,10 +2551,11 @@ static int cmd_get(int argc, char **argv) printf(get_help); return -1; } + /* Convert command line parameters */ context.handle = strtoul(argv[0], 0, 16); - return get_service(has_addr? &bdaddr: BDADDR_LOCAL, &context); + return get_service(has_addr ? &bdaddr : BDADDR_LOCAL, &context, 0); } static struct { @@ -2496,6 +2565,7 @@ static struct { } command[] = { { "search", cmd_search, "Search for a service" }, { "browse", cmd_browse, "Browse all available services" }, + { "records", cmd_records, "Request all records" }, { "add", cmd_add, "Add local service" }, { "del", cmd_del, "Delete local service" }, { "get", cmd_get, "Get local service" }, -- cgit From e7b5f3c69c6a7303b951e7a1398c87a568a16761 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 16:10:26 +0000 Subject: Include a raw mode for showing the original record tree --- tools/sdptool.1 | 21 ++-- tools/sdptool.c | 326 +++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 289 insertions(+), 58 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.1 b/tools/sdptool.1 index c4f248eb..5ed9e33e 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -65,15 +65,16 @@ local \fBsdpd\fR. .SH "COMMANDS" .PP The following commands are available. -.IP "\fBsearch [--bdaddr bdaddr] [--tree] service\fP" 10 +.IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] service\fP" 10 Search for services.. .IP "" 10 -Known service names are SP< DUN, LAN, FAX, OPUSH, -FTRN, NAP, GN, HID, CIP. -.IP "\fBbrowse [--tree] [bdaddr]\fP" 10 +Known service names are DID, SP, DUN, LAN, FAX, OPUSH, +FTP, HS, HF, SAP, NAP, GN, PANU, HID, CIP, CTP, A2SRC, A2SNK +and SYNCML. +.IP "\fBbrowse [--tree] [--raw] [bdaddr]\fP" 10 Browse all available services on the device specified by a Bluetooth address as a parameter. -.IP "\fBrecords [--tree] bdaddr\fP" 10 +.IP "\fBrecords [--tree] [--raw] bdaddr\fP" 10 Retrieve all possible service records. .IP "\fBadd [ --channel=N ]\fP" 10 Add a service to the local @@ -84,7 +85,7 @@ using the \fB--channel\fP option. .IP "\fBdel record_handle\fP" 10 Remove a service from the local \fBsdpd\fR. -.IP "\fBget [--tree] [--bdaddr bdaddr] record_handle\fP" 10 +.IP "\fBget [--tree] [--raw] [--bdaddr bdaddr] record_handle\fP" 10 Retrieve a service from the local \fBsdpd\fR. .IP "\fBsetattr record_handle attrib_id attrib_value\fP" 10 @@ -99,13 +100,13 @@ Displays help on using sdptool. .SH "EXAMPLES" .PP -sdptool browse 00:80:98:24:15:6D +sdptool browse 00:80:98:24:15:6D .PP -sdptool browse local +sdptool browse local .PP -sdptool add DUN +sdptool add DUN .PP -sdptool del LAN +sdptool del 0x10000 .SH "BUGS" .PP Documentation needs improving. diff --git a/tools/sdptool.c b/tools/sdptool.c index 64e3a464..d015f12f 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -36,9 +36,11 @@ #include #include +#include #include +#include #include -#include +#include #include #include @@ -46,6 +48,8 @@ #include #include +#include + #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1) /* @@ -61,11 +65,15 @@ static int estr2ba(char *str, bdaddr_t *ba) return str2ba(str, ba); } +#define DEFAULT_VIEW 0 /* Display only known attribute */ +#define TREE_VIEW 1 /* Display full attribute tree */ +#define RAW_VIEW 2 /* Display raw tree */ + /* Pass args to the inquiry/search handler */ struct search_context { char *svc; /* Service */ uuid_t group; /* Browse group */ - int tree; /* Display full attribute tree */ + int view; /* View mode */ uint32_t handle; /* Service record handle */ }; @@ -219,7 +227,7 @@ static struct attrib_def audio_attrib_names[] = { /* Same for the UUIDs. See BT assigned numbers */ static struct uuid_def uuid16_names[] = { /* -- Protocols -- */ - { 0x0001, "SDP (Service Discovery Protocol)", NULL, 0 }, + { 0x0001, "SDP", NULL, 0 }, { 0x0002, "UDP", NULL, 0 }, { 0x0003, "RFCOMM", NULL, 0 }, { 0x0004, "TCP", NULL, 0 }, @@ -230,7 +238,7 @@ static struct uuid_def uuid16_names[] = { { 0x000a, "FTP", NULL, 0 }, { 0x000c, "HTTP", NULL, 0 }, { 0x000e, "WSP", NULL, 0 }, - { 0x000f, "BNEP (PAN/BNEP)", NULL, 0 }, + { 0x000f, "BNEP", NULL, 0 }, { 0x0010, "UPnP/ESDP", NULL, 0 }, { 0x0011, "HIDP", NULL, 0 }, { 0x0012, "HardcopyControlChannel", NULL, 0 }, @@ -242,11 +250,11 @@ static struct uuid_def uuid16_names[] = { { 0x001d, "UDI_C-Plane", NULL, 0 }, { 0x0100, "L2CAP", NULL, 0 }, /* -- Services -- */ - { 0x1000, "ServiceDiscoveryServerServiceClassID (SDP)", + { 0x1000, "ServiceDiscoveryServerServiceClassID", sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) }, - { 0x1001, "BrowseGroupDescriptorServiceClassID (SDP)", + { 0x1001, "BrowseGroupDescriptorServiceClassID", browse_attrib_names, sizeof(browse_attrib_names)/sizeof(struct attrib_def) }, - { 0x1002, "PublicBrowseGroup (SDP)", NULL, 0 }, + { 0x1002, "PublicBrowseGroup", NULL, 0 }, { 0x1101, "SerialPort", NULL, 0 }, { 0x1102, "LANAccessUsingPPP", NULL, 0 }, { 0x1103, "DialupNetworking (DUN)", NULL, 0 }, @@ -276,7 +284,10 @@ static struct uuid_def uuid16_names[] = { pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, { 0x1118, "DirectPrinting (BPP)", NULL, 0 }, { 0x1119, "ReferencePrinting (BPP)", NULL, 0 }, - /* ... */ + { 0x111a, "Imaging (BIP)", NULL, 0 }, + { 0x111b, "ImagingResponder (BIP)", NULL, 0 }, + { 0x111c, "ImagingAutomaticArchive (BIP)", NULL, 0 }, + { 0x111d, "ImagingReferencedObjects (BIP)", NULL, 0 }, { 0x111e, "Handsfree", NULL, 0 }, { 0x111f, "HandsfreeAudioGateway", NULL, 0 }, { 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 }, @@ -411,9 +422,9 @@ static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, char *member_name = NULL; /* Find member name. Almost black magic ;-) */ - if (context->attrib && context->attrib->members && - context->member_index < context->attrib->member_max) { - member_name = context->attrib->members[context->member_index].name; + if (context && context->attrib && context->attrib->members && + context->member_index < context->attrib->member_max) { + member_name = context->attrib->members[context->member_index].name; } switch (sdpdata->dtd) { @@ -484,7 +495,7 @@ static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, /* * Parse a single attribute. */ -static void sdp_attr_printf_func(void *value, void *userData) +static void print_tree_attr_func(void *value, void *userData) { sdp_data_t *sdpdata = NULL; uint16_t attrId; @@ -535,11 +546,191 @@ static void sdp_attr_printf_func(void *value, void *userData) * We assume the record has already been read, parsed and cached * locally. Jean II */ -static void sdp_printf_service_attr(sdp_record_t *rec) +static void print_tree_attr(sdp_record_t *rec) { if (rec && rec->attrlist) { struct service_context service = { NULL }; - sdp_list_foreach(rec->attrlist, sdp_attr_printf_func, &service); + sdp_list_foreach(rec->attrlist, print_tree_attr_func, &service); + } +} + +static void print_raw_data(sdp_data_t *data, int indent) +{ + struct uuid_def *def; + char *str; + int i, hex; + + if (!data) + return; + + for (i = 0; i < indent; i++) + printf("\t"); + + switch (data->dtd) { + case SDP_DATA_NIL: + printf("NIL\n"); + break; + case SDP_BOOL: + printf("Bool %s\n", data->val.uint8 ? "True" : "False"); + break; + case SDP_UINT8: + printf("UINT8 0x%02x\n", data->val.uint8); + break; + case SDP_UINT16: + printf("UINT16 0x%04x\n", data->val.uint16); + break; + case SDP_UINT32: + printf("UINT32 0x%08x\n", data->val.uint32); + break; + case SDP_UINT64: + printf("UINT64 0x%016llx\n", data->val.uint64); + break; + case SDP_UINT128: + printf("UINT128 ...\n"); + break; + case SDP_INT8: + printf("INT8 %d\n", data->val.int8); + break; + case SDP_INT16: + printf("INT16 %d\n", data->val.int16); + break; + case SDP_INT32: + printf("INT32 %d\n", data->val.int32); + break; + case SDP_INT64: + printf("INT64 %lld\n", data->val.int64); + break; + case SDP_INT128: + printf("INT128 ...\n"); + break; + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + switch (data->val.uuid.type) { + case SDP_UUID16: + def = NULL; + for (i = 0; i < uuid16_max; i++) + if (uuid16_names[i].num == data->val.uuid.value.uuid16) { + def = &uuid16_names[i]; + break; + } + if (def) + printf("UUID16 0x%04x - %s\n", data->val.uuid.value.uuid16, def->name); + else + printf("UUID16 0x%04x\n", data->val.uuid.value.uuid16); + break; + case SDP_UUID32: + def = NULL; + if (!(data->val.uuid.value.uuid32 & 0xffff0000)) { + uint16_t value = data->val.uuid.value.uuid32; + for (i = 0; i < uuid16_max; i++) + if (uuid16_names[i].num == value) { + def = &uuid16_names[i]; + break; + } + } + if (def) + printf("UUID32 0x%08x - %s\n", data->val.uuid.value.uuid32, def->name); + else + printf("UUID32 0x%08x\n", data->val.uuid.value.uuid32); + break; + case SDP_UUID128: + printf("UUID128 "); + for (i = 0; i < 16; i++) { + switch (i) { + case 4: + case 6: + case 8: + case 10: + printf("-"); + break; + } + printf("%02x", (unsigned char ) data->val.uuid.value.uuid128.data[i]); + } + printf("\n"); + break; + default: + printf("UUID type 0x%02x\n", data->val.uuid.type); + break; + } + break; + case SDP_TEXT_STR8: + case SDP_TEXT_STR16: + case SDP_TEXT_STR32: + str = data->val.str; + if (data->unitSize > strlen(str) + 1) { + hex = 0; + for (i = 0; i < data->unitSize - 1; i++) + if (!isprint(str[i])) { + hex = 1; + break; + } + if (str[data->unitSize - 1] != '\0') + hex = 1; + } else + hex = 0; + if (hex) { + printf("String"); + for (i = 0; i < data->unitSize; i++) + printf(" %02x", (unsigned char) str[i]); + printf("\n"); + } else + printf("String %s\n", str); + break; + case SDP_URL_STR8: + case SDP_URL_STR16: + case SDP_URL_STR32: + printf("URL %s\n", data->val.str); + break; + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + printf("Sequence\n"); + print_raw_data(data->val.dataseq, indent + 1); + break; + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + printf("Alternate\n"); + print_raw_data(data->val.dataseq, indent + 1); + break; + default: + printf("Unknown type 0x%02x\n", data->dtd); + break; + } + + print_raw_data(data->next, indent); +} + +static void print_raw_attr_func(void *value, void *userData) +{ + sdp_data_t *data = (sdp_data_t *) value; + struct attrib_def *def = NULL; + int i; + + /* Search amongst the generic attributes */ + for (i = 0; i < attrib_max; i++) + if (attrib_names[i].num == data->attrId) { + def = &attrib_names[i]; + break; + } + + if (def) + printf("\tAttribute 0x%04x - %s\n", data->attrId, def->name); + else + printf("\tAttribute 0x%04x\n", data->attrId); + + if (data) + print_raw_data(data, 2); + else + printf(" NULL value\n"); +} + +static void print_raw_attr(sdp_record_t *rec) +{ + if (rec && rec->attrlist) { + printf("Sequence\n"); + sdp_list_foreach(rec->attrlist, print_raw_attr_func, 0); } } @@ -2219,10 +2410,12 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) return -1; } - if (context->svc) - printf("Searching for %s on %s ...\n", context->svc, str); - else - printf("Browsing %s ...\n", str); + if (context->view != RAW_VIEW) { + if (context->svc) + printf("Searching for %s on %s ...\n", context->svc, str); + else + printf("Browsing %s ...\n", str); + } attrid = sdp_list_append(0, &range); search = sdp_list_append(0, &context->group); @@ -2238,15 +2431,23 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) sdp_record_t *rec = (sdp_record_t *) seq->data; struct search_context sub_context; - if (context->tree) { - /* Display full tree */ - sdp_printf_service_attr(rec); - } else { + switch (context->view) { + case DEFAULT_VIEW: /* Display user friendly form */ print_service_attr(rec); + printf("\n"); + break; + case TREE_VIEW: + /* Display full tree */ + print_tree_attr(rec); + printf("\n"); + break; + default: + /* Display raw tree */ + print_raw_attr(rec); + break; } - printf("\n"); - + if (sdp_get_group_id(rec, &sub_context.group) != -1) { /* Set the subcontext for browsing the sub tree */ memcpy(&sub_context, context, sizeof(struct search_context)); @@ -2266,6 +2467,7 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) static struct option browse_options[] = { { "help", 0, 0, 'h' }, { "tree", 0, 0, 't' }, + { "raw", 0, 0, 'r' }, { "uuid", 1, 0, 'u' }, { "l2cap", 0, 0, 'l' }, { 0, 0, 0, 0 } @@ -2273,7 +2475,7 @@ static struct option browse_options[] = { static char *browse_help = "Usage:\n" - "\tbrowse [--tree] [--uuid uuid] [--l2cap] [bdaddr]\n"; + "\tbrowse [--tree] [--raw] [--uuid uuid] [--l2cap] [bdaddr]\n"; /* * Browse the full SDP database (i.e. list all services starting from the @@ -2292,7 +2494,10 @@ static int cmd_browse(int argc, char **argv) for_each_opt(opt, browse_options, 0) { switch (opt) { case 't': - context.tree = 1; + context.view = TREE_VIEW; + break; + case 'r': + context.view = RAW_VIEW; break; case 'u': if (sscanf(optarg, "%i", &num) != 1 || num < 0 || num > 0xffff) { @@ -2322,15 +2527,16 @@ static int cmd_browse(int argc, char **argv) } static struct option search_options[] = { - { "help", 0,0, 'h' }, - { "bdaddr", 1,0, 'b' }, - { "tree", 0,0, 't' }, + { "help", 0,0, 'h' }, + { "bdaddr", 1,0, 'b' }, + { "tree", 0,0, 't' }, + { "raw", 0, 0, 'r' }, { 0, 0, 0, 0} }; static char *search_help = "Usage:\n" - "\tsearch [--bdaddr bdaddr] [--tree] SERVICE\n" + "\tsearch [--bdaddr bdaddr] [--tree] [--raw] SERVICE\n" "SERVICE is a name (string) or UUID (0x1002)\n"; /* @@ -2361,7 +2567,10 @@ static int cmd_search(int argc, char **argv) has_addr = 1; break; case 't': - context.tree = 1; + context.view = TREE_VIEW; + break; + case 'r': + context.view = RAW_VIEW; break; default: printf(search_help); @@ -2435,19 +2644,29 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int qui sdp_list_free(attrid, 0); sdp_close(session); if (!rec) { - if (!quite) + if (!quite) { printf("Service get request failed.\n"); - return -1; + return -1; + } else + return 0; } - if (context->tree) { - /* Display full tree */ - sdp_printf_service_attr(rec); - } else { + switch (context->view) { + case DEFAULT_VIEW: /* Display user friendly form */ print_service_attr(rec); + printf("\n"); + break; + case TREE_VIEW: + /* Display full tree */ + print_tree_attr(rec); + printf("\n"); + break; + default: + /* Display raw tree */ + print_raw_attr(rec); + break; } - printf("\n"); sdp_record_free(rec); return 0; @@ -2456,12 +2675,13 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int qui static struct option records_options[] = { { "help", 0, 0, 'h' }, { "tree", 0, 0, 't' }, + { "raw", 0, 0, 'r' }, { 0, 0, 0, 0 } }; static char *records_help = "Usage:\n" - "\trecords [--tree] bdaddr\n"; + "\trecords [--tree] [--raw] bdaddr\n"; /* * Request possible SDP service records @@ -2469,9 +2689,9 @@ static char *records_help = static int cmd_records(int argc, char **argv) { struct search_context context; - uint32_t base[] = { 0x10000, 0x1002e }; + uint32_t base[] = { 0x10000, 0x1002e, 0x110b }; bdaddr_t bdaddr; - int i, n, opt, num = 32; + int i, n, opt, err = 0, num = 32; /* Initialise context */ memset(&context, '\0', sizeof(struct search_context)); @@ -2479,7 +2699,10 @@ static int cmd_records(int argc, char **argv) for_each_opt(opt, records_options, 0) { switch (opt) { case 't': - context.tree = 1; + context.view = TREE_VIEW; + break; + case 'r': + context.view = RAW_VIEW; break; default: printf(records_help); @@ -2500,22 +2723,26 @@ static int cmd_records(int argc, char **argv) for (i = 0; i < sizeof(base) / sizeof(uint32_t); i++) for (n = 0; n < num; n++) { context.handle = base[i] + n; - get_service(&bdaddr, &context, 1); + err = get_service(&bdaddr, &context, 1); + if (err < 0) + goto done; } +done: return 0; } static struct option get_options[] = { - { "help", 0,0, 'h' }, - { "bdaddr", 1,0, 'b' }, - { "tree", 0,0, 't' }, + { "help", 0, 0, 'h' }, + { "bdaddr", 1, 0, 'b' }, + { "tree", 0, 0, 't' }, + { "raw", 0, 0, 'r' }, { 0, 0, 0, 0 } }; static char *get_help = "Usage:\n" - "\tget [--tree] [--bdaddr bdaddr] record_handle\n"; + "\tget [--tree] [--raw] [--bdaddr bdaddr] record_handle\n"; /* * Get a specific SDP record on the local SDP server @@ -2537,7 +2764,10 @@ static int cmd_get(int argc, char **argv) has_addr = 1; break; case 't': - context.tree = 1; + context.view = TREE_VIEW; + break; + case 'r': + context.view = RAW_VIEW; break; default: printf(get_help); -- cgit From 211002ea1a8e4b94afebc67f5b13eff46e09eb6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:21:43 +0000 Subject: Support reading of complex varid values --- tools/csr.c | 41 +++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 73 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index b5691afa..6ed0a08f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -399,6 +399,47 @@ char *csr_pskeytostr(uint16_t pskey) } } +int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + unsigned char cmd[] = { 0x00, 0x00, (length + 5) & 0xff, (length + 5) >> 8, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + memcpy(cp + 11, value, length); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 11, length); + + return 0; +} + int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, diff --git a/tools/csr.h b/tools/csr.h index 7aa90c31..c8ed9445 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -26,13 +26,37 @@ * $Id$ */ -#define CSR_VARID_BUILDID 0x2819 -#define CSR_VARID_CHIPVER 0x281a -#define CSR_VARID_CHIPREV 0x281b -#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c - -#define CSR_VARID_PANIC_ARG 0x6805 -#define CSR_VARID_FAULT_ARG 0x6806 +#define CSR_VARID_BC01_STATUS 0x2801 /* uint16 */ +#define CSR_VARID_BUILDID 0x2819 /* uint16 */ +#define CSR_VARID_CHIPVER 0x281a /* uint16 */ +#define CSR_VARID_CHIPREV 0x281b /* uint16 */ +#define CSR_VARID_INTERFACE_VERSION 0x2825 /* uint16 */ +#define CSR_VARID_RAND 0x282a /* uint16 */ +#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c /* uint16 */ +#define CSR_VARID_CHIPANAREV 0x2836 /* uint16 */ +#define CSR_VARID_BUILDID_LOADER 0x2838 /* uint16 */ +#define CSR_VARID_BT_CLOCK 0x2c00 /* uint32 */ +#define CSR_VARID_CRYPT_KEY_LENGTH 0x3008 /* complex */ +#define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */ +#define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ +#define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ +#define CSR_VARID_COLD_RESET 0x4001 /* valueless */ +#define CSR_VARID_WARM_RESET 0x4002 /* valueless */ +#define CSR_VARID_COLD_HALT 0x4003 /* valueless */ +#define CSR_VARID_WARM_HALT 0x4004 /* valueless */ +#define CSR_VARID_INIT_BT_STACK 0x4005 /* valueless */ +#define CSR_VARID_ACTIVATE_BT_STACK 0x4006 /* valueless */ +#define CSR_VARID_ENABLE_TX 0x4007 /* valueless */ +#define CSR_VARID_DISABLE_TX 0x4008 /* valueless */ +#define CSR_VARID_RECAL 0x4009 /* valueless */ +#define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ +#define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */ +#define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */ +#define CSR_VARID_CONFIG_UART 0x6802 /* uint16 */ +#define CSR_VARID_PANIC_ARG 0x6805 /* uint16 */ +#define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */ +#define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ +#define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab #define CSR_PSKEY_UART_BAUDRATE 0x01be @@ -46,6 +70,7 @@ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); +int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); -- cgit From ffa2b0a23afbb3616fd6f1fc9ec89cd116b61675 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:25:12 +0000 Subject: Fix length calculation for complex data --- tools/csr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 6ed0a08f..d1932cf4 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -401,7 +401,7 @@ char *csr_pskeytostr(uint16_t pskey) int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { - unsigned char cmd[] = { 0x00, 0x00, (length + 5) & 0xff, (length + 5) >> 8, + unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 5) & 0xff, ((length / 2) + 5) >> 8, seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -- cgit From ef1e3cfb87d1313ff2ebd4e4128be9a6e17072b2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:41:03 +0000 Subject: Add PSKEYs for min and max encryption key length --- tools/csr.c | 4 ++++ tools/csr.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index d1932cf4..9fbdba17 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -380,6 +380,10 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) char *csr_pskeytostr(uint16_t pskey) { switch (pskey) { + case CSR_PSKEY_ENC_KEY_LMIN: + return "Minimum encryption key length"; + case CSR_PSKEY_ENC_KEY_LMAX: + return "Maximum encryption key length"; case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; case CSR_PSKEY_UART_BAUDRATE: diff --git a/tools/csr.h b/tools/csr.h index c8ed9445..42dfb8d0 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -58,6 +58,8 @@ #define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ +#define CSR_PSKEY_ENC_KEY_LMIN 0x00da +#define CSR_PSKEY_ENC_KEY_LMAX 0x00db #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab #define CSR_PSKEY_UART_BAUDRATE 0x01be #define CSR_PSKEY_HOST_INTERFACE 0x01f9 -- cgit From 186a4118ec7cc9f105f4e23b49e71c2b0e46cfa4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:46:09 +0000 Subject: Support minimum and maximum encryption key length --- tools/pskey.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index edf78e8d..f0ce1b4a 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -91,6 +91,8 @@ static struct { int type; char *str; } storage[] = { + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, -- cgit From fd1420fe08910f599bbb3bc84840318d1b99f748 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:51:27 +0000 Subject: Add tool for the CSR BCCMD interface --- tools/Makefile.am | 5 +- tools/bccmd.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 tools/bccmd.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index e9574f3e..66839dd7 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -22,7 +22,7 @@ sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) -noinst_PROGRAMS = hcisecfilter ppporc pskey +noinst_PROGRAMS = hcisecfilter ppporc pskey bccmd hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a @@ -41,6 +41,9 @@ ppporc_LDADD = @BLUEZ_LIBS@ pskey_SOURCES = pskey.c csr.h csr.c pskey_LDADD = @BLUEZ_LIBS@ +bccmd_SOURCES = bccmd.c csr.h csr.c +bccmd_LDADD = @BLUEZ_LIBS@ + if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif diff --git a/tools/bccmd.c b/tools/bccmd.c new file mode 100644 index 00000000..4b4a1fb4 --- /dev/null +++ b/tools/bccmd.c @@ -0,0 +1,193 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + +static int cmd_keylen(int dd, int argc, char *argv[]) +{ + uint8_t buf[8]; + uint16_t handle, keylen; + int err; + + if (argc < 1) { + errno = EINVAL; + return -1; + } + + if (argc > 1) { + errno = E2BIG; + return -1; + } + + handle = atoi(argv[0]); + + memset(buf, 0, sizeof(buf)); + buf[0] = handle & 0xff; + buf[1] = handle >> 8; + + err = csr_read_varid_complex(dd, 0x4711, + CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); + if (err < 0) { + errno = -err; + return -1; + } + + handle = buf[0] | (buf[1] << 8); + keylen = buf[2] | (buf[3] << 8); + + printf("Crypt key length: %d bit\n", keylen * 8); + + return 0; +} + +static struct { + char *str; + int (*func)(int dd, int argc, char **argv); + char *arg; + char *doc; +} commands[] = { + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { NULL }, +}; + +static void usage(void) +{ + int i; + + printf("bccmd - Utility for the CSR BCCMD interface\n\n"); + printf("Usage:\n" + "\tbccmd [-i ] \n\n"); + + printf("Commands:\n"); + for (i = 0; commands[i].str; i++) + printf("\t%s\t%s\t%s\n", commands[i].str, + commands[i].arg, commands[i].doc); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct hci_dev_info di; + struct hci_version ver; + int i, err, dd, opt, dev = 0; + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + exit(1); + } + + if (hci_devinfo(dev, &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (ver.manufacturer != 10) { + fprintf(stderr, "Unsupported manufacturer\n"); + hci_close_dev(dd); + exit(1); + } + + for (i = 0; commands[i].str; i++) { + if (strcasecmp(commands[i].str, argv[0])) + continue; + + err = commands[i].func(dd, argc - 1, argv + 1); + + hci_close_dev(dd); + + if (err < 0) { + fprintf(stderr, "Can't execute command: %s (%d)\n", + strerror(errno), errno); + exit(1); + } + + exit(0); + } + + fprintf(stderr, "Unsupported command\n"); + + hci_close_dev(dd); + + exit(1); +} -- cgit From 34e0b4d0b4513834ec1c982ee201331579ec3e45 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 May 2005 19:49:56 +0000 Subject: Add build id for BlueCore2-PnG with Unified 18f firmware --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 9fbdba17..4829a66d 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -274,6 +274,8 @@ static struct { { 1989, "HCI 18.4" }, { 2062, "Unified 20a1" }, { 2063, "Unified 20a1" }, + { 2067, "Unified 18f" }, + { 2068, "Unified 18f" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From b07abfc01ed48a0e74e134fb36ef35ce8590ecc7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 8 Jun 2005 09:42:37 +0000 Subject: Add support for changing local and remote version information --- tools/csr.h | 21 ++++++++++++--------- tools/pskey.c | 34 ++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index 42dfb8d0..347e1d54 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -58,15 +58,18 @@ #define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ -#define CSR_PSKEY_ENC_KEY_LMIN 0x00da -#define CSR_PSKEY_ENC_KEY_LMAX 0x00db -#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab -#define CSR_PSKEY_UART_BAUDRATE 0x01be -#define CSR_PSKEY_HOST_INTERFACE 0x01f9 -#define CSR_PSKEY_USB_VENDOR_ID 0x02be -#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf -#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb -#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd +#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xFE8f, 0xF99B, 0x8000 } */ +#define CSR_PSKEY_ENC_KEY_LMIN 0x00da +#define CSR_PSKEY_ENC_KEY_LMAX 0x00db +#define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ +#define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab +#define CSR_PSKEY_UART_BAUDRATE 0x01be +#define CSR_PSKEY_HOST_INTERFACE 0x01f9 +#define CSR_PSKEY_USB_VENDOR_ID 0x02be +#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf +#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb +#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); diff --git a/tools/pskey.c b/tools/pskey.c index f0ce1b4a..2b4bc210 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -42,15 +42,16 @@ #include "csr.h" -#define CSR_TYPE_NULL 0 -#define CSR_TYPE_UINT16 1 +#define CSR_TYPE_NULL 0 +#define CSR_TYPE_UINT8 1 +#define CSR_TYPE_UINT16 2 static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { uint16_t value; int err; - if (type != CSR_TYPE_UINT16) { + if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { errno = EFAULT; return -1; } @@ -60,7 +61,10 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) return -1; } - value = atoi(argv[0]); + if (!strncasecmp(argv[0], "0x", 2)) + value = strtol(argv[0] + 2, NULL, 16); + else + value = atoi(argv[0]); err = csr_write_pskey_uint16(dd, 0x4711, pskey, value); @@ -72,7 +76,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) uint16_t value; int err; - if (type != CSR_TYPE_UINT16) { + if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { errno = EFAULT; return -1; } @@ -91,15 +95,17 @@ static struct { int type; char *str; } storage[] = { - { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, - { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, - { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, - { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, - { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, - { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, - { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, - { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, - { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, + { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, + { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, { 0x0000, CSR_TYPE_NULL, NULL }, }; -- cgit From f285dc875c194aab8b1048b53d9681b43fa1a18c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 10 Jun 2005 05:30:28 +0000 Subject: Allow reading of complex PS keys --- tools/csr.c | 48 +++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + tools/pskey.c | 73 ++++++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 99 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 4829a66d..6b34fc3f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -386,6 +386,12 @@ char *csr_pskeytostr(uint16_t pskey) return "Minimum encryption key length"; case CSR_PSKEY_ENC_KEY_LMAX: return "Maximum encryption key length"; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return "Local supported features block"; + case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: + return "The HCI and LMP version reported locally"; + case CSR_PSKEY_LMP_REMOTE_VERSION: + return "The LMP version reported remotely"; case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; case CSR_PSKEY_UART_BAUDRATE: @@ -486,6 +492,48 @@ int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *val return 0; } +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length) +{ + unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, + seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, + pskey & 0xff, pskey >> 8, + (length / 2) & 0xff, (length / 2) >> 8, + 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 17, length); + + return 0; +} + int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, diff --git a/tools/csr.h b/tools/csr.h index 347e1d54..61df145e 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -77,5 +77,6 @@ char *csr_pskeytostr(uint16_t pskey); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); diff --git a/tools/pskey.c b/tools/pskey.c index 2b4bc210..9a4dd547 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -43,8 +43,9 @@ #include "csr.h" #define CSR_TYPE_NULL 0 -#define CSR_TYPE_UINT8 1 -#define CSR_TYPE_UINT16 2 +#define CSR_TYPE_ARRAY 1 +#define CSR_TYPE_UINT8 2 +#define CSR_TYPE_UINT16 3 static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { @@ -73,19 +74,38 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) static int read_pskey(int dd, uint16_t pskey, int type) { - uint16_t value; - int err; + uint8_t array[64]; + uint16_t value = 0; + int i, err, size = sizeof(array); - if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { + memset(array, 0, sizeof(array)); + + if (type != CSR_TYPE_ARRAY && + type != CSR_TYPE_UINT8 && + type != CSR_TYPE_UINT16) { errno = EFAULT; return -1; } - err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); - if (err < 0) - return err; + if (type != CSR_TYPE_ARRAY) { + err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); + if (err < 0) + return err; + + printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); + } else { + if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) + size = 8; - printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); + err = csr_read_pskey_complex(dd, 0x4711, pskey, array, size); + if (err < 0) + return err; + + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < size; i++) + printf(" 0x%02x", array[i]); + printf("\n"); + } return err; } @@ -95,31 +115,38 @@ static struct { int type; char *str; } storage[] = { - { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, - { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, - { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, - { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, - { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, - { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, - { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, - { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, - { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, - { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, - { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, + { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, + { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, + { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, { 0x0000, CSR_TYPE_NULL, NULL }, }; static void usage(void) { - int i; + int i, pos = 0; printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" "\tpskey [-i ] [value]\n\n"); printf("Keys:\n\t"); - for (i = 0; storage[i].pskey; i++) - printf("%s ", storage[i].str); + for (i = 0; storage[i].pskey; i++) { + printf("%s ", storage[i].str); + pos += strlen(storage[i].str) + 1; + if (pos > 60) { + printf("\n\t"); + pos = 0; + } + } printf("\n"); } -- cgit From adb76ec0bc45fe4d8b481db3418a86d686591d84 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 10 Jun 2005 06:59:27 +0000 Subject: Add build ids for new sniffer firmwares --- tools/csr.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 6b34fc3f..fd547ad3 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -322,6 +322,18 @@ static struct { { 1759, "Sniff 40 (2004-11-03)" }, { 1760, "Sniff 40 (2004-11-03)" }, { 1761, "Sniff 40 (2004-11-03)" }, + { 2009, "Sniff 41 (2005-04-06)" }, + { 2010, "Sniff 41 (2005-04-06)" }, + { 2011, "Sniff 41 (2005-04-06)" }, + { 2016, "Sniff 42 (2005-04-11)" }, + { 2017, "Sniff 42 (2005-04-11)" }, + { 2018, "Sniff 42 (2005-04-11)" }, + { 2023, "Sniff 43 (2005-04-14)" }, + { 2024, "Sniff 43 (2005-04-14)" }, + { 2025, "Sniff 43 (2005-04-14)" }, + { 2032, "Sniff 44 (2005-04-18)" }, + { 2033, "Sniff 44 (2005-04-18)" }, + { 2034, "Sniff 44 (2005-04-18)" }, { 0, } }; -- cgit From f31fbabd2aa6a30523afb53396d039f4b8a6de1b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 14:02:56 +0000 Subject: Add support for inquiry scan type --- tools/hciconfig.8 | 6 ++++++ tools/hciconfig.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index dabfeb36..9fb8b552 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -133,6 +133,12 @@ With no prints out the current inquiry mode. Otherwise, sets inquiry mode to .IR mode . .TP +.BI inqtype " [type]" +With no +.IR type , +prints out the current inquiry scan type. Otherwise, sets inquiry scan type to +.IR type . +.TP .BI inqparms " [win:int]" With no .IR win:int , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 5f72ce66..f6c932e4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -881,6 +881,40 @@ static void cmd_inq_mode(int ctl, int hdev, char *opt) } } +static void cmd_inq_type(int ctl, int hdev, char *opt) +{ + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (opt) { + uint8_t type = atoi(opt); + + if (hci_write_inquiry_scan_type(dd, type, 2000) < 0) { + fprintf(stderr, "Can't set inquiry scan type on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint8_t type; + + if (hci_read_inquiry_scan_type(dd, &type, 1000) < 0) { + fprintf(stderr, "Can't read inquiry scan type on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf("\tInquiry scan type: %s\n", + type == 1 ? "Interlaced Inquiry Scan" : "Standard Inquiry Scan"); + } +} + static void cmd_inq_parms(int ctl, int hdev, char *opt) { struct hci_request rq; @@ -1325,6 +1359,7 @@ static struct { { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { "inqmode", cmd_inq_mode, "[mode]", "Get/set inquiry mode" }, + { "inqtype", cmd_inq_type, "[type]", "Get/set inquiry scan type" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, -- cgit From 8937ece83f3e3317a84214028ec81b1fc042a040 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 18:01:04 +0000 Subject: Fix direction bit for clear status and abort commands --- tools/dfu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/dfu.c b/tools/dfu.c index 08e256b9..b46027a0 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -146,7 +146,7 @@ int dfu_clear_status(struct usb_dev_handle *udev, int intf) if (!udev) return -EIO; - return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, DFU_CLRSTATUS, 0, intf, NULL, 0, DFU_TIMEOUT); } @@ -164,6 +164,6 @@ int dfu_abort(struct usb_dev_handle *udev, int intf) if (!udev) return -EIO; - return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, DFU_ABORT, 0, intf, NULL, 0, DFU_TIMEOUT); } -- cgit From 3257d9b3a8f59561960c75f310fea33d23858024 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 21:25:49 +0000 Subject: Fix program error codes on memory allocations --- tools/hcitool.c | 72 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 24 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 6e225cee..210ab2ba 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1030,8 +1030,10 @@ static void cmd_dc(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1165,8 +1167,10 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1236,8 +1240,10 @@ static void cmd_lq(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1309,8 +1315,10 @@ static void cmd_tpl(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1382,8 +1390,10 @@ static void cmd_afh(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1465,8 +1475,10 @@ static void cmd_cpt(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1546,8 +1558,10 @@ static void cmd_lst(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1631,8 +1645,10 @@ static void cmd_auth(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1700,8 +1716,10 @@ static void cmd_enc(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1770,8 +1788,10 @@ static void cmd_key(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1839,8 +1859,10 @@ static void cmd_clkoff(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1912,8 +1934,10 @@ static void cmd_clock(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; -- cgit From 1d2e71b109d907473939864caa5afec86000d58a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Jun 2005 12:10:54 +0000 Subject: Replace non-printable characters in device names --- tools/hcitool.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 210ab2ba..e6561feb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -411,7 +412,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, opt, dd, cc, nc; + int i, n, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -510,6 +511,10 @@ static void cmd_scan(int dev_id, int argc, char **argv) sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); + for (n = 0; n < 248 && name[n]; n++) + if (!isprint(name[n])) + name[n] = '.'; + printf("\t%s\t%s\n", addr, name); continue; } @@ -563,8 +568,12 @@ static void cmd_scan(int dev_id, int argc, char **argv) sizeof(name), name, 100000) < 0) { if (!nc) strcpy(name, "n/a"); - } else + } else { + for (n = 0; n < 248 && name[n]; n++) + if (!isprint(name[n])) + name[n] = '.'; nc = 0; + } } printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); -- cgit From 4cf1f07d58e85915f12099d9eb5560e7acbf4deb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 21 Jun 2005 16:49:26 +0000 Subject: Don't use hci_uart.h anymore --- tools/hciattach.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 33ecdf03..b7f6dab6 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -49,7 +49,18 @@ #include #include #include -#include + +#ifndef N_HCI +#define N_HCI 15 +#endif + +#define HCIUARTSETPROTO _IOW('U', 200, int) +#define HCIUARTGETPROTO _IOR('U', 201, int) + +#define HCI_UART_H4 0 +#define HCI_UART_BCSP 1 +#define HCI_UART_3WIRE 2 +#define HCI_UART_H4DS 3 struct uart_t { char *type; -- cgit From ef24c2a9db8b95032e4d87b730dcffdf1b9901a4 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 24 Jun 2005 13:56:56 +0000 Subject: fix help message --- tools/sdptool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index d015f12f..97282e8d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2812,8 +2812,8 @@ static void usage(void) printf("Usage:\n" "\tsdptool [options] [command parameters]\n"); printf("Options:\n" - "\t--help\t\tDisplay help\n" - "\t--source\tSpecify source interface\n"); + "\t-h\t\tDisplay help\n" + "\t-i\t\tSpecify source interface\n"); printf("Commands:\n"); for (i = 0; command[i].cmd; i++) -- cgit From a32c06bc2990f56420782e8966aa5de08b61d505 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:08:26 +0000 Subject: Update reading of local Bluetooth clock --- tools/hcitool.1 | 2 +- tools/hcitool.c | 51 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index d863e7d1..01ef03a8 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -175,7 +175,7 @@ Change the connection link key for the device with Bluetooth address Read the clock offset for the device with Bluetooth address .IR bdaddr . .TP -.BI clock " [which clock]" +.BI clock " [bdaddr] [which clock]" Read the clock for the device with Bluetooth address .IR bdaddr . The clock can be diff --git a/tools/hcitool.c b/tools/hcitool.c index e6561feb..7f0cc23a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1900,14 +1900,14 @@ static struct option clock_options[] = { static char *clock_help = "Usage:\n" - "\tclock [which clock]\n"; + "\tclock [bdaddr] [which clock]\n"; static void cmd_clock(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; uint8_t which; - uint32_t clock; + uint32_t handle, clock; uint16_t accuracy; int opt, dd; @@ -1921,12 +1921,13 @@ static void cmd_clock(int dev_id, int argc, char **argv) argc -= optind; argv += optind; - if (argc < 1) { - printf(clock_help); - return; - } + if (argc > 0) + str2ba(argv[0], &bdaddr); + else + bacpy(&bdaddr, BDADDR_ANY); - str2ba(argv[0], &bdaddr); + if (!bacmp(&bdaddr, BDADDR_ANY)) + dev_id = hci_get_route(NULL); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -1942,22 +1943,31 @@ static void cmd_clock(int dev_id, int argc, char **argv) exit(1); } - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) { - perror("Can't allocate memory"); - exit(1); - } + if (bacmp(&bdaddr, BDADDR_ANY)) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - perror("Get connection info failed"); - exit(1); - } + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + free(cr); + exit(1); + } + + handle = htobs(cr->conn_info->handle); + which = (argc > 1) ? atoi(argv[1]) : 0x01; - which = (argc > 1) ? atoi(argv[1]) : 0x01; + free(cr); + } else { + handle = 0x00; + which = 0x00; + } - if (hci_read_clock(dd, htobs(cr->conn_info->handle), which, &clock, &accuracy, 1000) < 0) { + if (hci_read_clock(dd, handle, which, &clock, &accuracy, 1000) < 0) { perror("Reading clock failed"); exit(1); } @@ -1968,7 +1978,6 @@ static void cmd_clock(int dev_id, int argc, char **argv) printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); close(dd); - free(cr); } static struct { -- cgit From 2dd0e662aaec1ec73b7783a625c1645020dc29d7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:09:51 +0000 Subject: Add support for reading uint32 values --- tools/csr.c | 40 ++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 41 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index fd547ad3..4648d9fa 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -504,6 +504,46 @@ int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *val return 0; } +int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value) +{ + unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + *value = ((rp[11] + (rp[12] << 8)) << 16) + (rp[13] + (rp[14] << 8)); + + return 0; +} + int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, diff --git a/tools/csr.h b/tools/csr.h index 61df145e..5098a69d 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -77,6 +77,7 @@ char *csr_pskeytostr(uint16_t pskey); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); +int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); -- cgit From ab788511066ea30c788d907fd44c8427f97b6e54 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:10:34 +0000 Subject: Add support for getting the local Bluetooth clock --- tools/bccmd.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index 4b4a1fb4..5e358b01 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -79,6 +79,22 @@ static int cmd_keylen(int dd, int argc, char *argv[]) return 0; } +static int cmd_clock(int dd, int argc, char *argv[]) +{ + uint32_t clock = 0; + int err; + + err = csr_read_varid_uint32(dd, 0x4711, CSR_VARID_BT_CLOCK, &clock); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock); + + return 0; +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); @@ -86,6 +102,7 @@ static struct { char *doc; } commands[] = { { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { NULL }, }; @@ -99,7 +116,7 @@ static void usage(void) printf("Commands:\n"); for (i = 0; commands[i].str; i++) - printf("\t%s\t%s\t%s\n", commands[i].str, + printf("\t%s\t%-8s\t%s\n", commands[i].str, commands[i].arg, commands[i].doc); } -- cgit From bee17a8b3e9f220f4064069e3cc9a485663ce057 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:42:56 +0000 Subject: Add Audio/Video control utility --- tools/Makefile.am | 18 ++++- tools/avctrl.8 | 38 +++++++++ tools/avctrl.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 tools/avctrl.8 create mode 100644 tools/avctrl.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 66839dd7..adff35b9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,6 +2,14 @@ # $Id$ # +if AVCTRL +avctrl_programs = avctrl +avctrl_manfiles = avctrl.8 +else +avctrl_programs = +avctrl_manfiles = +endif + if HID2HCI hid2hci_programs = hid2hci hid2hci_manfiles = hid2hci.8 @@ -18,7 +26,7 @@ dfutool_programs = dfutool_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) +sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) @@ -44,6 +52,10 @@ pskey_LDADD = @BLUEZ_LIBS@ bccmd_SOURCES = bccmd.c csr.h csr.c bccmd_LDADD = @BLUEZ_LIBS@ +if AVCTRL +avctrl_LDADD = @USB_LIBS@ +endif + if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif @@ -58,8 +70,8 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - $(hid2hci_manfiles) $(dfutool_manfiles) + $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) hid2hci.8 dfutool.1 +EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 dfutool.1 MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/avctrl.8 b/tools/avctrl.8 new file mode 100644 index 00000000..f791cf9e --- /dev/null +++ b/tools/avctrl.8 @@ -0,0 +1,38 @@ +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH AVCTRL 8 "JUNE 6, 2005" "" "" + +.SH NAME +avctrl \- Bluetooth Audio/Video control utility +.SH SYNOPSIS +.BR "avctrl +[ +.I options +] +.SH DESCRIPTION +.B avctrl +is used to control the Audio/Video dongles. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible options. +.TP +.BI -q +Don't display any messages. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/avctrl.c b/tools/avctrl.c new file mode 100644 index 00000000..120a382f --- /dev/null +++ b/tools/avctrl.c @@ -0,0 +1,233 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif + +#ifndef USB_DIR_IN +#define USB_DIR_IN 0x80 +#endif + +#define HID_REQ_GET_REPORT 0x01 +#define HID_REQ_GET_IDLE 0x02 +#define HID_REQ_GET_PROTOCOL 0x03 +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_SET_IDLE 0x0a +#define HID_REQ_SET_PROTOCOL 0x0b + +struct device_info; + +struct device_id { + uint16_t vendor; + uint16_t product; + int (*func)(struct device_info *dev); +}; + +struct device_info { + struct usb_device *dev; + struct device_id *id; +}; + +#define GET_STATE 0x01 +#define GET_REMOTE_BDADDR 0x02 +#define DISCOVER 0x03 +#define SWITCH_TO_DFU 0x04 +#define READ_CODEC 0x05 + +static int dongle_csr(struct device_info *devinfo) +{ + unsigned char buf[8]; + struct usb_dev_handle *udev; + int err, intf = 2; + + udev = usb_open(devinfo->dev); + if (!udev) + return -errno; + + if (usb_claim_interface(udev, intf) < 0) { + err = -errno; + usb_close(udev); + return err; + } + + memset(buf, 0, sizeof(buf)); + buf[0] = SWITCH_TO_DFU; + + err = usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + HID_REQ_SET_REPORT, 0x03 << 8, intf, buf, sizeof(buf), 10000); + + if (err == 0) { + err = -1; + errno = EALREADY; + } else { + if (errno == ETIMEDOUT) + err = 0; + } + + usb_release_interface(udev, intf); + usb_close(udev); + + return err; +} + +static struct device_id device_list[] = { + { 0x0a12, 0x1004, dongle_csr }, + { -1 } +}; + +static struct device_id *match_device(uint16_t vendor, uint16_t product) +{ + int i; + + for (i = 0; device_list[i].func; i++) { + if (vendor == device_list[i].vendor && + product == device_list[i].product) + return &device_list[i]; + } + + return NULL; +} + +static int find_devices(struct device_info *devinfo, size_t size) +{ + struct usb_bus *bus; + struct usb_device *dev; + struct device_id *id; + int count = 0; + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) { + id = match_device(dev->descriptor.idVendor, + dev->descriptor.idProduct); + if (!id) + continue; + + if (count < size) { + devinfo[count].dev = dev; + devinfo[count].id = id; + count++; + } + } + + return count; +} + +static void usage(void) +{ + printf("avctrl - Bluetooth Audio/Video control utility\n\n"); + + printf("Usage:\n" + "\tavctrl [options]\n" + "\n"); + + printf("Options:\n" + "\t-h, --help Display help\n" + "\t-q, --quiet Don't display any messages\n" + "\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "quiet", 0, 0, 'q' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct device_info dev[16]; + int i, opt, num, quiet = 0; + + while ((opt = getopt_long(argc, argv, "+qh", main_options, NULL)) != -1) { + switch (opt) { + case 'q': + quiet = 1; + break; + case 'h': + usage(); + exit(0); + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + usb_init(); + + num = find_devices(dev, sizeof(dev) / sizeof(dev[0])); + if (num <= 0) { + if (!quiet) + fprintf(stderr, "No Audio/Video devices found\n"); + exit(1); + } + + for (i = 0; i < num; i++) { + struct device_id *id = dev[i].id; + + if (!quiet) + printf("Switching device %04x:%04x ", + id->vendor, id->product); + fflush(stdout); + + if (id->func(&dev[i]) < 0) { + if (!quiet) + printf("failed (%s)\n", strerror(errno)); + } else { + if (!quiet) + printf("was successful\n"); + } + } + + return 0; +} -- cgit From cbbe4f3f909cde4356f1323e0bd157e2fe9320de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 13:01:52 +0000 Subject: Don't show empty names --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 7f0cc23a..ceddeda5 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -575,7 +575,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) nc = 0; } } - printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); + + if (strlen(name) > 0) + printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); if (extcls) { memcpy(cls, (info+i)->dev_class, 3); -- cgit From 4f32352b05190a3f70828c38f4a4f25655bb696e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 13:13:17 +0000 Subject: Move CSR panic and fault code reading to the bccmd tool --- tools/bccmd.c | 42 +++++++++++++++++++++++++++++++++++++++--- tools/hciconfig.c | 12 +----------- 2 files changed, 40 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index 5e358b01..df39a3df 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -95,14 +95,50 @@ static int cmd_clock(int dd, int argc, char *argv[]) return 0; } +static int cmd_panicarg(int dd, int argc, char *argv[]) +{ + uint16_t error = 0; + int err; + + err = csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Panic code: 0x%02x (%s)\n", error, + error < 0x100 ? "valid" : "invalid"); + + return 0; +} + +static int cmd_faultarg(int dd, int argc, char *argv[]) +{ + uint16_t error = 0; + int err; + + err = csr_read_varid_uint16(dd, 5, CSR_VARID_FAULT_ARG, &error); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Fault code: 0x%02x (%s)\n", error, + error < 0x100 ? "valid" : "invalid"); + + return 0; +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); char *arg; char *doc; } commands[] = { - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, { NULL }, }; @@ -116,7 +152,7 @@ static void usage(void) printf("Commands:\n"); for (i = 0; commands[i].str; i++) - printf("\t%s\t%-8s\t%s\n", commands[i].str, + printf("\t%-10s%-8s\t%s\n", commands[i].str, commands[i].arg, commands[i].doc); } diff --git a/tools/hciconfig.c b/tools/hciconfig.c index f6c932e4..4dfb57a7 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1173,7 +1173,7 @@ static void print_rev_ericsson(int dd) static void print_rev_csr(int dd, uint16_t rev) { - uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, error; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco; if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { printf("\t%s\n", csr_buildidtostr(rev)); @@ -1193,16 +1193,6 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); - - if (!csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error)) { - if (error < 0x0100) - printf("\tPanic code: 0x%02x\n", error); - } - - if (!csr_read_varid_uint16(dd, 6, CSR_VARID_FAULT_ARG, &error)) { - if (error < 0x0100) - printf("\tFault code: 0x%02x\n", error); - } } static void print_rev_digianswer(int dd) -- cgit From 1f422e5f2b343d35a8c77ce4be16f74b2819b2bf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 21:15:41 +0000 Subject: Fix some GCC 4.0 warnings --- tools/avctrl.c | 2 +- tools/ciptool.c | 3 ++- tools/dfu.c | 8 ++++---- tools/dfu.h | 4 ++-- tools/dfutool.c | 4 ++-- tools/hcitool.c | 8 +++++--- tools/hid2hci.c | 2 +- tools/sdptool.c | 4 ++-- 8 files changed, 19 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/avctrl.c b/tools/avctrl.c index 120a382f..14d42e4a 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -82,7 +82,7 @@ struct device_info { static int dongle_csr(struct device_info *devinfo) { - unsigned char buf[8]; + char buf[8]; struct usb_dev_handle *udev; int err, intf = 2; diff --git a/tools/ciptool.c b/tools/ciptool.c index 7c952cf4..38446f93 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -134,7 +134,8 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne struct hci_dev_info di; struct sockaddr_l2 addr; struct l2cap_options opts; - int sk, size; + socklen_t size; + int sk; hci_devinfo(dev_id, &di); if (!(di.link_policy & HCI_LP_RSWITCH)) { diff --git a/tools/dfu.c b/tools/dfu.c index b46027a0..bfbc0f2d 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -114,7 +114,7 @@ int dfu_detach(struct usb_dev_handle *udev, int intf) DFU_DETACH, 0x1388, intf, NULL, 0, DFU_TIMEOUT); } -int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size) +int dfu_upload(struct usb_dev_handle *udev, int intf, int block, char *buffer, int size) { if (!udev) return -EIO; @@ -123,7 +123,7 @@ int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char * DFU_UPLOAD, block, intf, buffer, size, DFU_TIMEOUT); } -int dfu_download(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size) +int dfu_download(struct usb_dev_handle *udev, int intf, int block, char *buffer, int size) { if (!udev) return -EIO; @@ -138,7 +138,7 @@ int dfu_get_status(struct usb_dev_handle *udev, int intf, struct dfu_status *sta return -EIO; return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, - DFU_GETSTATUS, 0, intf, (unsigned char *) status, DFU_STATUS_SIZE, DFU_TIMEOUT); + DFU_GETSTATUS, 0, intf, (char *) status, DFU_STATUS_SIZE, DFU_TIMEOUT); } int dfu_clear_status(struct usb_dev_handle *udev, int intf) @@ -156,7 +156,7 @@ int dfu_get_state(struct usb_dev_handle *udev, int intf, uint8_t *state) return -EIO; return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, - DFU_GETSTATE, 0, intf, (unsigned char *) state, 1, DFU_TIMEOUT); + DFU_GETSTATE, 0, intf, (char *) state, 1, DFU_TIMEOUT); } int dfu_abort(struct usb_dev_handle *udev, int intf) diff --git a/tools/dfu.h b/tools/dfu.h index 1a253505..915efd8c 100644 --- a/tools/dfu.h +++ b/tools/dfu.h @@ -100,8 +100,8 @@ struct dfu_suffix { /* DFU interface */ int dfu_detach(struct usb_dev_handle *udev, int intf); -int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size); -int dfu_download(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size); +int dfu_upload(struct usb_dev_handle *udev, int intf, int block, char *buffer, int size); +int dfu_download(struct usb_dev_handle *udev, int intf, int block, char *buffer, int size); int dfu_get_status(struct usb_dev_handle *udev, int intf, struct dfu_status *status); int dfu_clear_status(struct usb_dev_handle *udev, int intf); int dfu_get_state(struct usb_dev_handle *udev, int intf, uint8_t *state); diff --git a/tools/dfutool.c b/tools/dfutool.c index 47510cef..06da5248 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -400,7 +400,7 @@ static void cmd_upgrade(char *device, int argc, char **argv) struct dfu_status status; struct dfu_suffix suffix; struct stat st; - unsigned char *buf; + char *buf; unsigned long filesize, count, timeout = 0; char *filename; uint32_t crc; @@ -568,7 +568,7 @@ static void cmd_archive(char *device, int argc, char **argv) struct usb_dev_handle *udev; struct dfu_status status; struct dfu_suffix suffix; - unsigned char buf[2048]; + char buf[2048]; unsigned long timeout = 0; char *filename; uint32_t crc; diff --git a/tools/hcitool.c b/tools/hcitool.c index ceddeda5..156b0790 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -819,7 +819,7 @@ static char *cmd_help = static void cmd_cmd(int dev_id, int argc, char **argv) { - char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; + unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; int i, opt, len, dd; @@ -940,9 +940,10 @@ static char *cc_help = static void cmd_cc(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; - int opt, ptype, dd; uint16_t handle; uint8_t role; + unsigned int ptype; + int dd, opt; role = 0x01; ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; @@ -1451,7 +1452,8 @@ static void cmd_cpt(int dev_id, int argc, char **argv) set_conn_ptype_cp cp; evt_conn_ptype_changed rp; bdaddr_t bdaddr; - int opt, dd, ptype; + unsigned int ptype; + int dd, opt; for_each_opt(opt, cpt_options, NULL) { switch (opt) { diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 115e0ef5..9a85c1fd 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -130,7 +130,7 @@ static int switch_hidproxy(struct device_info *devinfo) return err; } -static int send_report(int fd, const unsigned char *buf, size_t size) +static int send_report(int fd, const char *buf, size_t size) { struct hiddev_report_info rinfo; struct hiddev_usage_ref uref; diff --git a/tools/sdptool.c b/tools/sdptool.c index 97282e8d..3a2ce834 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -874,7 +874,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri if (!strncasecmp(argv[i], "u0x", 3)) { /* UUID16 */ uint16_t value_int = strtoul((argv[i]) + 3, NULL, 16); - uuid_t *value_uuid = (uuid_t *)malloc(sizeof(uuid_t)); + uuid_t *value_uuid = (uuid_t *) malloc(sizeof(uuid_t)); allocArray[i] = value_uuid; sdp_uuid16_create(value_uuid, value_int); @@ -883,7 +883,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri valueArray[i] = &value_uuid->value.uuid16; } else if (!strncasecmp(argv[i], "0x", 2)) { /* Int */ - uint32_t *value_int = (int *)malloc(sizeof(int)); + uint32_t *value_int = (uint32_t *) malloc(sizeof(int)); allocArray[i] = value_int; *value_int = strtoul((argv[i]) + 2, NULL, 16); -- cgit From e063c0ede09c386be3a5fb579f3cdf75f5826493 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 21:23:02 +0000 Subject: Add build id for BlueCore3-Audio with Unified 18e firmware --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 4648d9fa..6fb93f06 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -276,6 +276,8 @@ static struct { { 2063, "Unified 20a1" }, { 2067, "Unified 18f" }, { 2068, "Unified 18f" }, + { 2243, "Unified 18e" }, + { 2244, "Unified 18e" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 0bf15aa0833fccedbb038830bee423f29e6b1d5e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Jul 2005 17:19:40 +0000 Subject: Update some wording in the manual page --- tools/sdptool.1 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 5ed9e33e..781a91e5 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -64,8 +64,14 @@ performing SDP queries on Bluetooth devices, and administering a local \fBsdpd\fR. .SH "COMMANDS" .PP -The following commands are available. -.IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] service\fP" 10 +The following commands are available. In all cases \fBbdaddr\fR +specifies the device to search or browse. If \fIlocal\fP is used +for \fBbdaddr\fP, then the local \fBsdpd\fR is searched. +.PP +Services are identified and manipulated with a 4-byte \fBrecord_handle\fP +(NOT the service name). To find a service's \fBrecord_handle\fP, look for the +"Service RecHandle" line in the \fBsearch\fP or \fBbrowse\fP results +.IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] service_name\fP" 10 Search for services.. .IP "" 10 Known service names are DID, SP, DUN, LAN, FAX, OPUSH, -- cgit From 489f776973a6b46016edc0cd978918018a93b9a1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 14 Jul 2005 09:20:35 +0000 Subject: Add build id for BlueCore3-MM with Unified 20d firmware --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 6fb93f06..6832ec6d 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -278,6 +278,8 @@ static struct { { 2068, "Unified 18f" }, { 2243, "Unified 18e" }, { 2244, "Unified 18e" }, + { 2258, "Unified 20d" }, + { 2259, "Unified 20d" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From ef05ec89bbe7f2460d64e1206799c63913c71df5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 02:59:49 +0000 Subject: Use the new device specific functions --- tools/sdptool.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 3a2ce834..b3f4648c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -782,7 +782,7 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha } /* Update on the server */ - if (sdp_record_update(sess, rec)) { + if (sdp_device_record_update(sess, &interface, rec)) { printf("Service Record update failed (%d).\n", errno); return -1; } @@ -904,7 +904,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri sdp_attr_replace(rec, attrib, pSequenceHolder); /* Update on the server */ - if (sdp_record_update(session, rec)) { + if (sdp_device_record_update(session, &interface, rec)) { printf("Service Record update failed (%d).\n", errno); return -1; } @@ -1170,7 +1170,7 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Serial Port", 0, "COM Port"); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1228,7 +1228,7 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1284,7 +1284,7 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "LAN Access over PPP", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1343,7 +1343,7 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Headset", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1405,7 +1405,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Handsfree", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1467,7 +1467,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "SIM Access", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1525,7 +1525,7 @@ static int add_fax(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Fax", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1598,7 +1598,7 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "OBEX Object Push", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1659,7 +1659,7 @@ static int add_ftp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1732,7 +1732,7 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Network Access Point Service", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1791,7 +1791,7 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Group Network Service", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1853,7 +1853,7 @@ static int add_panu(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "PAN User", NULL, NULL); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1910,7 +1910,7 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1968,7 +1968,7 @@ static int add_a2source(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Audio Source", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto done; @@ -2027,7 +2027,7 @@ static int add_a2sink(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Audio Sink", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto done; @@ -2078,7 +2078,7 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "SyncML Client", NULL, NULL); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); return -1; } @@ -2112,7 +2112,7 @@ static int add_nokiaid(sdp_session_t *session, svc_info_t *si) sdp_attr_add(&record, SDP_ATTR_SERVICE_VERSION, version); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); sdp_data_free(version); return -1; @@ -2155,7 +2155,7 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Nokia PC Suite", NULL, NULL); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); return -1; } @@ -2187,7 +2187,7 @@ static int add_sr1(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); return -1; } @@ -2327,7 +2327,7 @@ static int del_service(bdaddr_t *bdaddr, void *arg) return -1; } - if (sdp_record_unregister(sess, rec)) { + if (sdp_device_record_unregister(sess, &interface, rec)) { printf("Failed to unregister service record: %s\n", strerror(errno)); sdp_close(sess); return -1; -- cgit From 8ac83f1424fe8c726aeeccda705c6840d5b31ab9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 03:24:28 +0000 Subject: Correctly terminate the device name string --- tools/hciconfig.c | 3 ++- tools/hcitool.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 4dfb57a7..ca44831f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -437,7 +437,7 @@ static void cmd_name(int ctl, int hdev, char *opt) exit(1); } } else { - char name[248]; + char name[249]; int i; if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n", @@ -447,6 +447,7 @@ static void cmd_name(int ctl, int hdev, char *opt) for (i = 0; i < 248 && name[i]; i++) if (!isprint(name[i])) name[i] = '.'; + name[248] = '\0'; print_dev_hdr(&di); printf("\tName: '%s'\n", name); } diff --git a/tools/hcitool.c b/tools/hcitool.c index 156b0790..ba8ba823 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -514,6 +514,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (n = 0; n < 248 && name[n]; n++) if (!isprint(name[n])) name[n] = '.'; + name[248] = '\0'; printf("\t%s\t%s\n", addr, name); continue; @@ -572,6 +573,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (n = 0; n < 248 && name[n]; n++) if (!isprint(name[n])) name[n] = '.'; + name[248] = '\0'; nc = 0; } } -- cgit From ad3049f07e580ee1ffb235afea1e368c4c46a639 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 07:34:55 +0000 Subject: Use bt_free() to free the memory allocated by lmp_featurestostr() --- tools/hciconfig.c | 12 +++++++++--- tools/hcitool.c | 14 +++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ca44831f..745ed74f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -109,8 +109,11 @@ static void print_dev_features(struct hci_dev_info *di, int format) di->features[3], di->features[4], di->features[5], di->features[6], di->features[7]); - if (format) - printf("%s\n", lmp_featurestostr(di->features, "\t\t", 63)); + if (format) { + char *tmp = lmp_featurestostr(di->features, "\t\t", 63); + printf("%s\n", tmp); + bt_free(tmp); + } } static void cmd_rstat(int ctl, int hdev, char *opt) @@ -379,6 +382,7 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) static void cmd_features(int ctl, int hdev, char *opt) { uint8_t max_page, features[8]; + char *tmp; int i, dd; if (!(di.features[7] & LMP_EXT_FEAT)) { @@ -401,12 +405,14 @@ static void cmd_features(int ctl, int hdev, char *opt) } print_dev_hdr(&di); + tmp = lmp_featurestostr(di.features, "\t\t", 63); printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", (max_page > 0) ? " page 0" : "", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); - printf("%s\n", lmp_featurestostr(di.features, "\t\t", 63)); + printf("%s\n", tmp); + bt_free(tmp); for (i = 1; i <= max_page; i++) { if (hci_read_local_ext_features(dd, 1, &max_page, features, 1000) < 0) diff --git a/tools/hcitool.c b/tools/hcitool.c index ba8ba823..bc09ea07 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -379,7 +379,8 @@ static void cmd_inq(int dev_id, int argc, char **argv) (info+i)->dev_class[1], (info+i)->dev_class[0]); } - free(info); + + bt_free(info); } /* Device scanning */ @@ -603,13 +604,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + char *tmp = lmp_featurestostr(features, "\t\t", 63); printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); - printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + printf("%s\n", tmp); + bt_free(tmp); } if (cc) { @@ -622,7 +625,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } close(dd); - free(info); + bt_free(info); } /* Remote name */ @@ -786,10 +789,11 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + char *tmp = lmp_featurestostr(features, "\t\t", 63); printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], - features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 63)); + features[4], features[5], features[6], features[7], tmp); + bt_free(tmp); } if (features[7] & LMP_EXT_FEAT) { -- cgit From 7ba9b7fda144865222a5d254b36bf484d5af99e7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 06:42:20 +0000 Subject: Use bt_free() instead of free() for inquiry results --- tools/ciptool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index 38446f93..263e0573 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -256,7 +256,7 @@ static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv) if (!get_psm(&src, &dst, &psm)) continue; - free(info); + bt_free(info); printf("\tConnecting to device %s\n", addr); do_connect(ctl, dev_id, &src, &dst, psm, 0); @@ -264,7 +264,7 @@ static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv) } } - free(info); + bt_free(info); fprintf(stderr, "\tNo devices in range or visible\n"); exit(1); } -- cgit From 08ecd7d64afc3493046db2e09e5e8f875571ee84 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Aug 2005 11:24:49 +0000 Subject: Add UUIDs for phonebook access profile --- tools/sdptool.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index b3f4648c..f6a47ddf 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -302,6 +302,8 @@ static struct uuid_def uuid16_names[] = { { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, { 0x112d, "SIM Access (SAP)", NULL, 0 }, + { 0x112e, "Phonebook Access (PBAP) - PCE", NULL, 0 }, + { 0x112f, "Phonebook Access (PBAP) - PSE", NULL, 0 }, /* ... */ { 0x1200, "PnPInformation", did_attrib_names, sizeof(did_attrib_names)/sizeof(struct attrib_def) }, -- cgit From 326acb25fa999f4cf908a69412e9dc6f429f9d49 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Aug 2005 11:28:27 +0000 Subject: Add missing UUID translations --- tools/sdptool.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index f6a47ddf..96a95cc8 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -301,6 +301,9 @@ static struct uuid_def uuid16_names[] = { { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, + { 0x112a, "UDI-MT", NULL, 0 }, + { 0x112b, "UDI-TA", NULL, 0 }, + { 0x112c, "Audio/Video", NULL, 0 }, { 0x112d, "SIM Access (SAP)", NULL, 0 }, { 0x112e, "Phonebook Access (PBAP) - PCE", NULL, 0 }, { 0x112f, "Phonebook Access (PBAP) - PSE", NULL, 0 }, @@ -312,6 +315,10 @@ static struct uuid_def uuid16_names[] = { { 0x1203, "GenericAudio", audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, { 0x1204, "GenericTelephony", NULL, 0 }, + /* ... */ + { 0x1303, "VideoSource", NULL, 0 }, + { 0x1304, "VideoSink", NULL, 0 }, + { 0x1305, "VideoDistribution", NULL, 0 }, }; static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); -- cgit From 6b4fc0af31df1b4736c2209893b2b7d8890b0ed7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Aug 2005 11:42:07 +0000 Subject: Add support for HotSync service records --- tools/sdptool.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 96a95cc8..41e2fc09 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2097,6 +2097,36 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) return 0; } +static unsigned char hotsync_uuid[] = { 0xF5, 0xBE, 0xB6, 0x51, 0x41, 0x71, 0x40, 0x51, + 0xAC, 0xF5, 0x6C, 0xA7, 0x20, 0x22, 0x42, 0xF0 }; + +static int add_hotsync(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass; + uuid_t root_uuid, svclass_uuid; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) hotsync_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("HotSync service record registered\n"); + + return 0; +} + static unsigned char nokid_uuid[] = { 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; @@ -2237,6 +2267,7 @@ struct { { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, { "SYNCML", 0, add_syncml, syncml_uuid }, + { "HOTSYNC", 0, add_hotsync, hotsync_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "SR1", 0, add_sr1, sr1_uuid }, -- cgit From 9781497af59916008927db6089cd38f782e16261 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Aug 2005 14:40:45 +0000 Subject: Add support for HotSync and ActiveSync profiles --- tools/sdptool.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 41e2fc09..fd824c2c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2097,10 +2097,94 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) return 0; } -static unsigned char hotsync_uuid[] = { 0xF5, 0xBE, 0xB6, 0x51, 0x41, 0x71, 0x40, 0x51, - 0xAC, 0xF5, 0x6C, 0xA7, 0x20, 0x22, 0x42, 0xF0 }; +static unsigned char async_uuid[] = { 0x03, 0x50, 0x27, 0x8F, 0x3D, 0xCA, 0x4E, 0x62, + 0x83, 0x1D, 0xA4, 0x11, 0x65, 0xFF, 0x90, 0x6C }; + +static int add_activesync(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel? si->channel: 21; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid128_create(&svclass_uuid, (void *) async_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "Microsoft ActiveSync", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("ActiveSync service record registered\n"); + + return 0; +} + +static unsigned char hotsync_uuid[] = { 0xD8, 0x0C, 0xF9, 0xEA, 0x13, 0x4C, 0x11, 0xD5, + 0x83, 0xCE, 0x00, 0x30, 0x65, 0x7C, 0x54, 0x3C }; static int add_hotsync(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel? si->channel: 22; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid128_create(&svclass_uuid, (void *) hotsync_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "PalmOS HotSync", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("HotSync service record registered\n"); + + return 0; +} + +static unsigned char palmos_uuid[] = { 0xF5, 0xBE, 0xB6, 0x51, 0x41, 0x71, 0x40, 0x51, + 0xAC, 0xF5, 0x6C, 0xA7, 0x20, 0x22, 0x42, 0xF0 }; + +static int add_palmos(sdp_session_t *session, svc_info_t *si) { sdp_record_t record; sdp_list_t *root, *svclass; @@ -2122,7 +2206,7 @@ static int add_hotsync(sdp_session_t *session, svc_info_t *si) return -1; } - printf("HotSync service record registered\n"); + printf("PalmOS service record registered\n"); return 0; } @@ -2267,7 +2351,9 @@ struct { { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, { "SYNCML", 0, add_syncml, syncml_uuid }, + { "ACTIVESYNC", 0, add_activesync, async_uuid }, { "HOTSYNC", 0, add_hotsync, hotsync_uuid }, + { "PALMOS", 0, add_palmos, palmos_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "SR1", 0, add_sr1, sr1_uuid }, -- cgit From 50b0825682e67eb4a094261c5a0249c37bb84694 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Aug 2005 15:47:42 +0000 Subject: Identify the extended inquiry mode correctly --- tools/hciconfig.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 745ed74f..3bf3b292 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -883,8 +883,21 @@ static void cmd_inq_mode(int ctl, int hdev, char *opt) } print_dev_hdr(&di); - printf("\tInquiry mode: %s\n", - mode == 1 ? "Inquiry with RSSI" : "Standard Inquiry"); + printf("\tInquiry mode: "); + switch (mode) { + case 0: + printf("Standard Inquiry\n"); + break; + case 1: + printf("Inquiry with RSSI\n"); + break; + case 2: + printf("Inquiry with RSSI or Extended Inquiry\n"); + break; + default: + printf("Unknown (0x%02x)\n", mode); + break; + } } } -- cgit From b207244243cb0407728fbbb5ff8cbe95f9d74260 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 22 Aug 2005 20:36:28 +0000 Subject: Add support for writing valueless BCCMD variables --- tools/csr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 47 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 6832ec6d..1f1ab229 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -427,6 +427,52 @@ char *csr_pskeytostr(uint16_t pskey) } } +int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return hci_send_cmd(dd, OGF_VENDOR_CMD, 0x00, sizeof(cmd) + 1, cp); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} + int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 5) & 0xff, ((length / 2) + 5) >> 8, diff --git a/tools/csr.h b/tools/csr.h index 5098a69d..acb30641 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -75,6 +75,7 @@ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); +int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); -- cgit From 87af78afc0d5753583825f061c36f7705762c576 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 22 Aug 2005 20:38:18 +0000 Subject: Add support for reset and transmitter modification --- tools/bccmd.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index df39a3df..e476165e 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -95,6 +95,22 @@ static int cmd_clock(int dd, int argc, char *argv[]) return 0; } +static int cmd_rand(int dd, int argc, char *argv[]) +{ + uint16_t rand = 0; + int err; + + err = csr_read_varid_uint16(dd, 5, CSR_VARID_RAND, &rand); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Random number: 0x%02x (%d)\n", rand, rand); + + return 0; +} + static int cmd_panicarg(int dd, int argc, char *argv[]) { uint16_t error = 0; @@ -129,16 +145,41 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) return 0; } +static int cmd_coldreset(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, CSR_VARID_COLD_RESET); +} + +static int cmd_warmreset(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, CSR_VARID_WARM_RESET); +} + +static int cmd_disabletx(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, CSR_VARID_DISABLE_TX); +} + +static int cmd_enabletx(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, CSR_VARID_ENABLE_TX); +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); char *arg; char *doc; } commands[] = { - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "panicarg", cmd_panicarg, "", "Get panic code argument" }, - { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "coldreset", cmd_coldreset, "", "Perform cold reset" }, + { "warmreset", cmd_warmreset, "", "Perform warm reset" }, + { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, + { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, { NULL }, }; -- cgit From 082b69d2c075d1ec468a0a3bcd16b5f077a3fd3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 6 Sep 2005 20:57:54 +0000 Subject: Document the putkey and delkey commands --- tools/hciconfig.8 | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 9fb8b552..53c60526 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -193,6 +193,16 @@ bytes and SCO buffer size to .I pkt packets. .TP +.BI putkey " " +This command stores the link key for +.I bdaddr +on the device. +.TP +.BI delkey " " +This command deletes the stored link key for +.I bdaddr +from the device. +.TP .BI commands Display supported commands. .TP -- cgit From 9848c1fa4ee7b49d425cb790fe9ab5edff8761dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 16:15:39 +0000 Subject: Show supported commands also in clear text --- tools/hciconfig.c | 18 ++++++++++++++++-- tools/hcitool.c | 10 ++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3bf3b292..0d13542d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -795,6 +795,7 @@ static void cmd_delkey(int ctl, int hdev, char *opt) static void cmd_commands(int ctl, int hdev, char *opt) { uint8_t cmds[64]; + char *str; int i, n, dd; dd = hci_open_dev(hdev); @@ -823,12 +824,17 @@ static void cmd_commands(int ctl, int hdev, char *opt) printf(")\n"); } + str = hci_commandstostr(cmds, "\t", 71); + printf("%s\n", str); + bt_free(str); + hci_close_dev(dd); } static void cmd_version(int ctl, int hdev, char *opt) { struct hci_version ver; + char *hciver, *lmpver; int dd; dd = hci_open_dev(hdev); @@ -844,13 +850,21 @@ static void cmd_version(int ctl, int hdev, char *opt) exit(1); } + hciver = hci_vertostr(ver.hci_ver); + lmpver = lmp_vertostr(ver.hci_ver); + print_dev_hdr(&di); printf("\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n" "\tManufacturer: %s (%d)\n", - hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, - lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, + hciver ? hciver : "n/a", ver.hci_ver, ver.hci_rev, + lmpver ? lmpver : "n/a", ver.lmp_ver, ver.lmp_subver, bt_compidtostr(ver.manufacturer), ver.manufacturer); + if (hciver) + bt_free(hciver); + if (lmpver) + bt_free(lmpver); + hci_close_dev(dd); } diff --git a/tools/hcitool.c b/tools/hcitool.c index bc09ea07..2865ec42 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -595,12 +595,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (extinf && handle > 0) { if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); printf("Manufacturer:\t%s (%d)\n", bt_compidtostr(version.manufacturer), version.manufacturer); printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", - lmp_vertostr(version.lmp_ver), + ver ? ver : "n/a", version.lmp_ver, version.lmp_subver); + if (ver) + bt_free(ver); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { @@ -779,13 +782,16 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tDevice Name: %s\n", name); if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" "\tManufacturer: %s (%d)\n", - lmp_vertostr(version.lmp_ver), + ver ? ver : "n/a", version.lmp_ver, version.lmp_subver, bt_compidtostr(version.manufacturer), version.manufacturer); + if (ver) + bt_free(ver); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { -- cgit From fdc6176107c8ef2a88a225a335cca3c6cd2a0808 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 21:47:05 +0000 Subject: Add an example for the PSR file format --- tools/Makefile.am | 2 +- tools/example.psr | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tools/example.psr (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index adff35b9..e3983a17 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -72,6 +72,6 @@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 dfutool.1 +EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 dfutool.1 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/example.psr b/tools/example.psr new file mode 100644 index 00000000..bbbec73a --- /dev/null +++ b/tools/example.psr @@ -0,0 +1,12 @@ +// PSKEY_BDADDR +&0001 = 0001 2821 005b 6789 +// PSKEY_ANA_FTRIM +&01f6 = 0025 +// PSKEY_HOST_INTERFACE +&01f9 = 0001 +// PSKEY_UART_BAUD_RATE +&0204 = 01d8 +// PSKEY_ANA_FREQ +&01fe = 0004 +// PSKEY_UART_CONFIG +&0205 = 0006 -- cgit From 36e1d1d1f94e5cf10e9d5cf7de1d2878b3d33ed8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 Sep 2005 10:54:30 +0000 Subject: Add skeleton for the csrinit utility --- tools/Makefile.am | 19 ++++++++-- tools/csrinit.8 | 35 +++++++++++++++++++ tools/csrinit.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 tools/csrinit.8 create mode 100644 tools/csrinit.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index e3983a17..3a018bb7 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -18,6 +18,14 @@ hid2hci_programs = hid2hci_manfiles = endif +if CSRINIT +csrinit_programs = csrinit +csrinit_manfiles = csrinit.8 +else +csrinit_programs = +csrinit_manfiles = +endif + if DFUTOOL dfutool_programs = dfutool dfutool_manfiles = dfutool.1 @@ -26,7 +34,7 @@ dfutool_programs = dfutool_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) +sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) $(csrinit_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) @@ -60,6 +68,11 @@ if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif +if CSRINIT +csrinit_SOURCES = csrinit.c csr.h +csrinit_LDADD = @USB_LIBS@ +endif + if DFUTOOL dfutool_SOURCES = dfutool.c dfu.h dfu.c dfutool_LDADD = @USB_LIBS@ @@ -70,8 +83,8 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) + $(avctrl_manfiles) $(hid2hci_manfiles) $(csrinit_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 dfutool.1 example.psr +EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/csrinit.8 b/tools/csrinit.8 new file mode 100644 index 00000000..35a033d9 --- /dev/null +++ b/tools/csrinit.8 @@ -0,0 +1,35 @@ +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH CSRINIT 8 "SEPTEMBER 8, 2005" "" "" + +.SH NAME +csrinit \- Utility for the setting up CSR ROM chips +.SH SYNOPSIS +.BR "csrinit +[ +.I options +] +.SH DESCRIPTION +.B csrinit +is used to setup the ROM chips from CSR. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible options. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/csrinit.c b/tools/csrinit.c new file mode 100644 index 00000000..07310175 --- /dev/null +++ b/tools/csrinit.c @@ -0,0 +1,101 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "csr.h" + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif + +#ifndef USB_DIR_IN +#define USB_DIR_IN 0x80 +#endif + +static void usage(void) +{ + printf("csrinit - Utility for the setting up CSR ROM chips\n\n"); + + printf("Usage:\n" + "\tcsrinit [options]\n" + "\n"); + + printf("Options:\n" + "\t-h, --help Display help\n" + "\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + int opt; + + while ((opt = getopt_long(argc, argv, "+h", main_options, NULL)) != -1) { + switch (opt) { + case 'h': + usage(); + exit(0); + + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + usb_init(); + + return 0; +} -- cgit From 5a1c827dde80ace68f94641edb21d39c1ccacbbc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 Sep 2005 11:51:20 +0000 Subject: Update security filter definitions --- tools/hcisecfilter.c | 152 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 61 deletions(-) (limited to 'tools') diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index d3c658c8..02d0d554 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -45,82 +45,112 @@ int main(void) uint32_t ocf_mask[4]; /* Packet types */ - memset((void *)&type_mask, 0, sizeof(type_mask)); + memset(&type_mask, 0, sizeof(type_mask)); hci_set_bit(HCI_EVENT_PKT, &type_mask); - printf("Type mask: { 0x%x }\n", type_mask); + printf("Type mask: { 0x%02x }\n", type_mask); /* Events */ - memset((void *)event_mask, 0, sizeof(event_mask)); - hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); - hci_set_bit(EVT_INQUIRY_RESULT, event_mask); - - hci_set_bit(EVT_CONN_COMPLETE, event_mask); - hci_set_bit(EVT_CONN_REQUEST, event_mask); - hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); - - hci_set_bit(EVT_AUTH_COMPLETE, event_mask); - hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); - - hci_set_bit(EVT_CMD_COMPLETE, event_mask); - hci_set_bit(EVT_CMD_STATUS, event_mask); - - hci_set_bit(EVT_READ_REMOTE_FEATURES_COMPLETE, event_mask); - hci_set_bit(EVT_READ_REMOTE_VERSION_COMPLETE, event_mask); - hci_set_bit(EVT_REMOTE_NAME_REQ_COMPLETE, event_mask); - - printf("Event mask: { 0x%x, 0x%x }\n", event_mask[0], event_mask[1]); + memset(event_mask, 0, sizeof(event_mask)); + hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); + hci_set_bit(EVT_INQUIRY_RESULT, event_mask); + hci_set_bit(EVT_CONN_COMPLETE, event_mask); + hci_set_bit(EVT_CONN_REQUEST, event_mask); + hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); + hci_set_bit(EVT_AUTH_COMPLETE, event_mask); + hci_set_bit(EVT_REMOTE_NAME_REQ_COMPLETE, event_mask); + hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); + hci_set_bit(EVT_READ_REMOTE_FEATURES_COMPLETE, event_mask); + hci_set_bit(EVT_READ_REMOTE_VERSION_COMPLETE, event_mask); + hci_set_bit(EVT_CMD_COMPLETE, event_mask); + hci_set_bit(EVT_CMD_STATUS, event_mask); + hci_set_bit(EVT_READ_CLOCK_OFFSET_COMPLETE, event_mask); + hci_set_bit(EVT_INQUIRY_RESULT_WITH_RSSI, event_mask); + hci_set_bit(EVT_READ_REMOTE_EXT_FEATURES_COMPLETE, event_mask); + hci_set_bit(EVT_SYNC_CONN_COMPLETE, event_mask); + hci_set_bit(EVT_SYNC_CONN_CHANGED, event_mask); + //hci_set_bit(EVT_EXTENDED_INQUIRY_RESULT, event_mask); + + printf("Event mask: { 0x%08x, 0x%08x }\n", + event_mask[0], event_mask[1]); /* OGF_LINK_CTL */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_INQUIRY, ocf_mask); - hci_set_bit(OCF_REMOTE_NAME_REQ, ocf_mask); - hci_set_bit(OCF_READ_REMOTE_FEATURES, ocf_mask); - hci_set_bit(OCF_READ_REMOTE_VERSION, ocf_mask); - - printf("OGF_LINK_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", - ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_INQUIRY, ocf_mask); + hci_set_bit(OCF_INQUIRY_CANCEL, ocf_mask); + hci_set_bit(OCF_REMOTE_NAME_REQ, ocf_mask); + hci_set_bit(OCF_REMOTE_NAME_REQ_CANCEL, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_EXT_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_VERSION, ocf_mask); + hci_set_bit(OCF_READ_CLOCK_OFFSET, ocf_mask); + hci_set_bit(OCF_READ_LMP_HANDLE, ocf_mask); + + printf("OGF_LINK_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_LINK_POLICY */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); - hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); + hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); + hci_set_bit(OCF_READ_DEFAULT_LINK_POLICY, ocf_mask); - printf("OGF_LINK_POLICY: { 0x%x, 0x%x, 0x%x, 0x%x }\n", + printf("OGF_LINK_POLICY: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_HOST_CTL */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_READ_AUTH_ENABLE, ocf_mask); - hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); - hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); - hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); - hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); - hci_set_bit(OCF_READ_TRANSMIT_POWER_LEVEL, ocf_mask); - - printf("OGF_HOST_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", - ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_PIN_TYPE, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); + hci_set_bit(OCF_READ_CONN_ACCEPT_TIMEOUT, ocf_mask); + hci_set_bit(OCF_READ_PAGE_TIMEOUT, ocf_mask); + hci_set_bit(OCF_READ_SCAN_ENABLE, ocf_mask); + hci_set_bit(OCF_READ_PAGE_ACTIVITY, ocf_mask); + hci_set_bit(OCF_READ_INQ_ACTIVITY, ocf_mask); + hci_set_bit(OCF_READ_AUTH_ENABLE, ocf_mask); + hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); + hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); + hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); + hci_set_bit(OCF_READ_AUTOMATIC_FLUSH_TIMEOUT, ocf_mask); + hci_set_bit(OCF_READ_NUM_BROADCAST_RETRANS, ocf_mask); + hci_set_bit(OCF_READ_HOLD_MODE_ACTIVITY, ocf_mask); + hci_set_bit(OCF_READ_TRANSMIT_POWER_LEVEL, ocf_mask); + hci_set_bit(OCF_READ_LINK_SUPERVISION_TIMEOUT, ocf_mask); + hci_set_bit(OCF_READ_NUM_SUPPORTED_IAC, ocf_mask); + hci_set_bit(OCF_READ_CURRENT_IAC_LAP, ocf_mask); + hci_set_bit(OCF_READ_PAGE_SCAN_PERIOD_MODE, ocf_mask); + hci_set_bit(OCF_READ_PAGE_SCAN_MODE, ocf_mask); + hci_set_bit(OCF_READ_INQUIRY_SCAN_TYPE, ocf_mask); + hci_set_bit(OCF_READ_INQUIRY_MODE, ocf_mask); + hci_set_bit(OCF_READ_PAGE_SCAN_TYPE, ocf_mask); + hci_set_bit(OCF_READ_AFH_MODE, ocf_mask); + + printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_INFO_PARAM */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_READ_LOCAL_VERSION, ocf_mask); - hci_set_bit(OCF_READ_LOCAL_FEATURES, ocf_mask); - hci_set_bit(OCF_READ_BUFFER_SIZE, ocf_mask); - hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); - hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_LOCAL_VERSION, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_COMMANDS, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_EXT_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_BUFFER_SIZE, ocf_mask); + hci_set_bit(OCF_READ_COUNTRY_CODE, ocf_mask); + hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); + + printf("OGF_INFO_PARAM: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - printf("OGF_INFO_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", - ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + /* OGF_STATUS_PARAM */ + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); + hci_set_bit(OCF_READ_LINK_QUALITY, ocf_mask); + hci_set_bit(OCF_READ_RSSI, ocf_mask); + hci_set_bit(OCF_READ_AFH_MAP, ocf_mask); + hci_set_bit(OCF_READ_CLOCK, ocf_mask); - /* OGF_INFO_PARAM */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); - hci_set_bit(OCF_RESET_FAILED_CONTACT_COUNTER, ocf_mask); - hci_set_bit(OCF_READ_LINK_QUALITY, ocf_mask); - hci_set_bit(OCF_READ_RSSI, ocf_mask); - - printf("OGF_STATUS_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", - ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + printf("OGF_STATUS_PARAM: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); return 0; } -- cgit From 2ed8bc58caa1e27dffad6766a59f8f9f0930dc08 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Sep 2005 04:10:59 +0000 Subject: Don't forget the command for reading the extended inquiry response --- tools/hcisecfilter.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 02d0d554..5827f143 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -124,6 +124,7 @@ int main(void) hci_set_bit(OCF_READ_INQUIRY_MODE, ocf_mask); hci_set_bit(OCF_READ_PAGE_SCAN_TYPE, ocf_mask); hci_set_bit(OCF_READ_AFH_MODE, ocf_mask); + //hci_set_bit(OCF_READ_EXT_INQUIRY_RESPONSE, ocf_mask); printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); -- cgit From e116bfb4f0192a6e54a71dfb0b2f3b63849e1524 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 00:03:53 +0000 Subject: Add support for PSKEY_ANA_FREQ and PSKEY_ANA_FTRIM --- tools/csr.h | 4 +++- tools/pskey.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index acb30641..95b5c63d 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -65,7 +65,9 @@ #define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab #define CSR_PSKEY_UART_BAUDRATE 0x01be -#define CSR_PSKEY_HOST_INTERFACE 0x01f9 +#define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */ +#define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* uint16 */ +#define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */ #define CSR_PSKEY_USB_VENDOR_ID 0x02be #define CSR_PSKEY_USB_PRODUCT_ID 0x02bf #define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb diff --git a/tools/pskey.c b/tools/pskey.c index 9a4dd547..030a6a43 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -123,6 +123,8 @@ static struct { { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, + { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, "anafreq" }, + { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, "anaftrim" }, { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, -- cgit From b42672cbb91ea35268da5f0f385f539f133b2a0e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 00:09:39 +0000 Subject: Add PSKEY_ANA_FREQ and PSKEY_ANA_FTRIM translations --- tools/csr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 1f1ab229..5932c822 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -412,8 +412,12 @@ char *csr_pskeytostr(uint16_t pskey) return "Map SCO over PCM"; case CSR_PSKEY_UART_BAUDRATE: return "UART Baud rate"; + case CSR_PSKEY_ANA_FTRIM: + return "Crystal frequency trim"; case CSR_PSKEY_HOST_INTERFACE: return "Host interface"; + case CSR_PSKEY_ANA_FREQ: + return "Crystal frequency"; case CSR_PSKEY_USB_VENDOR_ID: return "USB vendor identifier"; case CSR_PSKEY_USB_PRODUCT_ID: -- cgit From 7eaf5aa39ab4592548baeffaca65f0e490e036b1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 00:34:21 +0000 Subject: Add support for transient persistent storage values --- tools/csr.c | 15 ++++++++------- tools/csr.h | 6 +++--- tools/hciconfig.c | 2 +- tools/pskey.c | 20 ++++++++++++++------ 4 files changed, 26 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 5932c822..39706623 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -598,13 +598,13 @@ int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *val return 0; } -int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length) +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, pskey & 0xff, pskey >> 8, (length / 2) & 0xff, (length / 2) >> 8, - 0x00, 0x00, 0x00, 0x00 }; + store & 0xff, store >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; struct hci_request rq; @@ -640,11 +640,12 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *val return 0; } -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value) +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, - pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; + pskey & 0xff, pskey >> 8, 0x01, 0x00, + store & 0xff, store >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; struct hci_request rq; @@ -680,12 +681,12 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *val return 0; } -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value) +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value) { unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, - pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, - value & 0xff, value >> 8 }; + pskey & 0xff, pskey >> 8, 0x01, 0x00, + store & 0xff, store >> 8, value & 0xff, value >> 8 }; unsigned char cp[254], rp[254]; struct hci_request rq; diff --git a/tools/csr.h b/tools/csr.h index 95b5c63d..dc5e1029 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -81,6 +81,6 @@ int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); -int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length); -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value); +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 0d13542d..2a352e85 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1225,7 +1225,7 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_varid_uint16(dd, 3, CSR_VARID_MAX_CRYPT_KEY_LENGTH, &maxkeylen)) printf("\tMax key size: %d bit\n", maxkeylen * 8); - if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) + if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, 0x0000, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); } diff --git a/tools/pskey.c b/tools/pskey.c index 030a6a43..0180be59 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -47,6 +47,8 @@ #define CSR_TYPE_UINT8 2 #define CSR_TYPE_UINT16 3 +static int transient = 0; + static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { uint16_t value; @@ -67,7 +69,8 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) else value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, 0x4711, pskey, value); + err = csr_write_pskey_uint16(dd, 0x4711, pskey, + transient ? 0x0008 : 0x0000, value); return err; } @@ -88,7 +91,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) } if (type != CSR_TYPE_ARRAY) { - err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); + err = csr_read_pskey_uint16(dd, 0x4711, pskey, 0x0000, &value); if (err < 0) return err; @@ -97,7 +100,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) size = 8; - err = csr_read_pskey_complex(dd, 0x4711, pskey, array, size); + err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); if (err < 0) return err; @@ -138,7 +141,7 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [value]\n\n"); + "\tpskey [-i ] [-t] [value]\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -153,8 +156,9 @@ static void usage(void) } static struct option main_options[] = { - { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, + { "transient", 0, 0, 't' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -164,7 +168,7 @@ int main(int argc, char *argv[]) struct hci_version ver; int i, err, dd, opt, dev = 0; - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:th", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -174,6 +178,10 @@ int main(int argc, char *argv[]) } break; + case 't': + transient = 1; + break; + case 'h': default: usage(); -- cgit From 0f29ca5cf9885ba0b22db226c73c09478470c097 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 00:47:42 +0000 Subject: Add optional warm reset of the device --- tools/pskey.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 0180be59..0c06e9ef 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -141,7 +141,7 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [-t] [value]\n\n"); + "\tpskey [-i ] [-r] [-t] [value]\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -157,6 +157,7 @@ static void usage(void) static struct option main_options[] = { { "device", 1, 0, 'i' }, + { "reset", 0, 0, 'r' }, { "transient", 0, 0, 't' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } @@ -166,9 +167,9 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0; + int i, err, dd, opt, dev = 0, reset = 0; - while ((opt=getopt_long(argc, argv, "+i:th", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rth", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -178,6 +179,10 @@ int main(int argc, char *argv[]) } break; + case 'r': + reset = 1; + break; + case 't': transient = 1; break; @@ -229,10 +234,14 @@ int main(int argc, char *argv[]) if (strcasecmp(storage[i].str, argv[0])) continue; - if (argc > 1) + if (argc > 1) { err = write_pskey(dd, storage[i].pskey, storage[i].type, argc - 1, argv + 1); - else + + if (reset) + csr_write_varid_valueless(dd, 0x0000, + CSR_VARID_WARM_RESET); + } else err = read_pskey(dd, storage[i].pskey, storage[i].type); hci_close_dev(dd); -- cgit From d83a07e5e8cef7c6a9af50e64ee5a8c9aa1ff069 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Sep 2005 03:20:14 +0000 Subject: Update PSKEY definitions --- tools/csr.c | 2 ++ tools/csr.h | 17 +++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 39706623..801652a1 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -408,6 +408,8 @@ char *csr_pskeytostr(uint16_t pskey) return "The HCI and LMP version reported locally"; case CSR_PSKEY_LMP_REMOTE_VERSION: return "The LMP version reported remotely"; + case CSR_PSKEY_HOSTIO_USE_HCI_EXTN: + return "Use hci_extn to route non-hci channels"; case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; case CSR_PSKEY_UART_BAUDRATE: diff --git a/tools/csr.h b/tools/csr.h index dc5e1029..1d9a18c2 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -59,19 +59,20 @@ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ #define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xFE8f, 0xF99B, 0x8000 } */ -#define CSR_PSKEY_ENC_KEY_LMIN 0x00da -#define CSR_PSKEY_ENC_KEY_LMAX 0x00db +#define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ +#define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ #define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ #define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ -#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab -#define CSR_PSKEY_UART_BAUDRATE 0x01be +#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool (uint16) */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab /* bool (uint16) */ +#define CSR_PSKEY_UART_BAUDRATE 0x01be /* uint16 */ #define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */ #define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* uint16 */ #define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */ -#define CSR_PSKEY_USB_VENDOR_ID 0x02be -#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf -#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb -#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd +#define CSR_PSKEY_USB_VENDOR_ID 0x02be /* uint16 */ +#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf /* uint16 */ +#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb /* uint16 */ +#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd /* int16 */ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); -- cgit From 12bc903cff57bed548080354159c0841cc20650b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Sep 2005 03:23:55 +0000 Subject: Support HOSTIO_USE_HCI_EXTN setting --- tools/pskey.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 0c06e9ef..f8d93042 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -123,6 +123,7 @@ static struct { { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, + { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, "hciextn" }, { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, -- cgit From fad20a44db8a86d6687c6c57e3f7e18a5320c95e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 Sep 2005 04:18:46 +0000 Subject: Fix wrong UUID-128 for the PalmOS id record --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index fd824c2c..6c07cfab 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2197,7 +2197,7 @@ static int add_palmos(sdp_session_t *session, svc_info_t *si) root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(&record, root); - sdp_uuid128_create(&svclass_uuid, (void *) hotsync_uuid); + sdp_uuid128_create(&svclass_uuid, (void *) palmos_uuid); svclass = sdp_list_append(NULL, &svclass_uuid); sdp_set_service_classes(&record, svclass); -- cgit From c30cad7c8395eec65221edd4d835c5a4b7a2dde1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Sep 2005 13:04:58 +0000 Subject: Add more build ids for Unified 20e and Unified 21a firmwares --- tools/csr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 801652a1..abf1150b 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -280,6 +280,10 @@ static struct { { 2244, "Unified 18e" }, { 2258, "Unified 20d" }, { 2259, "Unified 20d" }, + { 2361, "Unified 20e" }, + { 2362, "Unified 20e" }, + { 2423, "Unified 21a" }, + { 2424, "Unified 21a" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From ca1b11b40db46287fc63024d5bb824d9695c1b67 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Sep 2005 11:43:37 +0000 Subject: Include the stdint.h header file --- tools/csrinit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csrinit.c b/tools/csrinit.c index 07310175..5d939539 100644 --- a/tools/csrinit.c +++ b/tools/csrinit.c @@ -32,6 +32,7 @@ #include #include +#include #include #include -- cgit From 4e44a8510e66998d0df1c257014945535d1d847c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Sep 2005 16:22:58 +0000 Subject: Add build ids for new sniffer firmwares --- tools/csr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index abf1150b..250700d9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -342,6 +342,12 @@ static struct { { 2032, "Sniff 44 (2005-04-18)" }, { 2033, "Sniff 44 (2005-04-18)" }, { 2034, "Sniff 44 (2005-04-18)" }, + { 2288, "Sniff 45 (2005-07-08)" }, + { 2289, "Sniff 45 (2005-07-08)" }, + { 2290, "Sniff 45 (2005-07-08)" }, + { 2388, "Sniff 46 (2005-08-17)" }, + { 2389, "Sniff 46 (2005-08-17)" }, + { 2390, "Sniff 46 (2005-08-17)" }, { 0, } }; -- cgit From f1407f1eff7f904defca54b598bad95bff108fde Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Sep 2005 10:50:26 +0000 Subject: Add support for the extended inquiry response commands --- tools/hciconfig.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 2a352e85..1bf7438b 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -915,6 +915,48 @@ static void cmd_inq_mode(int ctl, int hdev, char *opt) } } +static void cmd_inq_data(int ctl, int hdev, char *opt) +{ + int i, dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (opt) { + uint8_t fec = 0, data[248]; + + memset(data, 0, sizeof(data)); + data[0] = strlen(opt) + 1; + data[1] = 0x09; + memcpy(data + 2, opt, strlen(opt)); + + if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { + fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint8_t fec, data[240]; + + if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) { + fprintf(stderr, "Can't read extended inquiry response on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf("\tFEC: %d\n\t", fec); + for (i = 0; i < 240; i++) + printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ", + (i + 1) % 16 ? " " : "\n\t"); + printf("\n"); + } +} + static void cmd_inq_type(int ctl, int hdev, char *opt) { int dd; @@ -1382,8 +1424,9 @@ static struct { { "class", cmd_class, "[class]", "Get/Set class of device" }, { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, - { "inqmode", cmd_inq_mode, "[mode]", "Get/set inquiry mode" }, - { "inqtype", cmd_inq_type, "[type]", "Get/set inquiry scan type" }, + { "inqmode", cmd_inq_mode, "[mode]", "Get/Set inquiry mode" }, + { "inqdata", cmd_inq_data, "[name]", "Get/Set inquiry data (device name)" }, + { "inqtype", cmd_inq_type, "[type]", "Get/Set inquiry scan type" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, -- cgit From 8b530335eac02fdb11c449068eb0732fb45bfa93 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Sep 2005 11:12:26 +0000 Subject: Update for the extended inquiry response command --- tools/hciconfig.8 | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 53c60526..0547ae3a 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -133,6 +133,12 @@ With no prints out the current inquiry mode. Otherwise, sets inquiry mode to .IR mode . .TP +.BI inqdata " [name]" +With no +.IR name , +prints out the current inquiry data. Otherwise, sets inquiry data to +.IR name . +.TP .BI inqtype " [type]" With no .IR type , -- cgit From bf1758786cd88dbf3ae3d113f7fce95c43ee71eb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Sep 2005 11:13:25 +0000 Subject: Add support for inquiry access codes --- tools/hcitool.c | 57 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 2865ec42..1804d9fd 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -323,6 +323,7 @@ static struct option inq_options[] = { { "help", 0, 0, 'h' }, { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, + { "iac", 1, 0, 'i' }, { "flush", 0, 0, 'f' }, { 0, 0, 0, 0 } }; @@ -331,14 +332,16 @@ static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--iac=lap] specify the inquiry access code\n" "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { - int num_rsp, length, flags; inquiry_info *info = NULL; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + int num_rsp, length, flags; char addr[18]; - int i, opt; + int i, l, opt; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -354,6 +357,17 @@ static void cmd_inq(int dev_id, int argc, char **argv) num_rsp = atoi(optarg); break; + case 'i': + l = strtoul(optarg, 0, 16); + if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + break; + case 'f': flags |= IREQ_CACHE_FLUSH; break; @@ -365,7 +379,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) } printf("Inquiring ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); if (num_rsp < 0) { perror("Inquiry failed."); exit(1); @@ -389,22 +403,24 @@ static struct option scan_options[] = { { "help", 0, 0, 'h' }, { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, + { "iac", 1, 0, 'i' }, { "flush", 0, 0, 'f' }, - { "class", 0, 0, 'c' }, - { "info", 0, 0, 'i' }, - { "oui", 0, 0, 'o' }, - { "all", 0, 0, 'a' }, - { "ext", 0, 0, 'a' }, + { "class", 0, 0, 'C' }, + { "info", 0, 0, 'I' }, + { "oui", 0, 0, 'O' }, + { "all", 0, 0, 'A' }, + { "ext", 0, 0, 'A' }, { 0, 0, 0, 0 } }; static char *scan_help = "Usage:\n" - "\tscan [--length=N] [--numrsp=N] [--flush] [--class] [--info] [--oui]\n"; + "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui]\n"; static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; int num_rsp, length, flags; uint8_t cls[3], features[8]; uint16_t handle; @@ -413,7 +429,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, n, opt, dd, cc, nc; + int i, n, l, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -429,23 +445,34 @@ static void cmd_scan(int dev_id, int argc, char **argv) num_rsp = atoi(optarg); break; + case 'i': + l = strtoul(optarg, 0, 16); + if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + break; + case 'f': flags |= IREQ_CACHE_FLUSH; break; - case 'c': + case 'C': extcls = 1; break; - case 'i': + case 'I': extinf = 1; break; - case 'o': + case 'O': extoui = 1; break; - case 'a': + case 'A': extcls = 1; extinf = 1; extoui = 1; @@ -471,7 +498,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } printf("Scanning ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); if (num_rsp < 0) { perror("Inquiry failed"); exit(1); -- cgit From 3e077cde783d52817e9934681699c51994ba2031 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 30 Sep 2005 13:05:09 +0000 Subject: Add manual page for bccmd utility --- tools/Makefile.am | 4 +++- tools/bccmd.8 | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 tools/bccmd.8 (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 3a018bb7..8a2241c6 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -85,6 +85,8 @@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ $(avctrl_manfiles) $(hid2hci_manfiles) $(csrinit_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 example.psr +noinst_MANS = bccmd.8 + +EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 bccmd.8 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/bccmd.8 b/tools/bccmd.8 new file mode 100644 index 00000000..a51be28e --- /dev/null +++ b/tools/bccmd.8 @@ -0,0 +1,55 @@ +.TH BCCMD 8 "Sep 30 2005" BlueZ "Linux System Administration" +.SH NAME +bccmd \- Utility for the CSR BCCMD interface +.SH SYNOPSIS +.B bccmd +.br +.B bccmd [-i ] +.br + +.SH DESCRIPTION +.LP +.B +bccmd +issues BlueCore commands to +.B +Cambridge Silicon Radio +devices. If run without the argument, a short help page will be diaplayed. +.PP + +.SH OPTIONS +.TP +.BI -i\ +Specify a particular device to operate on. If not specified, default is the first available device. +.SH COMMANDS +.TP +.BI keylen\ +Get current crypt key length +.TP +.BI clock +Get local Bluetooth clock +.TP +.BI rand +Get random number +.TP +.BI panicarg +Get panic code argument +.TP +.BI faultarg +Get fault code argument +.TP +.BI coldreset +Perform cold reset +.TP +.BI warmreset +Perform warm reset +.TP +.BI disabletx +Disable TX on the device +.TP +.BI enabletx +Enable TX on the device +.SH AUTHORS +Written by Marcel Holtmann , +man page by Adam Laurie +.PP -- cgit From 5b90831adf64b3461986e52afe608b8917f389c9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 19 Oct 2005 10:51:58 +0000 Subject: Add command for device discovery --- tools/avctrl.8 | 1 + tools/avctrl.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/avctrl.8 b/tools/avctrl.8 index f791cf9e..7c3759d6 100644 --- a/tools/avctrl.8 +++ b/tools/avctrl.8 @@ -23,6 +23,7 @@ avctrl \- Bluetooth Audio/Video control utility [ .I options ] + .SH DESCRIPTION .B avctrl is used to control the Audio/Video dongles. diff --git a/tools/avctrl.c b/tools/avctrl.c index 14d42e4a..03b54117 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -66,7 +66,7 @@ struct device_info; struct device_id { uint16_t vendor; uint16_t product; - int (*func)(struct device_info *dev); + int (*func)(struct device_info *dev, int argc, char *argv[]); }; struct device_info { @@ -80,12 +80,23 @@ struct device_info { #define SWITCH_TO_DFU 0x04 #define READ_CODEC 0x05 -static int dongle_csr(struct device_info *devinfo) +static int dongle_csr(struct device_info *devinfo, int argc, char *argv[]) { char buf[8]; struct usb_dev_handle *udev; int err, intf = 2; + memset(buf, 0, sizeof(buf)); + + if (!strncasecmp(argv[0], "discover", 4)) + buf[0] = DISCOVER; + else if (!strncasecmp(argv[0], "switch", 3)) + buf[0] = SWITCH_TO_DFU; + else if (!strncasecmp(argv[0], "dfu", 3)) + buf[0] = SWITCH_TO_DFU; + else + return -EINVAL; + udev = usb_open(devinfo->dev); if (!udev) return -errno; @@ -96,9 +107,6 @@ static int dongle_csr(struct device_info *devinfo) return err; } - memset(buf, 0, sizeof(buf)); - buf[0] = SWITCH_TO_DFU; - err = usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, HID_REQ_SET_REPORT, 0x03 << 8, intf, buf, sizeof(buf), 10000); @@ -166,13 +174,18 @@ static void usage(void) printf("avctrl - Bluetooth Audio/Video control utility\n\n"); printf("Usage:\n" - "\tavctrl [options]\n" + "\tavctrl [options] \n" "\n"); printf("Options:\n" "\t-h, --help Display help\n" "\t-q, --quiet Don't display any messages\n" "\n"); + + printf("Commands:\n" + "\tdiscover Simulate pressing the discover button\n" + "\tswitch Switch the dongle to DFU mode\n" + "\n"); } static struct option main_options[] = { @@ -203,6 +216,11 @@ int main(int argc, char *argv[]) argv += optind; optind = 0; + if (argc < 1) { + usage(); + exit(1); + } + usb_init(); num = find_devices(dev, sizeof(dev) / sizeof(dev[0])); @@ -214,15 +232,17 @@ int main(int argc, char *argv[]) for (i = 0; i < num; i++) { struct device_id *id = dev[i].id; + int err; if (!quiet) - printf("Switching device %04x:%04x ", + printf("Selecting device %04x:%04x ", id->vendor, id->product); fflush(stdout); - if (id->func(&dev[i]) < 0) { + err = id->func(&dev[i], argc, argv); + if (err < 0) { if (!quiet) - printf("failed (%s)\n", strerror(errno)); + printf("failed (%s)\n", strerror(-err)); } else { if (!quiet) printf("was successful\n"); -- cgit From 97a6bcbbe32c89438f4f54e47b376c75e2949763 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 21 Oct 2005 11:44:26 +0000 Subject: Allow clear text IAC values --- tools/hciconfig.c | 11 ++++++++--- tools/hcitool.c | 13 +++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1bf7438b..f85f5272 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -158,7 +159,11 @@ static void cmd_iac(int ctl, int hdev, char *opt) if (opt) { int l = strtoul(opt, 0, 16); uint8_t lap[3]; - if (l < 0x9e8b00 || l > 0x9e8b3f) { + if (!strcasecmp(opt, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(opt, "liac")) { + l = 0x9e8b00; + } else if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } @@ -182,8 +187,8 @@ static void cmd_iac(int ctl, int hdev, char *opt) for (i = 0; i < n; i++) { printf("0x"); for (j = 3; j--; ) - printf("%02x", lap[j + 3*i]); - if (i < n-1) + printf("%02x", lap[j + 3 * i]); + if (i < n - 1) printf(", "); } printf("\n"); diff --git a/tools/hcitool.c b/tools/hcitool.c index 1804d9fd..75b09b77 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -359,7 +360,11 @@ static void cmd_inq(int dev_id, int argc, char **argv) case 'i': l = strtoul(optarg, 0, 16); - if (l < 0x9e8b00 || l > 0x9e8b3f) { + if (!strcasecmp(optarg, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(optarg, "liac")) { + l = 0x9e8b00; + } if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } @@ -447,7 +452,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) case 'i': l = strtoul(optarg, 0, 16); - if (l < 0x9e8b00 || l > 0x9e8b3f) { + if (!strcasecmp(optarg, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(optarg, "liac")) { + l = 0x9e8b00; + } else if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } -- cgit From a8f6c4d67b3f06165e27570ffeecea464fbe877c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Oct 2005 22:25:31 +0000 Subject: Add support for writing complex PS keys --- tools/csr.c | 59 ++++++++++++++++++++--------------------------------------- tools/csr.h | 1 + 2 files changed, 21 insertions(+), 39 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 250700d9..e600cec7 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -463,7 +463,7 @@ int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid) case CSR_VARID_WARM_HALT: return hci_send_cmd(dd, OGF_VENDOR_CMD, 0x00, sizeof(cmd) + 1, cp); } - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = 0x00; @@ -630,7 +630,7 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; + rq.clen = sizeof(cmd) + length - 1; rq.rparam = rp; rq.rlen = sizeof(rp); @@ -652,11 +652,12 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto return 0; } -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value) +int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length) { - unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, + unsigned char cmd[] = { 0x02, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, - pskey & 0xff, pskey >> 8, 0x01, 0x00, + pskey & 0xff, pskey >> 8, + (length / 2) & 0xff, (length / 2) >> 8, store & 0xff, store >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; @@ -666,12 +667,14 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stor cp[0] = 0xc2; memcpy(cp + 1, cmd, sizeof(cmd)); + memcpy(cp + 17, value, length); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; + rq.clen = sizeof(cmd) + length - 1; rq.rparam = rp; rq.rlen = sizeof(rp); @@ -688,46 +691,24 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stor return -1; } - *value = rp[17] + (rp[18] << 8); - return 0; } -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value) +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value) { - unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, - seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, - pskey & 0xff, pskey >> 8, 0x01, 0x00, - store & 0xff, store >> 8, value & 0xff, value >> 8 }; - - unsigned char cp[254], rp[254]; - struct hci_request rq; + uint8_t array[2] = { 0x00, 0x00 }; + int err; - memset(&cp, 0, sizeof(cp)); - cp[0] = 0xc2; - memcpy(cp + 1, cmd, sizeof(cmd)); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = 0x00; - rq.event = EVT_VENDOR; - rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; - rq.rparam = rp; - rq.rlen = sizeof(rp); + err = csr_read_pskey_complex(dd, seqnum, pskey, store, array, 2); - if (hci_send_req(dd, &rq, 2000) < 0) - return -1; + *value = array[0] + (array[1] << 8); - if (rp[0] != 0xc2) { - errno = EIO; - return -1; - } + return err; +} - if ((rp[9] + (rp[10] << 8)) != 0) { - errno = ENXIO; - return -1; - } +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value) +{ + uint8_t array[2] = { value & 0xff, value >> 8 }; - return 0; + return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 2); } diff --git a/tools/csr.h b/tools/csr.h index 1d9a18c2..7d928d13 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -83,5 +83,6 @@ int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *val int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); +int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); -- cgit From b8857295f260fba3aa0e977cddfeb5e38d79298b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Oct 2005 22:26:59 +0000 Subject: Add support for changing the feature bits --- tools/pskey.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index f8d93042..45c53b32 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -51,26 +51,50 @@ static int transient = 0; static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { + uint8_t array[64]; uint16_t value; - int err; + int i, err, size = sizeof(array); - if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { + memset(array, 0, sizeof(array)); + + if (type != CSR_TYPE_ARRAY && + type != CSR_TYPE_UINT8 && + type != CSR_TYPE_UINT16) { errno = EFAULT; return -1; } - if (argc != 1) { - errno = E2BIG; - return -1; - } + if (type != CSR_TYPE_ARRAY) { + if (argc != 1) { + errno = E2BIG; + return -1; + } - if (!strncasecmp(argv[0], "0x", 2)) - value = strtol(argv[0] + 2, NULL, 16); - else - value = atoi(argv[0]); + if (!strncasecmp(argv[0], "0x", 2)) + value = strtol(argv[0] + 2, NULL, 16); + else + value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, 0x4711, pskey, + err = csr_write_pskey_uint16(dd, 0x4711, pskey, transient ? 0x0008 : 0x0000, value); + } else { + if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) + size = 8; + + if (argc != size) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < size; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i] = strtol(argv[i] + 2, NULL, 16); + else + array[i] = atoi(argv[i]); + + err = csr_write_pskey_complex(dd, 0x4711, pskey, + transient ? 0x0008 : 0x0000, array, size); + } return err; } @@ -239,7 +263,7 @@ int main(int argc, char *argv[]) err = write_pskey(dd, storage[i].pskey, storage[i].type, argc - 1, argv + 1); - if (reset) + if (!err && reset) csr_write_varid_valueless(dd, 0x0000, CSR_VARID_WARM_RESET); } else -- cgit From 807ca2230559ac939c8b481a9fcfe337a6707b3d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 20:26:25 +0000 Subject: Add the local supported commands PSKEY --- tools/csr.c | 2 ++ tools/csr.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index e600cec7..5a08d51f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -414,6 +414,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Maximum encryption key length"; case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: return "Local supported features block"; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return "Local supported commands"; case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: return "The HCI and LMP version reported locally"; case CSR_PSKEY_LMP_REMOTE_VERSION: diff --git a/tools/csr.h b/tools/csr.h index 7d928d13..e6c2acad 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -58,9 +58,10 @@ #define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ -#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xFE8f, 0xF99B, 0x8000 } */ #define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ #define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ +#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 } */ +#define CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS 0x0106 /* uint16[] = { 0xffff, 0x03ff, 0xfffe, 0xffff, 0xffff, 0xffff, 0x0ff3, 0xfff8, 0x003f } */ #define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ #define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ #define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool (uint16) */ -- cgit From a9e2212be2ea550a0421610c97cdce775e98ac62 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 20:27:03 +0000 Subject: Add support for the local supported commands --- tools/pskey.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 45c53b32..b4a6a3f5 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -78,8 +78,14 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) err = csr_write_pskey_uint16(dd, 0x4711, pskey, transient ? 0x0008 : 0x0000, value); } else { - if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) + switch (pskey) { + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: size = 8; + break; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + size = 18; + break; + } if (argc != size) { errno = EINVAL; @@ -121,8 +127,14 @@ static int read_pskey(int dd, uint16_t pskey, int type) printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); } else { - if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) + switch (pskey) { + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: size = 8; + break; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + size = 18; + break; + } err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); if (err < 0) @@ -145,6 +157,7 @@ static struct { { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, + { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, "commands" }, { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, "hciextn" }, -- cgit From 8a908f68a13c67fc1f0314957d91300d027213c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 22:22:45 +0000 Subject: Add support for the Logitech diNovo Media Desktop Laser --- tools/hid2hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 9a85c1fd..a5c2722c 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -226,6 +226,7 @@ static struct device_id device_list[] = { { HCI, 0x046d, 0xc703, switch_logitech }, { HCI, 0x046d, 0xc704, switch_logitech }, { HCI, 0x046d, 0xc705, switch_logitech }, + { HCI, 0x046d, 0x0b02, switch_logitech }, /* Logitech diNovo Media Desktop Laser */ { -1 } }; -- cgit From 3705606f41a7b9150a8ac66a9f83c4d534a95507 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 22:26:29 +0000 Subject: Add more BCCMD command ids and PS key values --- tools/csr.c | 6 +++++ tools/csr.h | 76 ++++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 51 insertions(+), 31 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 5a08d51f..4ab38232 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -408,6 +408,12 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) char *csr_pskeytostr(uint16_t pskey) { switch (pskey) { + case CSR_PSKEY_BDADDR: + return "Bluetooth address"; + case CSR_PSKEY_COUNTRYCODE: + return "Country code"; + case CSR_PSKEY_CLASSOFDEVICE: + return "Class of device"; case CSR_PSKEY_ENC_KEY_LMIN: return "Minimum encryption key length"; case CSR_PSKEY_ENC_KEY_LMAX: diff --git a/tools/csr.h b/tools/csr.h index e6c2acad..ff2c6541 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -26,38 +26,52 @@ * $Id$ */ -#define CSR_VARID_BC01_STATUS 0x2801 /* uint16 */ -#define CSR_VARID_BUILDID 0x2819 /* uint16 */ -#define CSR_VARID_CHIPVER 0x281a /* uint16 */ -#define CSR_VARID_CHIPREV 0x281b /* uint16 */ -#define CSR_VARID_INTERFACE_VERSION 0x2825 /* uint16 */ -#define CSR_VARID_RAND 0x282a /* uint16 */ -#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c /* uint16 */ -#define CSR_VARID_CHIPANAREV 0x2836 /* uint16 */ -#define CSR_VARID_BUILDID_LOADER 0x2838 /* uint16 */ -#define CSR_VARID_BT_CLOCK 0x2c00 /* uint32 */ -#define CSR_VARID_CRYPT_KEY_LENGTH 0x3008 /* complex */ -#define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */ -#define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ -#define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ -#define CSR_VARID_COLD_RESET 0x4001 /* valueless */ -#define CSR_VARID_WARM_RESET 0x4002 /* valueless */ -#define CSR_VARID_COLD_HALT 0x4003 /* valueless */ -#define CSR_VARID_WARM_HALT 0x4004 /* valueless */ -#define CSR_VARID_INIT_BT_STACK 0x4005 /* valueless */ -#define CSR_VARID_ACTIVATE_BT_STACK 0x4006 /* valueless */ -#define CSR_VARID_ENABLE_TX 0x4007 /* valueless */ -#define CSR_VARID_DISABLE_TX 0x4008 /* valueless */ -#define CSR_VARID_RECAL 0x4009 /* valueless */ -#define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ -#define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */ -#define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */ -#define CSR_VARID_CONFIG_UART 0x6802 /* uint16 */ -#define CSR_VARID_PANIC_ARG 0x6805 /* uint16 */ -#define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */ -#define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ -#define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ +#define CSR_VARID_PS_CLR_ALL 0x000b /* valueless */ +#define CSR_VARID_PS_FACTORY_SET 0x000c /* valueless */ +#define CSR_VARID_PS_CLR_ALL_STORES 0x082d /* uint16 */ +#define CSR_VARID_BC01_STATUS 0x2801 /* uint16 */ +#define CSR_VARID_BUILDID 0x2819 /* uint16 */ +#define CSR_VARID_CHIPVER 0x281a /* uint16 */ +#define CSR_VARID_CHIPREV 0x281b /* uint16 */ +#define CSR_VARID_INTERFACE_VERSION 0x2825 /* uint16 */ +#define CSR_VARID_RAND 0x282a /* uint16 */ +#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c /* uint16 */ +#define CSR_VARID_CHIPANAREV 0x2836 /* uint16 */ +#define CSR_VARID_BUILDID_LOADER 0x2838 /* uint16 */ +#define CSR_VARID_BT_CLOCK 0x2c00 /* uint32 */ +#define CSR_VARID_PS_NEXT 0x3005 /* complex */ +#define CSR_VARID_PS_SIZE 0x3006 /* complex */ +#define CSR_VARID_CRYPT_KEY_LENGTH 0x3008 /* complex */ +#define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */ +#define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ +#define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ +#define CSR_VARID_COLD_RESET 0x4001 /* valueless */ +#define CSR_VARID_WARM_RESET 0x4002 /* valueless */ +#define CSR_VARID_COLD_HALT 0x4003 /* valueless */ +#define CSR_VARID_WARM_HALT 0x4004 /* valueless */ +#define CSR_VARID_INIT_BT_STACK 0x4005 /* valueless */ +#define CSR_VARID_ACTIVATE_BT_STACK 0x4006 /* valueless */ +#define CSR_VARID_ENABLE_TX 0x4007 /* valueless */ +#define CSR_VARID_DISABLE_TX 0x4008 /* valueless */ +#define CSR_VARID_RECAL 0x4009 /* valueless */ +#define CSR_VARID_PS_FACTORY_RESTORE 0x400d /* valueless */ +#define CSR_VARID_PS_FACTORY_RESTORE_ALL 0x400e /* valueless */ +#define CSR_VARID_PS_DEFRAG_RESET 0x400f /* valueless */ +#define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ +#define CSR_VARID_PS_CLR 0x4818 /* uint16 */ +#define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */ +#define CSR_VARID_PS_CLR_STORES 0x500c /* complex */ +#define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */ +#define CSR_VARID_CONFIG_UART 0x6802 /* uint16 */ +#define CSR_VARID_PANIC_ARG 0x6805 /* uint16 */ +#define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */ +#define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ +#define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ +#define CSR_VARID_PS 0x7002 /* complex */ +#define CSR_PSKEY_BDADDR 0x0001 /* uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ +#define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ +#define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* uint32 */ #define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ #define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ #define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 } */ -- cgit From 51a4c2e364b3096d945ac4a01e844ca5d1513f4a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 22:27:08 +0000 Subject: Add support for listing all available PS keys --- tools/pskey.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index b4a6a3f5..24c0c4f2 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -179,7 +179,8 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [-r] [-t] [value]\n\n"); + "\tpskey [-i ] [-r] [-t] [value]\n" + "\tpskey [-i ] --list\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -197,6 +198,7 @@ static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, { "transient", 0, 0, 't' }, + { "list", 0, 0, 'l' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -205,9 +207,9 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0, reset = 0; + int i, err, dd, opt, dev = 0, list = 0, reset = 0; - while ((opt=getopt_long(argc, argv, "+i:rth", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rtlh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -225,6 +227,10 @@ int main(int argc, char *argv[]) transient = 1; break; + case 'l': + list = 1; + break; + case 'h': default: usage(); @@ -236,7 +242,7 @@ int main(int argc, char *argv[]) argv += optind; optind = 0; - if (argc < 1) { + if (!list && argc < 1) { usage(); exit(1); } @@ -268,6 +274,44 @@ int main(int argc, char *argv[]) exit(1); } + if (list) { + uint8_t array[8]; + uint16_t length, seqnum = 0x0000, pskey = 0x0000; + int err; + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, sizeof(array)); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, sizeof(array)); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + + printf("0x%04x - %s (%d bytes)\n", pskey, + csr_pskeytostr(pskey), length * 2); + } + + hci_close_dev(dd); + exit(0); + } + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; -- cgit From 967b0ec7667fb6d3db632ce8ccc66668c060a1f0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 23:10:08 +0000 Subject: Add support for UINT32 PS keys --- tools/csr.c | 21 +++++++++++++++++++++ tools/csr.h | 2 ++ 2 files changed, 23 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 4ab38232..936a20f9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -720,3 +720,24 @@ int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 2); } + +int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value) +{ + uint8_t array[4] = { 0x00, 0x00, 0x00, 0x00 }; + int err; + + err = csr_read_pskey_complex(dd, seqnum, pskey, store, array, 4); + + *value = ((array[0] + (array[1] << 8)) << 16) + + (array[2] + (array[3] << 8)); + + return err; +} + +int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value) +{ + uint8_t array[4] = { (value & 0xff0000) >> 16, value >> 24, + value & 0xff, (value & 0xff00) >> 8 }; + + return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 4); +} diff --git a/tools/csr.h b/tools/csr.h index ff2c6541..74c97c92 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -101,3 +101,5 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); +int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value); +int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value); -- cgit From d17f131aa94e5aa9e3bcfe391f033ada1bc855da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 23:10:53 +0000 Subject: Add PS keys for BD_ADDR, country code and class of device --- tools/pskey.c | 127 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 46 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 24c0c4f2..bf044dd3 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -46,25 +46,54 @@ #define CSR_TYPE_ARRAY 1 #define CSR_TYPE_UINT8 2 #define CSR_TYPE_UINT16 3 +#define CSR_TYPE_UINT32 4 static int transient = 0; +static int pskey_size(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_BDADDR: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return 18; + default: + return 64; + } +} + static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { uint8_t array[64]; uint16_t value; + uint32_t val32; int i, err, size = sizeof(array); memset(array, 0, sizeof(array)); - if (type != CSR_TYPE_ARRAY && - type != CSR_TYPE_UINT8 && - type != CSR_TYPE_UINT16) { - errno = EFAULT; - return -1; - } + switch (type) { + case CSR_TYPE_ARRAY: + size = pskey_size(pskey); + + if (argc != size) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < size; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i] = strtol(argv[i] + 2, NULL, 16); + else + array[i] = atoi(argv[i]); + + err = csr_write_pskey_complex(dd, 0x4711, pskey, + transient ? 0x0008 : 0x0000, array, size); + break; - if (type != CSR_TYPE_ARRAY) { + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: if (argc != 1) { errno = E2BIG; return -1; @@ -77,29 +106,27 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) err = csr_write_pskey_uint16(dd, 0x4711, pskey, transient ? 0x0008 : 0x0000, value); - } else { - switch (pskey) { - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - size = 8; - break; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - size = 18; - break; - } + break; - if (argc != size) { - errno = EINVAL; + case CSR_TYPE_UINT32: + if (argc != 1) { + errno = E2BIG; return -1; } - for (i = 0; i < size; i++) - if (!strncasecmp(argv[0], "0x", 2)) - array[i] = strtol(argv[i] + 2, NULL, 16); - else - array[i] = atoi(argv[i]); + if (!strncasecmp(argv[0], "0x", 2)) + val32 = strtol(argv[0] + 2, NULL, 16); + else + val32 = atoi(argv[0]); - err = csr_write_pskey_complex(dd, 0x4711, pskey, - transient ? 0x0008 : 0x0000, array, size); + err = csr_write_pskey_uint32(dd, 0x4711, pskey, + transient ? 0x0008 : 0x0000, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; } return err; @@ -109,41 +136,46 @@ static int read_pskey(int dd, uint16_t pskey, int type) { uint8_t array[64]; uint16_t value = 0; + uint32_t val32 = 0; int i, err, size = sizeof(array); memset(array, 0, sizeof(array)); - if (type != CSR_TYPE_ARRAY && - type != CSR_TYPE_UINT8 && - type != CSR_TYPE_UINT16) { - errno = EFAULT; - return -1; - } + switch (type) { + case CSR_TYPE_ARRAY: + size = pskey_size(pskey); - if (type != CSR_TYPE_ARRAY) { + err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); + if (err < 0) + return err; + + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < size; i++) + printf(" 0x%02x", array[i]); + printf("\n"); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: err = csr_read_pskey_uint16(dd, 0x4711, pskey, 0x0000, &value); if (err < 0) return err; printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); - } else { - switch (pskey) { - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - size = 8; - break; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - size = 18; - break; - } + break; - err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); + case CSR_TYPE_UINT32: + err = csr_read_pskey_uint32(dd, 0x4711, pskey, 0x0000, &val32); if (err < 0) return err; - printf("%s:", csr_pskeytostr(pskey)); - for (i = 0; i < size; i++) - printf(" 0x%02x", array[i]); - printf("\n"); + printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; } return err; @@ -154,6 +186,9 @@ static struct { int type; char *str; } storage[] = { + { CSR_PSKEY_BDADDR, CSR_TYPE_ARRAY, "bdaddr" }, + { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, "country" }, + { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, "devclass" }, { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, -- cgit From 70d9cbea647199f8f76d0f6b467799c5bb7b95fb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 23:19:09 +0000 Subject: Add more PS key definitions --- tools/csr.c | 10 ++++++++++ tools/csr.h | 5 +++++ 2 files changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 936a20f9..43ae25b0 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -414,6 +414,16 @@ char *csr_pskeytostr(uint16_t pskey) return "Country code"; case CSR_PSKEY_CLASSOFDEVICE: return "Class of device"; + case CSR_PSKEY_DEVICE_DRIFT: + return "Device drift"; + case CSR_PSKEY_DEVICE_JITTER: + return "Device jitter"; + case CSR_PSKEY_MAX_ACLS: + return "Maximum ACL links"; + case CSR_PSKEY_MAX_SCOS: + return "Maximum SCO links"; + case CSR_PSKEY_MAX_REMOTE_MASTERS: + return "Maximum remote masters"; case CSR_PSKEY_ENC_KEY_LMIN: return "Minimum encryption key length"; case CSR_PSKEY_ENC_KEY_LMAX: diff --git a/tools/csr.h b/tools/csr.h index 74c97c92..0f9859fa 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -72,6 +72,11 @@ #define CSR_PSKEY_BDADDR 0x0001 /* uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ #define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ #define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* uint32 */ +#define CSR_PSKEY_DEVICE_DRIFT 0x0004 /* uint16 */ +#define CSR_PSKEY_DEVICE_JITTER 0x0005 /* uint16 */ +#define CSR_PSKEY_MAX_ACLS 0x000d /* uint16 */ +#define CSR_PSKEY_MAX_SCOS 0x000e /* uint16 */ +#define CSR_PSKEY_MAX_REMOTE_MASTERS 0x000f /* uint16 */ #define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ #define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ #define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 } */ -- cgit From fdb212e90ef47972b4d2d1745d6da7e927ab19ff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 00:55:12 +0000 Subject: Update the list of PS keys --- tools/csr.c | 802 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 449 ++++++++++++++++++++++++++++++++-- 2 files changed, 1227 insertions(+), 24 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 43ae25b0..556f13cb 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -424,38 +424,840 @@ char *csr_pskeytostr(uint16_t pskey) return "Maximum SCO links"; case CSR_PSKEY_MAX_REMOTE_MASTERS: return "Maximum remote masters"; + case CSR_PSKEY_ENABLE_MASTERY_WITH_SLAVERY: + return "Support master and slave roles simultaneously"; + case CSR_PSKEY_H_HC_FC_MAX_ACL_PKT_LEN: + return "Maximum HCI ACL packet length"; + case CSR_PSKEY_H_HC_FC_MAX_SCO_PKT_LEN: + return "Maximum HCI SCO packet length"; + case CSR_PSKEY_H_HC_FC_MAX_ACL_PKTS: + return "Maximum number of HCI ACL packets"; + case CSR_PSKEY_H_HC_FC_MAX_SCO_PKTS: + return "Maximum number of HCI SCO packets"; + case CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK: + return "Flow control low water mark"; + case CSR_PSKEY_LC_MAX_TX_POWER: + return "Maximum transmit power"; + case CSR_PSKEY_TX_GAIN_RAMP: + return "Transmit gain ramp rate"; + case CSR_PSKEY_LC_PEER_POWER_PERIOD: + return "Peer transmit power control interval"; + case CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK: + return "Flow control pool low water mark"; + case CSR_PSKEY_LC_DEFAULT_TX_POWER: + return "Default transmit power"; + case CSR_PSKEY_LC_RSSI_GOLDEN_RANGE: + return "RSSI at bottom of golden receive range"; + case CSR_PSKEY_LC_COMBO_DISABLE_PIO_MASK: + return "Combo: PIO lines and logic to disable transmit"; + case CSR_PSKEY_LC_COMBO_PRIORITY_PIO_MASK: + return "Combo: priority activity PIO lines and logic"; + case CSR_PSKEY_LC_COMBO_DOT11_CHANNEL_PIO_BASE: + return "Combo: 802.11b channel number base PIO line"; + case CSR_PSKEY_LC_COMBO_DOT11_BLOCK_CHANNELS: + return "Combo: channels to block either side of 802.11b"; + case CSR_PSKEY_LC_MAX_TX_POWER_NO_RSSI: + return "Maximum transmit power when peer has no RSSI"; + case CSR_PSKEY_LC_CONNECTION_RX_WINDOW: + return "Receive window size during connections"; + case CSR_PSKEY_LC_COMBO_DOT11_TX_PROTECTION_MODE: + return "Combo: which TX packets shall we protect"; + case CSR_PSKEY_LC_ENHANCED_POWER_TABLE: + return "Radio power table"; + case CSR_PSKEY_LC_WIDEBAND_RSSI_CONFIG: + return "RSSI configuration for use with wideband RSSI"; + case CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_LEAD: + return "Combo: How much notice will we give the Combo Card"; + case CSR_PSKEY_BT_CLOCK_INIT: + return "Initial value of Bluetooth clock"; + case CSR_PSKEY_TX_MR_MOD_DELAY: + return "TX Mod delay"; + case CSR_PSKEY_RX_MR_SYNC_TIMING: + return "RX MR Sync Timing"; + case CSR_PSKEY_RX_MR_SYNC_CONFIG: + return "RX MR Sync Configuration"; + case CSR_PSKEY_LC_LOST_SYNC_SLOTS: + return "Time in ms for lost sync in low power modes"; + case CSR_PSKEY_RX_MR_SAMP_CONFIG: + return "RX MR Sync Configuration"; + case CSR_PSKEY_AGC_HYST_LEVELS: + return "AGC hysteresis levels"; + case CSR_PSKEY_RX_LEVEL_LOW_SIGNAL: + return "ANA_RX_LVL at low signal strengths"; + case CSR_PSKEY_AGC_IQ_LVL_VALUES: + return "ANA_IQ_LVL values for AGC algorithmn"; + case CSR_PSKEY_MR_FTRIM_OFFSET_12DB: + return "ANA_RX_FTRIM offset when using 12 dB IF atten "; + case CSR_PSKEY_MR_FTRIM_OFFSET_6DB: + return "ANA_RX_FTRIM offset when using 6 dB IF atten "; + case CSR_PSKEY_NO_CAL_ON_BOOT: + return "Do not calibrate radio on boot"; + case CSR_PSKEY_RSSI_HI_TARGET: + return "RSSI high target"; + case CSR_PSKEY_PREFERRED_MIN_ATTENUATION: + return "Preferred minimum attenuator setting"; + case CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_OVERRIDE: + return "Combo: Treat all packets as high priority"; + case CSR_PSKEY_LC_MULTISLOT_HOLDOFF: + return "Time till single slot packets are used for resync"; + case CSR_PSKEY_FREE_KEY_PIGEON_HOLE: + return "Link key store bitfield"; + case CSR_PSKEY_LINK_KEY_BD_ADDR0: + return "Bluetooth address + link key 0"; + case CSR_PSKEY_LINK_KEY_BD_ADDR1: + return "Bluetooth address + link key 1"; + case CSR_PSKEY_LINK_KEY_BD_ADDR2: + return "Bluetooth address + link key 2"; + case CSR_PSKEY_LINK_KEY_BD_ADDR3: + return "Bluetooth address + link key 3"; + case CSR_PSKEY_LINK_KEY_BD_ADDR4: + return "Bluetooth address + link key 4"; + case CSR_PSKEY_LINK_KEY_BD_ADDR5: + return "Bluetooth address + link key 5"; + case CSR_PSKEY_LINK_KEY_BD_ADDR6: + return "Bluetooth address + link key 6"; + case CSR_PSKEY_LINK_KEY_BD_ADDR7: + return "Bluetooth address + link key 7"; + case CSR_PSKEY_LINK_KEY_BD_ADDR8: + return "Bluetooth address + link key 8"; + case CSR_PSKEY_LINK_KEY_BD_ADDR9: + return "Bluetooth address + link key 9"; + case CSR_PSKEY_LINK_KEY_BD_ADDR10: + return "Bluetooth address + link key 10"; + case CSR_PSKEY_LINK_KEY_BD_ADDR11: + return "Bluetooth address + link key 11"; + case CSR_PSKEY_LINK_KEY_BD_ADDR12: + return "Bluetooth address + link key 12"; + case CSR_PSKEY_LINK_KEY_BD_ADDR13: + return "Bluetooth address + link key 13"; + case CSR_PSKEY_LINK_KEY_BD_ADDR14: + return "Bluetooth address + link key 14"; + case CSR_PSKEY_LINK_KEY_BD_ADDR15: + return "Bluetooth address + link key 15"; case CSR_PSKEY_ENC_KEY_LMIN: return "Minimum encryption key length"; case CSR_PSKEY_ENC_KEY_LMAX: return "Maximum encryption key length"; case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: return "Local supported features block"; + case CSR_PSKEY_LM_USE_UNIT_KEY: + return "Allow use of unit key for authentication?"; + case CSR_PSKEY_HCI_NOP_DISABLE: + return "Disable the HCI Command_Status event on boot"; + case CSR_PSKEY_LM_MAX_EVENT_FILTERS: + return "Maximum number of event filters"; + case CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE: + return "LM sends two LMP_accepted messages in test mode"; + case CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME: + return "Maximum time we hold a device around page"; + case CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME: + return "LM period for AFH adaption"; + case CSR_PSKEY_AFH_OPTIONS: + return "Options to configure AFH"; + case CSR_PSKEY_AFH_RSSI_RUN_PERIOD: + return "AFH RSSI reading period"; + case CSR_PSKEY_AFH_REENABLE_CHANNEL_TIME: + return "AFH good channel adding time"; + case CSR_PSKEY_NO_DROP_ON_ACR_MS_FAIL: + return "Complete link if acr barge-in role switch refused"; + case CSR_PSKEY_MAX_PRIVATE_KEYS: + return "Max private link keys stored"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR0: + return "Bluetooth address + link key 0"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR1: + return "Bluetooth address + link key 1"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR2: + return "Bluetooth address + link key 2"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR3: + return "Bluetooth address + link key 3"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR4: + return "Bluetooth address + link key 4"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR5: + return "Bluetooth address + link key 5"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR6: + return "Bluetooth address + link key 6"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR7: + return "Bluetooth address + link key 7"; case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: return "Local supported commands"; + case CSR_PSKEY_LM_MAX_ABSENCE_INDEX: + return "Maximum absence index allowed"; + case CSR_PSKEY_DEVICE_NAME: + return "Local device's \"user friendly\" name"; + case CSR_PSKEY_AFH_RSSI_THRESHOLD: + return "AFH RSSI threshold"; + case CSR_PSKEY_LM_CASUAL_SCAN_INTERVAL: + return "Scan interval in slots for casual scanning"; + case CSR_PSKEY_AFH_MIN_MAP_CHANGE: + return "The minimum amount to change an AFH map by"; + case CSR_PSKEY_AFH_RSSI_LP_RUN_PERIOD: + return "AFH RSSI reading period when in low power mode"; case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: return "The HCI and LMP version reported locally"; case CSR_PSKEY_LMP_REMOTE_VERSION: return "The LMP version reported remotely"; + case CSR_PSKEY_HOLD_ERROR_MESSAGE_NUMBER: + return "Maximum number of queued HCI Hardware Error Events"; + case CSR_PSKEY_DFU_ATTRIBUTES: + return "DFU attributes"; + case CSR_PSKEY_DFU_DETACH_TO: + return "DFU detach timeout"; + case CSR_PSKEY_DFU_TRANSFER_SIZE: + return "DFU transfer size"; + case CSR_PSKEY_DFU_ENABLE: + return "DFU enable"; + case CSR_PSKEY_DFU_LIN_REG_ENABLE: + return "Linear Regulator enabled at boot in DFU mode"; + case CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_MSB: + return "DFU encryption VM application public key MSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_LSB: + return "DFU encryption VM application public key LSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_M_DASH: + return "DFU encryption VM application M dash"; + case CSR_PSKEY_DFUENC_VMAPP_PK_R2N_MSB: + return "DFU encryption VM application public key R2N MSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_R2N_LSB: + return "DFU encryption VM application public key R2N LSB"; + case CSR_PSKEY_BCSP_LM_PS_BLOCK: + return "BCSP link establishment block"; + case CSR_PSKEY_HOSTIO_FC_PS_BLOCK: + return "HCI flow control block"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO0: + return "Host transport channel 0 settings (BCSP ACK"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO1: + return "Host transport channel 1 settings (BCSP-LE"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO2: + return "Host transport channel 2 settings (BCCMD"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO3: + return "Host transport channel 3 settings (HQ"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO4: + return "Host transport channel 4 settings (DM"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO5: + return "Host transport channel 5 settings (HCI CMD/EVT"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO6: + return "Host transport channel 6 settings (HCI ACL"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO7: + return "Host transport channel 7 settings (HCI SCO"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO8: + return "Host transport channel 8 settings (L2CAP"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO9: + return "Host transport channel 9 settings (RFCOMM"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO10: + return "Host transport channel 10 settings (SDP"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO11: + return "Host transport channel 11 settings (TEST"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO12: + return "Host transport channel 12 settings (DFU"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO13: + return "Host transport channel 13 settings (VM"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO14: + return "Host transport channel 14 settings"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO15: + return "Host transport channel 15 settings"; + case CSR_PSKEY_HOSTIO_UART_RESET_TIMEOUT: + return "UART reset counter timeout"; case CSR_PSKEY_HOSTIO_USE_HCI_EXTN: return "Use hci_extn to route non-hci channels"; + case CSR_PSKEY_HOSTIO_USE_HCI_EXTN_CCFC: + return "Use command-complete flow control for hci_extn"; + case CSR_PSKEY_HOSTIO_HCI_EXTN_PAYLOAD_SIZE: + return "Maximum hci_extn payload size"; + case CSR_PSKEY_BCSP_LM_CNF_CNT_LIMIT: + return "BCSP link establishment conf message count"; case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; + case CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC: + return "PCM interface synchronisation is difficult"; + case CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD: + return "Break poll period (microseconds"; + case CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE: + return "Minimum SCO packet size sent to host over UART HCI"; + case CSR_PSKEY_HOSTIO_MAP_SCO_CODEC: + return "Map SCO over the built-in codec"; + case CSR_PSKEY_PCM_CVSD_TX_HI_FREQ_BOOST: + return "High frequency boost for PCM when transmitting CVSD"; + case CSR_PSKEY_PCM_CVSD_RX_HI_FREQ_BOOST: + return "High frequency boost for PCM when receiving CVSD"; + case CSR_PSKEY_PCM_CONFIG32: + return "PCM interface settings bitfields"; + case CSR_PSKEY_USE_OLD_BCSP_LE: + return "Use the old version of BCSP link establishment"; + case CSR_PSKEY_PCM_CVSD_USE_NEW_FILTER: + return "CVSD uses the new filter if available"; + case CSR_PSKEY_PCM_FORMAT: + return "PCM data format"; + case CSR_PSKEY_CODEC_OUT_GAIN: + return "Audio output gain when using built-in codec"; + case CSR_PSKEY_CODEC_IN_GAIN: + return "Audio input gain when using built-in codec"; + case CSR_PSKEY_CODEC_PIO: + return "PIO to enable when built-in codec is enabled"; + case CSR_PSKEY_PCM_LOW_JITTER_CONFIG: + return "PCM interface settings for low jitter master mode"; + case CSR_PSKEY_HOSTIO_SCO_PCM_THRESHOLDS: + return "Thresholds for SCO PCM buffers"; + case CSR_PSKEY_HOSTIO_SCO_HCI_THRESHOLDS: + return "Thresholds for SCO HCI buffers"; + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM_SLOT: + return "Route SCO data to specified slot in pcm frame"; case CSR_PSKEY_UART_BAUDRATE: return "UART Baud rate"; + case CSR_PSKEY_UART_CONFIG_BCSP: + return "UART configuration when using BCSP"; + case CSR_PSKEY_UART_CONFIG_H4: + return "UART configuration when using H4"; + case CSR_PSKEY_UART_CONFIG_H5: + return "UART configuration when using H5"; + case CSR_PSKEY_UART_CONFIG_USR: + return "UART configuration when under VM control"; + case CSR_PSKEY_UART_TX_CRCS: + return "Use CRCs for BCSP or H5"; + case CSR_PSKEY_UART_ACK_TIMEOUT: + return "Acknowledgement timeout for BCSP and H5"; + case CSR_PSKEY_UART_TX_MAX_ATTEMPTS: + return "Max times to send reliable BCSP or H5 message"; + case CSR_PSKEY_UART_TX_WINDOW_SIZE: + return "Transmit window size for BCSP and H5"; + case CSR_PSKEY_UART_HOST_WAKE: + return "UART host wakeup"; + case CSR_PSKEY_HOSTIO_THROTTLE_TIMEOUT: + return "Host interface performance control."; + case CSR_PSKEY_PCM_ALWAYS_ENABLE: + return "PCM port is always enable when chip is running"; + case CSR_PSKEY_UART_HOST_WAKE_SIGNAL: + return "Signal to use for uart host wakeup protocol"; + case CSR_PSKEY_UART_CONFIG_H4DS: + return "UART configuration when using H4DS"; + case CSR_PSKEY_H4DS_WAKE_DURATION: + return "How long to spend waking the host when using H4DS"; + case CSR_PSKEY_H4DS_MAXWU: + return "Maximum number of H4DS Wake-Up messages to send"; + case CSR_PSKEY_H4DS_LE_TIMER_PERIOD: + return "H4DS Link Establishment Tsync and Tconf period"; + case CSR_PSKEY_H4DS_TWU_TIMER_PERIOD: + return "H4DS Twu timer period"; + case CSR_PSKEY_H4DS_UART_IDLE_TIMER_PERIOD: + return "H4DS Tuart_idle timer period"; case CSR_PSKEY_ANA_FTRIM: return "Crystal frequency trim"; + case CSR_PSKEY_WD_TIMEOUT: + return "Watchdog timeout (microseconds"; + case CSR_PSKEY_WD_PERIOD: + return "Watchdog period (microseconds"; case CSR_PSKEY_HOST_INTERFACE: return "Host interface"; + case CSR_PSKEY_HQ_HOST_TIMEOUT: + return "HQ host command timeout"; + case CSR_PSKEY_HQ_ACTIVE: + return "Enable host query task?"; + case CSR_PSKEY_BCCMD_SECURITY_ACTIVE: + return "Enable configuration security"; case CSR_PSKEY_ANA_FREQ: return "Crystal frequency"; + case CSR_PSKEY_PIO_PROTECT_MASK: + return "Access to PIO pins"; + case CSR_PSKEY_PMALLOC_SIZES: + return "pmalloc sizes array"; + case CSR_PSKEY_UART_BAUD_RATE: + return "UART Baud rate (pre 18"; + case CSR_PSKEY_UART_CONFIG: + return "UART configuration bitfield"; + case CSR_PSKEY_STUB: + return "Stub"; + case CSR_PSKEY_TXRX_PIO_CONTROL: + return "TX and RX PIO control"; + case CSR_PSKEY_ANA_RX_LEVEL: + return "ANA_RX_LVL register initial value"; + case CSR_PSKEY_ANA_RX_FTRIM: + return "ANA_RX_FTRIM register initial value"; + case CSR_PSKEY_PSBC_DATA_VERSION: + return "Persistent store version"; + case CSR_PSKEY_PCM0_ATTENUATION: + return "Volume control on PCM channel 0"; + case CSR_PSKEY_LO_LVL_MAX: + return "Maximum value of LO level control register"; + case CSR_PSKEY_LO_ADC_AMPL_MIN: + return "Minimum value of the LO amplitude measured on the ADC"; + case CSR_PSKEY_LO_ADC_AMPL_MAX: + return "Maximum value of the LO amplitude measured on the ADC"; + case CSR_PSKEY_IQ_TRIM_CHANNEL: + return "IQ calibration channel"; + case CSR_PSKEY_IQ_TRIM_GAIN: + return "IQ calibration gain"; + case CSR_PSKEY_TX_OFFSET_HALF_MHZ: + return "Transmit offset"; + case CSR_PSKEY_GBL_MISC_ENABLES: + return "Global miscellaneous hardware enables"; + case CSR_PSKEY_UART_SLEEP_TIMEOUT: + return "Time in ms to deep sleep if nothing received"; + case CSR_PSKEY_DEEP_SLEEP_STATE: + return "Deep sleep state usage"; + case CSR_PSKEY_IQ_ENABLE_PHASE_TRIM: + return "IQ phase enable"; + case CSR_PSKEY_HCI_HANDLE_FREEZE_PERIOD: + return "Time for which HCI handle is frozen after link removal"; + case CSR_PSKEY_MAX_FROZEN_HCI_HANDLES: + return "Maximum number of frozen HCI handles"; + case CSR_PSKEY_PAGETABLE_DESTRUCTION_DELAY: + return "Delay from freezing buf handle to deleting page table"; + case CSR_PSKEY_IQ_TRIM_PIO_SETTINGS: + return "IQ PIO settings"; + case CSR_PSKEY_USE_EXTERNAL_CLOCK: + return "Device uses an external clock"; + case CSR_PSKEY_DEEP_SLEEP_WAKE_CTS: + return "Exit deep sleep on CTS line activity"; + case CSR_PSKEY_FC_HC2H_FLUSH_DELAY: + return "Delay from disconnect to flushing HC->H FC tokens"; + case CSR_PSKEY_RX_HIGHSIDE: + return "Disable the HIGHSIDE bit in ANA_CONFIG"; + case CSR_PSKEY_TX_PRE_LVL: + return "TX pre-amplifier level"; + case CSR_PSKEY_RX_SINGLE_ENDED: + return "RX single ended"; + case CSR_PSKEY_TX_FILTER_CONFIG: + return "TX filter configuration"; + case CSR_PSKEY_CLOCK_REQUEST_ENABLE: + return "External clock request enable"; + case CSR_PSKEY_RX_MIN_ATTEN: + return "Minimum attenuation allowed for receiver"; + case CSR_PSKEY_XTAL_TARGET_AMPLITUDE: + return "Crystal target amplitude"; + case CSR_PSKEY_PCM_MIN_CPU_CLOCK: + return "Minimum CPU clock speed with PCM port running"; + case CSR_PSKEY_HOST_INTERFACE_PIO_USB: + return "USB host interface selection PIO line"; + case CSR_PSKEY_CPU_IDLE_MODE: + return "CPU idle mode when radio is active"; + case CSR_PSKEY_DEEP_SLEEP_CLEAR_RTS: + return "Deep sleep clears the UART RTS line"; + case CSR_PSKEY_RF_RESONANCE_TRIM: + return "Frequency trim for IQ and LNA resonant circuits"; + case CSR_PSKEY_DEEP_SLEEP_PIO_WAKE: + return "PIO line to wake the chip from deep sleep"; + case CSR_PSKEY_DRAIN_BORE_TIMERS: + return "Energy consumption measurement settings"; + case CSR_PSKEY_DRAIN_TX_POWER_BASE: + return "Energy consumption measurement settings"; + case CSR_PSKEY_MODULE_ID: + return "Module serial number"; + case CSR_PSKEY_MODULE_DESIGN: + return "Module design ID"; + case CSR_PSKEY_MODULE_SECURITY_CODE: + return "Module security code"; + case CSR_PSKEY_VM_DISABLE: + return "VM disable"; + case CSR_PSKEY_MOD_MANUF0: + return "Module manufactuer data 0"; + case CSR_PSKEY_MOD_MANUF1: + return "Module manufactuer data 1"; + case CSR_PSKEY_MOD_MANUF2: + return "Module manufactuer data 2"; + case CSR_PSKEY_MOD_MANUF3: + return "Module manufactuer data 3"; + case CSR_PSKEY_MOD_MANUF4: + return "Module manufactuer data 4"; + case CSR_PSKEY_MOD_MANUF5: + return "Module manufactuer data 5"; + case CSR_PSKEY_MOD_MANUF6: + return "Module manufactuer data 6"; + case CSR_PSKEY_MOD_MANUF7: + return "Module manufactuer data 7"; + case CSR_PSKEY_MOD_MANUF8: + return "Module manufactuer data 8"; + case CSR_PSKEY_MOD_MANUF9: + return "Module manufactuer data 9"; + case CSR_PSKEY_DUT_VM_DISABLE: + return "VM disable when entering radiotest modes"; + case CSR_PSKEY_USR0: + return "User configuration data 0"; + case CSR_PSKEY_USR1: + return "User configuration data 1"; + case CSR_PSKEY_USR2: + return "User configuration data 2"; + case CSR_PSKEY_USR3: + return "User configuration data 3"; + case CSR_PSKEY_USR4: + return "User configuration data 4"; + case CSR_PSKEY_USR5: + return "User configuration data 5"; + case CSR_PSKEY_USR6: + return "User configuration data 6"; + case CSR_PSKEY_USR7: + return "User configuration data 7"; + case CSR_PSKEY_USR8: + return "User configuration data 8"; + case CSR_PSKEY_USR9: + return "User configuration data 9"; + case CSR_PSKEY_USR10: + return "User configuration data 10"; + case CSR_PSKEY_USR11: + return "User configuration data 11"; + case CSR_PSKEY_USR12: + return "User configuration data 12"; + case CSR_PSKEY_USR13: + return "User configuration data 13"; + case CSR_PSKEY_USR14: + return "User configuration data 14"; + case CSR_PSKEY_USR15: + return "User configuration data 15"; + case CSR_PSKEY_USR16: + return "User configuration data 16"; + case CSR_PSKEY_USR17: + return "User configuration data 17"; + case CSR_PSKEY_USR18: + return "User configuration data 18"; + case CSR_PSKEY_USR19: + return "User configuration data 19"; + case CSR_PSKEY_USR20: + return "User configuration data 20"; + case CSR_PSKEY_USR21: + return "User configuration data 21"; + case CSR_PSKEY_USR22: + return "User configuration data 22"; + case CSR_PSKEY_USR23: + return "User configuration data 23"; + case CSR_PSKEY_USR24: + return "User configuration data 24"; + case CSR_PSKEY_USR25: + return "User configuration data 25"; + case CSR_PSKEY_USR26: + return "User configuration data 26"; + case CSR_PSKEY_USR27: + return "User configuration data 27"; + case CSR_PSKEY_USR28: + return "User configuration data 28"; + case CSR_PSKEY_USR29: + return "User configuration data 29"; + case CSR_PSKEY_USR30: + return "User configuration data 30"; + case CSR_PSKEY_USR31: + return "User configuration data 31"; + case CSR_PSKEY_USR32: + return "User configuration data 32"; + case CSR_PSKEY_USR33: + return "User configuration data 33"; + case CSR_PSKEY_USR34: + return "User configuration data 34"; + case CSR_PSKEY_USR35: + return "User configuration data 35"; + case CSR_PSKEY_USR36: + return "User configuration data 36"; + case CSR_PSKEY_USR37: + return "User configuration data 37"; + case CSR_PSKEY_USR38: + return "User configuration data 38"; + case CSR_PSKEY_USR39: + return "User configuration data 39"; + case CSR_PSKEY_USR40: + return "User configuration data 40"; + case CSR_PSKEY_USR41: + return "User configuration data 41"; + case CSR_PSKEY_USR42: + return "User configuration data 42"; + case CSR_PSKEY_USR43: + return "User configuration data 43"; + case CSR_PSKEY_USR44: + return "User configuration data 44"; + case CSR_PSKEY_USR45: + return "User configuration data 45"; + case CSR_PSKEY_USR46: + return "User configuration data 46"; + case CSR_PSKEY_USR47: + return "User configuration data 47"; + case CSR_PSKEY_USR48: + return "User configuration data 48"; + case CSR_PSKEY_USR49: + return "User configuration data 49"; + case CSR_PSKEY_USB_VERSION: + return "USB specification version number"; + case CSR_PSKEY_USB_DEVICE_CLASS_CODES: + return "USB device class codes"; case CSR_PSKEY_USB_VENDOR_ID: return "USB vendor identifier"; case CSR_PSKEY_USB_PRODUCT_ID: return "USB product identifier"; + case CSR_PSKEY_USB_MANUF_STRING: + return "USB manufacturer string"; + case CSR_PSKEY_USB_PRODUCT_STRING: + return "USB product string"; + case CSR_PSKEY_USB_SERIAL_NUMBER_STRING: + return "USB serial number string"; + case CSR_PSKEY_USB_CONFIG_STRING: + return "USB configuration string"; + case CSR_PSKEY_USB_ATTRIBUTES: + return "USB attributes bitmap"; + case CSR_PSKEY_USB_MAX_POWER: + return "USB device maximum power consumption"; + case CSR_PSKEY_USB_BT_IF_CLASS_CODES: + return "USB Bluetooth interface class codes"; + case CSR_PSKEY_USB_LANGID: + return "USB language strings supported"; + case CSR_PSKEY_USB_DFU_CLASS_CODES: + return "USB DFU class codes block"; case CSR_PSKEY_USB_DFU_PRODUCT_ID: return "USB DFU product ID"; + case CSR_PSKEY_USB_PIO_DETACH: + return "USB detach/attach PIO line"; + case CSR_PSKEY_USB_PIO_WAKEUP: + return "USB wakeup PIO line"; + case CSR_PSKEY_USB_PIO_PULLUP: + return "USB D+ pullup PIO line"; + case CSR_PSKEY_USB_PIO_VBUS: + return "USB VBus detection PIO Line"; + case CSR_PSKEY_USB_PIO_WAKE_TIMEOUT: + return "Timeout for assertion of USB PIO wake signal"; + case CSR_PSKEY_USB_PIO_RESUME: + return "PIO signal used in place of bus resume"; + case CSR_PSKEY_USB_BT_SCO_IF_CLASS_CODES: + return "USB Bluetooth SCO interface class codes"; + case CSR_PSKEY_USB_SUSPEND_PIO_LEVEL: + return "USB PIO levels to set when suspended"; + case CSR_PSKEY_USB_SUSPEND_PIO_DIR: + return "USB PIO I/O directions to set when suspended"; + case CSR_PSKEY_USB_SUSPEND_PIO_MASK: + return "USB PIO lines to be set forcibly in suspend"; + case CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE: + return "The maxmimum packet size for USB endpoint 0"; + case CSR_PSKEY_USB_CONFIG: + return "USB config params for new chips (>bc2"; + case CSR_PSKEY_RADIOTEST_ATTEN_INIT: + return "Radio test initial attenuator"; + case CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME: + return "IQ first calibration period in test"; + case CSR_PSKEY_RADIOTEST_SUBSEQUENT_TRIM_TIME: + return "IQ subsequent calibration period in test"; + case CSR_PSKEY_RADIOTEST_LO_LVL_TRIM_ENABLE: + return "LO_LVL calibration enable"; + case CSR_PSKEY_RADIOTEST_DISABLE_MODULATION: + return "Disable modulation during radiotest transmissions"; + case CSR_PSKEY_RFCOMM_FCON_THRESHOLD: + return "RFCOMM aggregate flow control on threshold"; + case CSR_PSKEY_RFCOMM_FCOFF_THRESHOLD: + return "RFCOMM aggregate flow control off threshold"; + case CSR_PSKEY_IPV6_STATIC_ADDR: + return "Static IPv6 address"; + case CSR_PSKEY_IPV4_STATIC_ADDR: + return "Static IPv4 address"; + case CSR_PSKEY_IPV6_STATIC_PREFIX_LEN: + return "Static IPv6 prefix length"; + case CSR_PSKEY_IPV6_STATIC_ROUTER_ADDR: + return "Static IPv6 router address"; + case CSR_PSKEY_IPV4_STATIC_SUBNET_MASK: + return "Static IPv4 subnet mask"; + case CSR_PSKEY_IPV4_STATIC_ROUTER_ADDR: + return "Static IPv4 router address"; + case CSR_PSKEY_MDNS_NAME: + return "Multicast DNS name"; + case CSR_PSKEY_FIXED_PIN: + return "Fixed PIN"; + case CSR_PSKEY_MDNS_PORT: + return "Multicast DNS port"; + case CSR_PSKEY_MDNS_TTL: + return "Multicast DNS TTL"; + case CSR_PSKEY_MDNS_IPV4_ADDR: + return "Multicast DNS IPv4 address"; + case CSR_PSKEY_ARP_CACHE_TIMEOUT: + return "ARP cache timeout"; + case CSR_PSKEY_HFP_POWER_TABLE: + return "HFP power table"; + case CSR_PSKEY_DRAIN_BORE_TIMER_COUNTERS: + return "Energy consumption estimation timer counters"; + case CSR_PSKEY_DRAIN_BORE_COUNTERS: + return "Energy consumption estimation counters"; + case CSR_PSKEY_LOOP_FILTER_TRIM: + return "Trim value to optimise loop filter"; + case CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK: + return "Energy consumption estimation current peak"; + case CSR_PSKEY_FORCE_16MHZ_REF_PIO: + return "PIO line to force 16 MHz reference to be assumed"; + case CSR_PSKEY_CDMA_LO_REF_LIMITS: + return "Local oscillator frequency reference limits for CDMA"; + case CSR_PSKEY_CDMA_LO_ERROR_LIMITS: + return "Local oscillator frequency error limits for CDMA"; + case CSR_PSKEY_CLOCK_STARTUP_DELAY: + return "Clock startup delay in milliseconds"; + case CSR_PSKEY_DEEP_SLEEP_CORRECTION_FACTOR: + return "Deep sleep clock correction factor"; + case CSR_PSKEY_TEMPERATURE_CALIBRATION: + return "Temperature in deg C for a given internal setting"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA: + return "Temperature for given internal PA adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL: + return "Temperature for a given TX_PRE_LVL adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB: + return "Temperature for a given TX_BB adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_ANA_FTRIM: + return "Temperature for given crystal trim adjustment"; + case CSR_PSKEY_TEST_DELTA_OFFSET: + return "Frequency offset applied to synthesiser in test mode"; + case CSR_PSKEY_RX_DYNAMIC_LVL_OFFSET: + return "Receiver dynamic level offset depending on channel"; + case CSR_PSKEY_TEST_FORCE_OFFSET: + return "Force use of exact value in PSKEY_TEST_DELTA_OFFSET"; + case CSR_PSKEY_RF_TRAP_BAD_DIVISION_RATIOS: + return "Trap bad division ratios in radio frequency tables"; + case CSR_PSKEY_RADIOTEST_CDMA_LO_REF_LIMITS: + return "LO frequency reference limits for CDMA in radiotest"; case CSR_PSKEY_INITIAL_BOOTMODE: return "Initial device bootmode"; + case CSR_PSKEY_ONCHIP_HCI_CLIENT: + return "HCI traffic routed internally"; + case CSR_PSKEY_RX_ATTEN_BACKOFF: + return "Receiver attenuation back-off"; + case CSR_PSKEY_RX_ATTEN_UPDATE_RATE: + return "Receiver attenuation update rate"; + case CSR_PSKEY_SYNTH_TXRX_THRESHOLDS: + return "Local oscillator tuning voltage limits for tx and rx"; + case CSR_PSKEY_MIN_WAIT_STATES: + return "Flash wait state indicator"; + case CSR_PSKEY_RSSI_CORRECTION: + return "RSSI correction factor."; + case CSR_PSKEY_SCHED_THROTTLE_TIMEOUT: + return "Scheduler performance control."; + case CSR_PSKEY_DEEP_SLEEP_USE_EXTERNAL_CLOCK: + return "Deep sleep uses external 32 kHz clock source"; + case CSR_PSKEY_TRIM_RADIO_FILTERS: + return "Trim rx and tx radio filters if true."; + case CSR_PSKEY_TRANSMIT_OFFSET: + return "Transmit offset in units of 62.5 kHz"; + case CSR_PSKEY_USB_VM_CONTROL: + return "VM application will supply USB descriptors"; + case CSR_PSKEY_MR_ANA_RX_FTRIM: + return "Medium rate value for the ANA_RX_FTRIM register"; + case CSR_PSKEY_I2C_CONFIG: + return "I2C configuration"; + case CSR_PSKEY_MR_TX_FILTER_CONFIG: + return "TX filter configuration used for enhanced data rate"; + case CSR_PSKEY_MR_TX_CONFIG2: + return "TX filter configuration used for enhanced data rate"; + case CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET: + return "Don't reset bootmode if USB host resets"; + case CSR_PSKEY_LC_USE_THROTTLING: + return "Adjust packet selection on packet error rate"; + case CSR_PSKEY_CHARGER_TRIM: + return "Trim value for the current charger"; + case CSR_PSKEY_CLOCK_REQUEST_FEATURES: + return "Clock request is tristated if enabled"; + case CSR_PSKEY_TRANSMIT_OFFSET_CLASS1: + return "Transmit offset / 62.5 kHz for class 1 radios"; + case CSR_PSKEY_TX_AVOID_PA_CLASS1_PIO: + return "PIO line asserted in class1 operation to avoid PA"; + case CSR_PSKEY_MR_PIO_CONFIG: + return "PIO line asserted in class1 operation to avoid PA"; + case CSR_PSKEY_UART_CONFIG2: + return "The UART Sampling point"; + case CSR_PSKEY_CLASS1_IQ_LVL: + return "IQ demand level for class 1 power level"; + case CSR_PSKEY_CLASS1_TX_CONFIG2: + return "TX filter configuration used for class 1 tx power"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1: + return "Temperature for given internal PA adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1: + return "Temperature for given internal PA adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR: + return "Temperature adjustment for TX_PRE_LVL in EDR"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER: + return "Temperature for a given TX_BB in EDR header"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD: + return "Temperature for a given TX_BB in EDR payload"; + case CSR_PSKEY_RX_MR_EQ_TAPS: + return "Adjust receiver configuration for EDR"; + case CSR_PSKEY_TX_PRE_LVL_CLASS1: + return "TX pre-amplifier level in class 1 operation"; + case CSR_PSKEY_ANALOGUE_ATTENUATOR: + return "TX analogue attenuator setting"; + case CSR_PSKEY_MR_RX_FILTER_TRIM: + return "Trim for receiver used in EDR."; + case CSR_PSKEY_MR_RX_FILTER_RESPONSE: + return "Filter response for receiver used in EDR."; + case CSR_PSKEY_PIO_WAKEUP_STATE: + return "PIO deep sleep wake up state "; + case CSR_PSKEY_MR_TX_IF_ATTEN_OFF_TEMP: + return "TX IF atten off temperature when using EDR."; + case CSR_PSKEY_LO_DIV_LATCH_BYPASS: + return "Bypass latch for LO dividers"; + case CSR_PSKEY_LO_VCO_STANDBY: + return "Use standby mode for the LO VCO"; + case CSR_PSKEY_SLOW_CLOCK_FILTER_SHIFT: + return "Slow clock sampling filter constant"; + case CSR_PSKEY_SLOW_CLOCK_FILTER_DIVIDER: + return "Slow clock filter fractional threshold"; + case CSR_PSKEY_USB_ATTRIBUTES_POWER: + return "USB self powered"; + case CSR_PSKEY_USB_ATTRIBUTES_WAKEUP: + return "USB responds to wake-up"; + case CSR_PSKEY_DFU_ATTRIBUTES_MANIFESTATION_TOLERANT: + return "DFU manifestation tolerant"; + case CSR_PSKEY_DFU_ATTRIBUTES_CAN_UPLOAD: + return "DFU can upload"; + case CSR_PSKEY_DFU_ATTRIBUTES_CAN_DOWNLOAD: + return "DFU can download"; + case CSR_PSKEY_UART_CONFIG_STOP_BITS: + return "UART: stop bits"; + case CSR_PSKEY_UART_CONFIG_PARITY_BIT: + return "UART: parity bit"; + case CSR_PSKEY_UART_CONFIG_FLOW_CTRL_EN: + return "UART: hardware flow control"; + case CSR_PSKEY_UART_CONFIG_RTS_AUTO_EN: + return "UART: RTS auto-enabled"; + case CSR_PSKEY_UART_CONFIG_RTS: + return "UART: RTS asserted"; + case CSR_PSKEY_UART_CONFIG_TX_ZERO_EN: + return "UART: TX zero enable"; + case CSR_PSKEY_UART_CONFIG_NON_BCSP_EN: + return "UART: enable BCSP-specific hardware"; + case CSR_PSKEY_UART_CONFIG_RX_RATE_DELAY: + return "UART: RX rate delay"; + case CSR_PSKEY_UART_SEQ_TIMEOUT: + return "UART: BCSP ack timeout"; + case CSR_PSKEY_UART_SEQ_RETRIES: + return "UART: retry limit in sequencing layer"; + case CSR_PSKEY_UART_SEQ_WINSIZE: + return "UART: BCSP transmit window size"; + case CSR_PSKEY_UART_USE_CRC_ON_TX: + return "UART: use BCSP CRCs"; + case CSR_PSKEY_UART_HOST_INITIAL_STATE: + return "UART: initial host state"; + case CSR_PSKEY_UART_HOST_ATTENTION_SPAN: + return "UART: host attention span"; + case CSR_PSKEY_UART_HOST_WAKEUP_TIME: + return "UART: host wakeup time"; + case CSR_PSKEY_UART_HOST_WAKEUP_WAIT: + return "UART: host wakeup wait"; + case CSR_PSKEY_BCSP_LM_MODE: + return "BCSP link establishment mode"; + case CSR_PSKEY_BCSP_LM_SYNC_RETRIES: + return "BCSP link establishment sync retries"; + case CSR_PSKEY_BCSP_LM_TSHY: + return "BCSP link establishment Tshy"; + case CSR_PSKEY_UART_DFU_CONFIG_STOP_BITS: + return "DFU mode UART: stop bits"; + case CSR_PSKEY_UART_DFU_CONFIG_PARITY_BIT: + return "DFU mode UART: parity bit"; + case CSR_PSKEY_UART_DFU_CONFIG_FLOW_CTRL_EN: + return "DFU mode UART: hardware flow control"; + case CSR_PSKEY_UART_DFU_CONFIG_RTS_AUTO_EN: + return "DFU mode UART: RTS auto-enabled"; + case CSR_PSKEY_UART_DFU_CONFIG_RTS: + return "DFU mode UART: RTS asserted"; + case CSR_PSKEY_UART_DFU_CONFIG_TX_ZERO_EN: + return "DFU mode UART: TX zero enable"; + case CSR_PSKEY_UART_DFU_CONFIG_NON_BCSP_EN: + return "DFU mode UART: enable BCSP-specific hardware"; + case CSR_PSKEY_UART_DFU_CONFIG_RX_RATE_DELAY: + return "DFU mode UART: RX rate delay"; + case CSR_PSKEY_AMUX_AIO0: + return "Multiplexer for AIO 0"; + case CSR_PSKEY_AMUX_AIO1: + return "Multiplexer for AIO 1"; + case CSR_PSKEY_AMUX_AIO2: + return "Multiplexer for AIO 2"; + case CSR_PSKEY_AMUX_AIO3: + return "Multiplexer for AIO 3"; + case CSR_PSKEY_LOCAL_NAME_SIMPLIFIED: + return "Local Name (simplified"; + case CSR_PSKEY_EXTENDED_STUB: + return "Extended stub"; default: return "Unknown"; } diff --git a/tools/csr.h b/tools/csr.h index 0f9859fa..319c863e 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -69,30 +69,431 @@ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ #define CSR_VARID_PS 0x7002 /* complex */ -#define CSR_PSKEY_BDADDR 0x0001 /* uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ -#define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ -#define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* uint32 */ -#define CSR_PSKEY_DEVICE_DRIFT 0x0004 /* uint16 */ -#define CSR_PSKEY_DEVICE_JITTER 0x0005 /* uint16 */ -#define CSR_PSKEY_MAX_ACLS 0x000d /* uint16 */ -#define CSR_PSKEY_MAX_SCOS 0x000e /* uint16 */ -#define CSR_PSKEY_MAX_REMOTE_MASTERS 0x000f /* uint16 */ -#define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ -#define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ -#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 } */ -#define CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS 0x0106 /* uint16[] = { 0xffff, 0x03ff, 0xfffe, 0xffff, 0xffff, 0xffff, 0x0ff3, 0xfff8, 0x003f } */ -#define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ -#define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ -#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool (uint16) */ -#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab /* bool (uint16) */ -#define CSR_PSKEY_UART_BAUDRATE 0x01be /* uint16 */ -#define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */ -#define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* uint16 */ -#define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */ -#define CSR_PSKEY_USB_VENDOR_ID 0x02be /* uint16 */ -#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf /* uint16 */ -#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb /* uint16 */ -#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd /* int16 */ +#define CSR_PSKEY_BDADDR 0x0001 /* bdaddr / uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ +#define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ +#define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* bdcod */ +#define CSR_PSKEY_DEVICE_DRIFT 0x0004 /* uint16 */ +#define CSR_PSKEY_DEVICE_JITTER 0x0005 /* uint16 */ +#define CSR_PSKEY_MAX_ACLS 0x000d /* uint16 */ +#define CSR_PSKEY_MAX_SCOS 0x000e /* uint16 */ +#define CSR_PSKEY_MAX_REMOTE_MASTERS 0x000f /* uint16 */ +#define CSR_PSKEY_ENABLE_MASTERY_WITH_SLAVERY 0x0010 /* bool */ +#define CSR_PSKEY_H_HC_FC_MAX_ACL_PKT_LEN 0x0011 /* uint16 */ +#define CSR_PSKEY_H_HC_FC_MAX_SCO_PKT_LEN 0x0012 /* uint8 */ +#define CSR_PSKEY_H_HC_FC_MAX_ACL_PKTS 0x0013 /* uint16 */ +#define CSR_PSKEY_H_HC_FC_MAX_SCO_PKTS 0x0014 /* uint16 */ +#define CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK 0x0015 /* lc_fc_lwm */ +#define CSR_PSKEY_LC_MAX_TX_POWER 0x0017 /* int16 */ +#define CSR_PSKEY_TX_GAIN_RAMP 0x001d /* uint16 */ +#define CSR_PSKEY_LC_PEER_POWER_PERIOD 0x001f /* TIME */ +#define CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK 0x0020 /* lc_fc_lwm */ +#define CSR_PSKEY_LC_DEFAULT_TX_POWER 0x0021 /* int16 */ +#define CSR_PSKEY_LC_RSSI_GOLDEN_RANGE 0x0022 /* uint8 */ +#define CSR_PSKEY_LC_COMBO_DISABLE_PIO_MASK 0x0028 /* uint16[] */ +#define CSR_PSKEY_LC_COMBO_PRIORITY_PIO_MASK 0x0029 /* uint16[] */ +#define CSR_PSKEY_LC_COMBO_DOT11_CHANNEL_PIO_BASE 0x002a /* uint16 */ +#define CSR_PSKEY_LC_COMBO_DOT11_BLOCK_CHANNELS 0x002b /* uint16 */ +#define CSR_PSKEY_LC_MAX_TX_POWER_NO_RSSI 0x002d /* int8 */ +#define CSR_PSKEY_LC_CONNECTION_RX_WINDOW 0x002e /* uint16 */ +#define CSR_PSKEY_LC_COMBO_DOT11_TX_PROTECTION_MODE 0x0030 /* uint16 */ +#define CSR_PSKEY_LC_ENHANCED_POWER_TABLE 0x0031 /* enhanced_power_setting[] */ +#define CSR_PSKEY_LC_WIDEBAND_RSSI_CONFIG 0x0032 /* wideband_rssi_config */ +#define CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_LEAD 0x0033 /* uint16 */ +#define CSR_PSKEY_BT_CLOCK_INIT 0x0034 /* uint32 */ +#define CSR_PSKEY_TX_MR_MOD_DELAY 0x0038 /* uint8 */ +#define CSR_PSKEY_RX_MR_SYNC_TIMING 0x0039 /* uint16 */ +#define CSR_PSKEY_RX_MR_SYNC_CONFIG 0x003a /* uint16 */ +#define CSR_PSKEY_LC_LOST_SYNC_SLOTS 0x003b /* uint16 */ +#define CSR_PSKEY_RX_MR_SAMP_CONFIG 0x003c /* uint16 */ +#define CSR_PSKEY_AGC_HYST_LEVELS 0x003d /* agc_hyst_config */ +#define CSR_PSKEY_RX_LEVEL_LOW_SIGNAL 0x003e /* uint16 */ +#define CSR_PSKEY_AGC_IQ_LVL_VALUES 0x003f /* IQ_LVL_VAL[] */ +#define CSR_PSKEY_MR_FTRIM_OFFSET_12DB 0x0040 /* uint16 */ +#define CSR_PSKEY_MR_FTRIM_OFFSET_6DB 0x0041 /* uint16 */ +#define CSR_PSKEY_NO_CAL_ON_BOOT 0x0042 /* bool */ +#define CSR_PSKEY_RSSI_HI_TARGET 0x0043 /* uint8 */ +#define CSR_PSKEY_PREFERRED_MIN_ATTENUATION 0x0044 /* uint8 */ +#define CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_OVERRIDE 0x0045 /* bool */ +#define CSR_PSKEY_LC_MULTISLOT_HOLDOFF 0x0047 /* TIME */ +#define CSR_PSKEY_FREE_KEY_PIGEON_HOLE 0x00c9 /* uint16 */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR0 0x00ca /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR1 0x00cb /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR2 0x00cc /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR3 0x00cd /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR4 0x00ce /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR5 0x00cf /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR6 0x00d0 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR7 0x00d1 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR8 0x00d2 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR9 0x00d3 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR10 0x00d4 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR11 0x00d5 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR12 0x00d6 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR13 0x00d7 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR14 0x00d8 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR15 0x00d9 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ +#define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ +#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 }*/ +#define CSR_PSKEY_LM_USE_UNIT_KEY 0x00f0 /* bool */ +#define CSR_PSKEY_HCI_NOP_DISABLE 0x00f2 /* bool */ +#define CSR_PSKEY_LM_MAX_EVENT_FILTERS 0x00f4 /* uint8 */ +#define CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE 0x00f6 /* bool */ +#define CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME 0x00f7 /* uint16 */ +#define CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME 0x00f8 /* uint16 */ +#define CSR_PSKEY_AFH_OPTIONS 0x00f9 /* uint16 */ +#define CSR_PSKEY_AFH_RSSI_RUN_PERIOD 0x00fa /* uint16 */ +#define CSR_PSKEY_AFH_REENABLE_CHANNEL_TIME 0x00fb /* uint16 */ +#define CSR_PSKEY_NO_DROP_ON_ACR_MS_FAIL 0x00fc /* bool */ +#define CSR_PSKEY_MAX_PRIVATE_KEYS 0x00fd /* uint8 */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR0 0x00fe /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR1 0x00ff /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR2 0x0100 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR3 0x0101 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR4 0x0102 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR5 0x0103 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR6 0x0104 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR7 0x0105 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS 0x0106 /* uint16[] = { 0xffff, 0x03ff, 0xfffe, 0xffff, 0xffff, 0xffff, 0x0ff3, 0xfff8, 0x003f } */ +#define CSR_PSKEY_LM_MAX_ABSENCE_INDEX 0x0107 /* uint8 */ +#define CSR_PSKEY_DEVICE_NAME 0x0108 /* uint16[] */ +#define CSR_PSKEY_AFH_RSSI_THRESHOLD 0x0109 /* uint16 */ +#define CSR_PSKEY_LM_CASUAL_SCAN_INTERVAL 0x010a /* uint16 */ +#define CSR_PSKEY_AFH_MIN_MAP_CHANGE 0x010b /* uint16[] */ +#define CSR_PSKEY_AFH_RSSI_LP_RUN_PERIOD 0x010c /* uint16 */ +#define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ +#define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ +#define CSR_PSKEY_HOLD_ERROR_MESSAGE_NUMBER 0x0113 /* uint16 */ +#define CSR_PSKEY_DFU_ATTRIBUTES 0x0136 /* uint8 */ +#define CSR_PSKEY_DFU_DETACH_TO 0x0137 /* uint16 */ +#define CSR_PSKEY_DFU_TRANSFER_SIZE 0x0138 /* uint16 */ +#define CSR_PSKEY_DFU_ENABLE 0x0139 /* bool */ +#define CSR_PSKEY_DFU_LIN_REG_ENABLE 0x013a /* bool */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_MSB 0x015e /* uint16[] */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_LSB 0x015f /* uint16[] */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_M_DASH 0x0160 /* uint16 */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_R2N_MSB 0x0161 /* uint16[] */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_R2N_LSB 0x0162 /* uint16[] */ +#define CSR_PSKEY_BCSP_LM_PS_BLOCK 0x0192 /* BCSP_LM_PS_BLOCK */ +#define CSR_PSKEY_HOSTIO_FC_PS_BLOCK 0x0193 /* HOSTIO_FC_PS_BLOCK */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO0 0x0194 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO1 0x0195 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO2 0x0196 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO3 0x0197 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO4 0x0198 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO5 0x0199 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO6 0x019a /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO7 0x019b /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO8 0x019c /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO9 0x019d /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO10 0x019e /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO11 0x019f /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO12 0x01a0 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO13 0x01a1 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO14 0x01a2 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO15 0x01a3 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_UART_RESET_TIMEOUT 0x01a4 /* TIME */ +#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool */ +#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN_CCFC 0x01a6 /* bool */ +#define CSR_PSKEY_HOSTIO_HCI_EXTN_PAYLOAD_SIZE 0x01a7 /* uint16 */ +#define CSR_PSKEY_BCSP_LM_CNF_CNT_LIMIT 0x01aa /* uint16 */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab /* bool */ +#define CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC 0x01ac /* bool */ +#define CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD 0x01ad /* TIME */ +#define CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE 0x01ae /* uint16 */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_CODEC 0x01b0 /* bool */ +#define CSR_PSKEY_PCM_CVSD_TX_HI_FREQ_BOOST 0x01b1 /* uint16 */ +#define CSR_PSKEY_PCM_CVSD_RX_HI_FREQ_BOOST 0x01b2 /* uint16 */ +#define CSR_PSKEY_PCM_CONFIG32 0x01b3 /* uint32 */ +#define CSR_PSKEY_USE_OLD_BCSP_LE 0x01b4 /* uint16 */ +#define CSR_PSKEY_PCM_CVSD_USE_NEW_FILTER 0x01b5 /* bool */ +#define CSR_PSKEY_PCM_FORMAT 0x01b6 /* uint16 */ +#define CSR_PSKEY_CODEC_OUT_GAIN 0x01b7 /* uint16 */ +#define CSR_PSKEY_CODEC_IN_GAIN 0x01b8 /* uint16 */ +#define CSR_PSKEY_CODEC_PIO 0x01b9 /* uint16 */ +#define CSR_PSKEY_PCM_LOW_JITTER_CONFIG 0x01ba /* uint32 */ +#define CSR_PSKEY_HOSTIO_SCO_PCM_THRESHOLDS 0x01bb /* uint16[] */ +#define CSR_PSKEY_HOSTIO_SCO_HCI_THRESHOLDS 0x01bc /* uint16[] */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM_SLOT 0x01bd /* uint16 */ +#define CSR_PSKEY_UART_BAUDRATE 0x01be /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_BCSP 0x01bf /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_H4 0x01c0 /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_H5 0x01c1 /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_USR 0x01c2 /* uint16 */ +#define CSR_PSKEY_UART_TX_CRCS 0x01c3 /* bool */ +#define CSR_PSKEY_UART_ACK_TIMEOUT 0x01c4 /* uint16 */ +#define CSR_PSKEY_UART_TX_MAX_ATTEMPTS 0x01c5 /* uint16 */ +#define CSR_PSKEY_UART_TX_WINDOW_SIZE 0x01c6 /* uint16 */ +#define CSR_PSKEY_UART_HOST_WAKE 0x01c7 /* uint16[] */ +#define CSR_PSKEY_HOSTIO_THROTTLE_TIMEOUT 0x01c8 /* TIME */ +#define CSR_PSKEY_PCM_ALWAYS_ENABLE 0x01c9 /* bool */ +#define CSR_PSKEY_UART_HOST_WAKE_SIGNAL 0x01ca /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_H4DS 0x01cb /* uint16 */ +#define CSR_PSKEY_H4DS_WAKE_DURATION 0x01cc /* uint16 */ +#define CSR_PSKEY_H4DS_MAXWU 0x01cd /* uint16 */ +#define CSR_PSKEY_H4DS_LE_TIMER_PERIOD 0x01cf /* uint16 */ +#define CSR_PSKEY_H4DS_TWU_TIMER_PERIOD 0x01d0 /* uint16 */ +#define CSR_PSKEY_H4DS_UART_IDLE_TIMER_PERIOD 0x01d1 /* uint16 */ +#define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */ +#define CSR_PSKEY_WD_TIMEOUT 0x01f7 /* TIME */ +#define CSR_PSKEY_WD_PERIOD 0x01f8 /* TIME */ +#define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* phys_bus */ +#define CSR_PSKEY_HQ_HOST_TIMEOUT 0x01fb /* TIME */ +#define CSR_PSKEY_HQ_ACTIVE 0x01fc /* bool */ +#define CSR_PSKEY_BCCMD_SECURITY_ACTIVE 0x01fd /* bool */ +#define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */ +#define CSR_PSKEY_PIO_PROTECT_MASK 0x0202 /* uint16 */ +#define CSR_PSKEY_PMALLOC_SIZES 0x0203 /* uint16[] */ +#define CSR_PSKEY_UART_BAUD_RATE 0x0204 /* uint16 */ +#define CSR_PSKEY_UART_CONFIG 0x0205 /* uint16 */ +#define CSR_PSKEY_STUB 0x0207 /* uint16 */ +#define CSR_PSKEY_TXRX_PIO_CONTROL 0x0209 /* uint16 */ +#define CSR_PSKEY_ANA_RX_LEVEL 0x020b /* uint16 */ +#define CSR_PSKEY_ANA_RX_FTRIM 0x020c /* uint16 */ +#define CSR_PSKEY_PSBC_DATA_VERSION 0x020d /* uint16 */ +#define CSR_PSKEY_PCM0_ATTENUATION 0x020f /* uint16 */ +#define CSR_PSKEY_LO_LVL_MAX 0x0211 /* uint16 */ +#define CSR_PSKEY_LO_ADC_AMPL_MIN 0x0212 /* uint16 */ +#define CSR_PSKEY_LO_ADC_AMPL_MAX 0x0213 /* uint16 */ +#define CSR_PSKEY_IQ_TRIM_CHANNEL 0x0214 /* uint16 */ +#define CSR_PSKEY_IQ_TRIM_GAIN 0x0215 /* uint16 */ +#define CSR_PSKEY_TX_OFFSET_HALF_MHZ 0x0217 /* int16 */ +#define CSR_PSKEY_GBL_MISC_ENABLES 0x0221 /* uint16 */ +#define CSR_PSKEY_UART_SLEEP_TIMEOUT 0x0222 /* uint16 */ +#define CSR_PSKEY_DEEP_SLEEP_STATE 0x0229 /* deep_sleep_state */ +#define CSR_PSKEY_IQ_ENABLE_PHASE_TRIM 0x022d /* bool */ +#define CSR_PSKEY_HCI_HANDLE_FREEZE_PERIOD 0x0237 /* TIME */ +#define CSR_PSKEY_MAX_FROZEN_HCI_HANDLES 0x0238 /* uint16 */ +#define CSR_PSKEY_PAGETABLE_DESTRUCTION_DELAY 0x0239 /* TIME */ +#define CSR_PSKEY_IQ_TRIM_PIO_SETTINGS 0x023a /* uint8 */ +#define CSR_PSKEY_USE_EXTERNAL_CLOCK 0x023b /* bool */ +#define CSR_PSKEY_DEEP_SLEEP_WAKE_CTS 0x023c /* uint16 */ +#define CSR_PSKEY_FC_HC2H_FLUSH_DELAY 0x023d /* TIME */ +#define CSR_PSKEY_RX_HIGHSIDE 0x023e /* bool */ +#define CSR_PSKEY_TX_PRE_LVL 0x0240 /* uint8 */ +#define CSR_PSKEY_RX_SINGLE_ENDED 0x0242 /* bool */ +#define CSR_PSKEY_TX_FILTER_CONFIG 0x0243 /* uint32 */ +#define CSR_PSKEY_CLOCK_REQUEST_ENABLE 0x0246 /* uint16 */ +#define CSR_PSKEY_RX_MIN_ATTEN 0x0249 /* uint16 */ +#define CSR_PSKEY_XTAL_TARGET_AMPLITUDE 0x024b /* uint8 */ +#define CSR_PSKEY_PCM_MIN_CPU_CLOCK 0x024d /* uint16 */ +#define CSR_PSKEY_HOST_INTERFACE_PIO_USB 0x0250 /* uint16 */ +#define CSR_PSKEY_CPU_IDLE_MODE 0x0251 /* cpu_idle_mode */ +#define CSR_PSKEY_DEEP_SLEEP_CLEAR_RTS 0x0252 /* bool */ +#define CSR_PSKEY_RF_RESONANCE_TRIM 0x0254 /* uint16 */ +#define CSR_PSKEY_DEEP_SLEEP_PIO_WAKE 0x0255 /* uint16 */ +#define CSR_PSKEY_DRAIN_BORE_TIMERS 0x0256 /* uint32[] */ +#define CSR_PSKEY_DRAIN_TX_POWER_BASE 0x0257 /* uint16 */ +#define CSR_PSKEY_MODULE_ID 0x0259 /* uint32 */ +#define CSR_PSKEY_MODULE_DESIGN 0x025a /* uint16 */ +#define CSR_PSKEY_MODULE_SECURITY_CODE 0x025c /* uint16[] */ +#define CSR_PSKEY_VM_DISABLE 0x025d /* bool */ +#define CSR_PSKEY_MOD_MANUF0 0x025e /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF1 0x025f /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF2 0x0260 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF3 0x0261 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF4 0x0262 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF5 0x0263 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF6 0x0264 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF7 0x0265 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF8 0x0266 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF9 0x0267 /* uint16[] */ +#define CSR_PSKEY_DUT_VM_DISABLE 0x0268 /* bool */ +#define CSR_PSKEY_USR0 0x028a /* uint16[] */ +#define CSR_PSKEY_USR1 0x028b /* uint16[] */ +#define CSR_PSKEY_USR2 0x028c /* uint16[] */ +#define CSR_PSKEY_USR3 0x028d /* uint16[] */ +#define CSR_PSKEY_USR4 0x028e /* uint16[] */ +#define CSR_PSKEY_USR5 0x028f /* uint16[] */ +#define CSR_PSKEY_USR6 0x0290 /* uint16[] */ +#define CSR_PSKEY_USR7 0x0291 /* uint16[] */ +#define CSR_PSKEY_USR8 0x0292 /* uint16[] */ +#define CSR_PSKEY_USR9 0x0293 /* uint16[] */ +#define CSR_PSKEY_USR10 0x0294 /* uint16[] */ +#define CSR_PSKEY_USR11 0x0295 /* uint16[] */ +#define CSR_PSKEY_USR12 0x0296 /* uint16[] */ +#define CSR_PSKEY_USR13 0x0297 /* uint16[] */ +#define CSR_PSKEY_USR14 0x0298 /* uint16[] */ +#define CSR_PSKEY_USR15 0x0299 /* uint16[] */ +#define CSR_PSKEY_USR16 0x029a /* uint16[] */ +#define CSR_PSKEY_USR17 0x029b /* uint16[] */ +#define CSR_PSKEY_USR18 0x029c /* uint16[] */ +#define CSR_PSKEY_USR19 0x029d /* uint16[] */ +#define CSR_PSKEY_USR20 0x029e /* uint16[] */ +#define CSR_PSKEY_USR21 0x029f /* uint16[] */ +#define CSR_PSKEY_USR22 0x02a0 /* uint16[] */ +#define CSR_PSKEY_USR23 0x02a1 /* uint16[] */ +#define CSR_PSKEY_USR24 0x02a2 /* uint16[] */ +#define CSR_PSKEY_USR25 0x02a3 /* uint16[] */ +#define CSR_PSKEY_USR26 0x02a4 /* uint16[] */ +#define CSR_PSKEY_USR27 0x02a5 /* uint16[] */ +#define CSR_PSKEY_USR28 0x02a6 /* uint16[] */ +#define CSR_PSKEY_USR29 0x02a7 /* uint16[] */ +#define CSR_PSKEY_USR30 0x02a8 /* uint16[] */ +#define CSR_PSKEY_USR31 0x02a9 /* uint16[] */ +#define CSR_PSKEY_USR32 0x02aa /* uint16[] */ +#define CSR_PSKEY_USR33 0x02ab /* uint16[] */ +#define CSR_PSKEY_USR34 0x02ac /* uint16[] */ +#define CSR_PSKEY_USR35 0x02ad /* uint16[] */ +#define CSR_PSKEY_USR36 0x02ae /* uint16[] */ +#define CSR_PSKEY_USR37 0x02af /* uint16[] */ +#define CSR_PSKEY_USR38 0x02b0 /* uint16[] */ +#define CSR_PSKEY_USR39 0x02b1 /* uint16[] */ +#define CSR_PSKEY_USR40 0x02b2 /* uint16[] */ +#define CSR_PSKEY_USR41 0x02b3 /* uint16[] */ +#define CSR_PSKEY_USR42 0x02b4 /* uint16[] */ +#define CSR_PSKEY_USR43 0x02b5 /* uint16[] */ +#define CSR_PSKEY_USR44 0x02b6 /* uint16[] */ +#define CSR_PSKEY_USR45 0x02b7 /* uint16[] */ +#define CSR_PSKEY_USR46 0x02b8 /* uint16[] */ +#define CSR_PSKEY_USR47 0x02b9 /* uint16[] */ +#define CSR_PSKEY_USR48 0x02ba /* uint16[] */ +#define CSR_PSKEY_USR49 0x02bb /* uint16[] */ +#define CSR_PSKEY_USB_VERSION 0x02bc /* uint16 */ +#define CSR_PSKEY_USB_DEVICE_CLASS_CODES 0x02bd /* usbclass */ +#define CSR_PSKEY_USB_VENDOR_ID 0x02be /* uint16 */ +#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf /* uint16 */ +#define CSR_PSKEY_USB_MANUF_STRING 0x02c1 /* unicodestring */ +#define CSR_PSKEY_USB_PRODUCT_STRING 0x02c2 /* unicodestring */ +#define CSR_PSKEY_USB_SERIAL_NUMBER_STRING 0x02c3 /* unicodestring */ +#define CSR_PSKEY_USB_CONFIG_STRING 0x02c4 /* unicodestring */ +#define CSR_PSKEY_USB_ATTRIBUTES 0x02c5 /* uint8 */ +#define CSR_PSKEY_USB_MAX_POWER 0x02c6 /* uint16 */ +#define CSR_PSKEY_USB_BT_IF_CLASS_CODES 0x02c7 /* usbclass */ +#define CSR_PSKEY_USB_LANGID 0x02c9 /* uint16 */ +#define CSR_PSKEY_USB_DFU_CLASS_CODES 0x02ca /* usbclass */ +#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb /* uint16 */ +#define CSR_PSKEY_USB_PIO_DETACH 0x02ce /* uint16 */ +#define CSR_PSKEY_USB_PIO_WAKEUP 0x02cf /* uint16 */ +#define CSR_PSKEY_USB_PIO_PULLUP 0x02d0 /* uint16 */ +#define CSR_PSKEY_USB_PIO_VBUS 0x02d1 /* uint16 */ +#define CSR_PSKEY_USB_PIO_WAKE_TIMEOUT 0x02d2 /* uint16 */ +#define CSR_PSKEY_USB_PIO_RESUME 0x02d3 /* uint16 */ +#define CSR_PSKEY_USB_BT_SCO_IF_CLASS_CODES 0x02d4 /* usbclass */ +#define CSR_PSKEY_USB_SUSPEND_PIO_LEVEL 0x02d5 /* uint16 */ +#define CSR_PSKEY_USB_SUSPEND_PIO_DIR 0x02d6 /* uint16 */ +#define CSR_PSKEY_USB_SUSPEND_PIO_MASK 0x02d7 /* uint16 */ +#define CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE 0x02d8 /* uint8 */ +#define CSR_PSKEY_USB_CONFIG 0x02d9 /* uint16 */ +#define CSR_PSKEY_RADIOTEST_ATTEN_INIT 0x0320 /* uint16 */ +#define CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME 0x0326 /* TIME */ +#define CSR_PSKEY_RADIOTEST_SUBSEQUENT_TRIM_TIME 0x0327 /* TIME */ +#define CSR_PSKEY_RADIOTEST_LO_LVL_TRIM_ENABLE 0x0328 /* bool */ +#define CSR_PSKEY_RADIOTEST_DISABLE_MODULATION 0x032c /* bool */ +#define CSR_PSKEY_RFCOMM_FCON_THRESHOLD 0x0352 /* uint16 */ +#define CSR_PSKEY_RFCOMM_FCOFF_THRESHOLD 0x0353 /* uint16 */ +#define CSR_PSKEY_IPV6_STATIC_ADDR 0x0354 /* uint16[] */ +#define CSR_PSKEY_IPV4_STATIC_ADDR 0x0355 /* uint32 */ +#define CSR_PSKEY_IPV6_STATIC_PREFIX_LEN 0x0356 /* uint8 */ +#define CSR_PSKEY_IPV6_STATIC_ROUTER_ADDR 0x0357 /* uint16[] */ +#define CSR_PSKEY_IPV4_STATIC_SUBNET_MASK 0x0358 /* uint32 */ +#define CSR_PSKEY_IPV4_STATIC_ROUTER_ADDR 0x0359 /* uint32 */ +#define CSR_PSKEY_MDNS_NAME 0x035a /* char[] */ +#define CSR_PSKEY_FIXED_PIN 0x035b /* uint8[] */ +#define CSR_PSKEY_MDNS_PORT 0x035c /* uint16 */ +#define CSR_PSKEY_MDNS_TTL 0x035d /* uint8 */ +#define CSR_PSKEY_MDNS_IPV4_ADDR 0x035e /* uint32 */ +#define CSR_PSKEY_ARP_CACHE_TIMEOUT 0x035f /* uint16 */ +#define CSR_PSKEY_HFP_POWER_TABLE 0x0360 /* uint16[] */ +#define CSR_PSKEY_DRAIN_BORE_TIMER_COUNTERS 0x03e7 /* uint32[] */ +#define CSR_PSKEY_DRAIN_BORE_COUNTERS 0x03e6 /* uint32[] */ +#define CSR_PSKEY_LOOP_FILTER_TRIM 0x03e4 /* uint16 */ +#define CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK 0x03e3 /* uint32[] */ +#define CSR_PSKEY_FORCE_16MHZ_REF_PIO 0x03e1 /* uint16 */ +#define CSR_PSKEY_CDMA_LO_REF_LIMITS 0x03df /* uint16 */ +#define CSR_PSKEY_CDMA_LO_ERROR_LIMITS 0x03de /* uint16 */ +#define CSR_PSKEY_CLOCK_STARTUP_DELAY 0x03dd /* uint16 */ +#define CSR_PSKEY_DEEP_SLEEP_CORRECTION_FACTOR 0x03dc /* int16 */ +#define CSR_PSKEY_TEMPERATURE_CALIBRATION 0x03db /* temperature_calibration */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA 0x03da /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL 0x03d9 /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB 0x03d8 /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_ANA_FTRIM 0x03d7 /* temperature_calibration[] */ +#define CSR_PSKEY_TEST_DELTA_OFFSET 0x03d6 /* uint16 */ +#define CSR_PSKEY_RX_DYNAMIC_LVL_OFFSET 0x03d4 /* uint16 */ +#define CSR_PSKEY_TEST_FORCE_OFFSET 0x03d3 /* bool */ +#define CSR_PSKEY_RF_TRAP_BAD_DIVISION_RATIOS 0x03cf /* uint16 */ +#define CSR_PSKEY_RADIOTEST_CDMA_LO_REF_LIMITS 0x03ce /* uint16 */ +#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd /* int16 */ +#define CSR_PSKEY_ONCHIP_HCI_CLIENT 0x03cc /* bool */ +#define CSR_PSKEY_RX_ATTEN_BACKOFF 0x03ca /* uint16 */ +#define CSR_PSKEY_RX_ATTEN_UPDATE_RATE 0x03c9 /* uint16 */ +#define CSR_PSKEY_SYNTH_TXRX_THRESHOLDS 0x03c7 /* uint16 */ +#define CSR_PSKEY_MIN_WAIT_STATES 0x03c6 /* uint16 */ +#define CSR_PSKEY_RSSI_CORRECTION 0x03c5 /* int8 */ +#define CSR_PSKEY_SCHED_THROTTLE_TIMEOUT 0x03c4 /* TIME */ +#define CSR_PSKEY_DEEP_SLEEP_USE_EXTERNAL_CLOCK 0x03c3 /* bool */ +#define CSR_PSKEY_TRIM_RADIO_FILTERS 0x03c2 /* uint16 */ +#define CSR_PSKEY_TRANSMIT_OFFSET 0x03c1 /* int16 */ +#define CSR_PSKEY_USB_VM_CONTROL 0x03c0 /* bool */ +#define CSR_PSKEY_MR_ANA_RX_FTRIM 0x03bf /* uint16 */ +#define CSR_PSKEY_I2C_CONFIG 0x03be /* uint16 */ +#define CSR_PSKEY_MR_TX_FILTER_CONFIG 0x03bb /* uint32 */ +#define CSR_PSKEY_MR_TX_CONFIG2 0x03ba /* uint16 */ +#define CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET 0x03b9 /* bool */ +#define CSR_PSKEY_LC_USE_THROTTLING 0x03b8 /* bool */ +#define CSR_PSKEY_CHARGER_TRIM 0x03b7 /* uint16 */ +#define CSR_PSKEY_CLOCK_REQUEST_FEATURES 0x03b6 /* uint16 */ +#define CSR_PSKEY_TRANSMIT_OFFSET_CLASS1 0x03b4 /* int16 */ +#define CSR_PSKEY_TX_AVOID_PA_CLASS1_PIO 0x03b3 /* uint16 */ +#define CSR_PSKEY_MR_PIO_CONFIG 0x03b2 /* uint16 */ +#define CSR_PSKEY_UART_CONFIG2 0x03b1 /* uint8 */ +#define CSR_PSKEY_CLASS1_IQ_LVL 0x03b0 /* uint16 */ +#define CSR_PSKEY_CLASS1_TX_CONFIG2 0x03af /* uint16 */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1 0x03ae /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1 0x03ad /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR 0x03ac /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER 0x03ab /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD 0x03aa /* temperature_calibration[] */ +#define CSR_PSKEY_RX_MR_EQ_TAPS 0x03a9 /* uint16[] */ +#define CSR_PSKEY_TX_PRE_LVL_CLASS1 0x03a8 /* uint8 */ +#define CSR_PSKEY_ANALOGUE_ATTENUATOR 0x03a7 /* bool */ +#define CSR_PSKEY_MR_RX_FILTER_TRIM 0x03a6 /* uint16 */ +#define CSR_PSKEY_MR_RX_FILTER_RESPONSE 0x03a5 /* int16[] */ +#define CSR_PSKEY_PIO_WAKEUP_STATE 0x039f /* uint16 */ +#define CSR_PSKEY_MR_TX_IF_ATTEN_OFF_TEMP 0x0394 /* int16 */ +#define CSR_PSKEY_LO_DIV_LATCH_BYPASS 0x0393 /* bool */ +#define CSR_PSKEY_LO_VCO_STANDBY 0x0392 /* bool */ +#define CSR_PSKEY_SLOW_CLOCK_FILTER_SHIFT 0x0391 /* uint16 */ +#define CSR_PSKEY_SLOW_CLOCK_FILTER_DIVIDER 0x0390 /* uint16 */ +#define CSR_PSKEY_USB_ATTRIBUTES_POWER 0x03f2 /* bool */ +#define CSR_PSKEY_USB_ATTRIBUTES_WAKEUP 0x03f3 /* bool */ +#define CSR_PSKEY_DFU_ATTRIBUTES_MANIFESTATION_TOLERANT 0x03f4 /* bool */ +#define CSR_PSKEY_DFU_ATTRIBUTES_CAN_UPLOAD 0x03f5 /* bool */ +#define CSR_PSKEY_DFU_ATTRIBUTES_CAN_DOWNLOAD 0x03f6 /* bool */ +#define CSR_PSKEY_UART_CONFIG_STOP_BITS 0x03fc /* bool */ +#define CSR_PSKEY_UART_CONFIG_PARITY_BIT 0x03fd /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_FLOW_CTRL_EN 0x03fe /* bool */ +#define CSR_PSKEY_UART_CONFIG_RTS_AUTO_EN 0x03ff /* bool */ +#define CSR_PSKEY_UART_CONFIG_RTS 0x0400 /* bool */ +#define CSR_PSKEY_UART_CONFIG_TX_ZERO_EN 0x0401 /* bool */ +#define CSR_PSKEY_UART_CONFIG_NON_BCSP_EN 0x0402 /* bool */ +#define CSR_PSKEY_UART_CONFIG_RX_RATE_DELAY 0x0403 /* uint16 */ +#define CSR_PSKEY_UART_SEQ_TIMEOUT 0x0405 /* uint16 */ +#define CSR_PSKEY_UART_SEQ_RETRIES 0x0406 /* uint16 */ +#define CSR_PSKEY_UART_SEQ_WINSIZE 0x0407 /* uint16 */ +#define CSR_PSKEY_UART_USE_CRC_ON_TX 0x0408 /* bool */ +#define CSR_PSKEY_UART_HOST_INITIAL_STATE 0x0409 /* hwakeup_state */ +#define CSR_PSKEY_UART_HOST_ATTENTION_SPAN 0x040a /* uint16 */ +#define CSR_PSKEY_UART_HOST_WAKEUP_TIME 0x040b /* uint16 */ +#define CSR_PSKEY_UART_HOST_WAKEUP_WAIT 0x040c /* uint16 */ +#define CSR_PSKEY_BCSP_LM_MODE 0x0410 /* uint16 */ +#define CSR_PSKEY_BCSP_LM_SYNC_RETRIES 0x0411 /* uint16 */ +#define CSR_PSKEY_BCSP_LM_TSHY 0x0412 /* uint16 */ +#define CSR_PSKEY_UART_DFU_CONFIG_STOP_BITS 0x0417 /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_PARITY_BIT 0x0418 /* uint16 */ +#define CSR_PSKEY_UART_DFU_CONFIG_FLOW_CTRL_EN 0x0419 /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_RTS_AUTO_EN 0x041a /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_RTS 0x041b /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_TX_ZERO_EN 0x041c /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_NON_BCSP_EN 0x041d /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_RX_RATE_DELAY 0x041e /* uint16 */ +#define CSR_PSKEY_AMUX_AIO0 0x041f /* ana_amux_sel */ +#define CSR_PSKEY_AMUX_AIO1 0x0420 /* ana_amux_sel */ +#define CSR_PSKEY_AMUX_AIO2 0x0421 /* ana_amux_sel */ +#define CSR_PSKEY_AMUX_AIO3 0x0422 /* ana_amux_sel */ +#define CSR_PSKEY_LOCAL_NAME_SIMPLIFIED 0x0423 /* local_name_complete */ +#define CSR_PSKEY_EXTENDED_STUB 0x2001 /* uint16 */ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); -- cgit From b77c88f001624ea277b84c0521286490c0c60c46 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 01:55:04 +0000 Subject: Add build definition to string function --- tools/csr.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- tools/csr.h | 1 + 2 files changed, 112 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 556f13cb..11068298 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -351,6 +351,112 @@ static struct { { 0, } }; +char *csr_builddeftostr(uint16_t def) +{ + switch (def) { + case 0x0000: + return "NONE"; + case 0x0001: + return "CHIP_BASE_BC01"; + case 0x0002: + return "CHIP_BASE_BC02"; + case 0x0003: + return "CHIP_BC01B"; + case 0x0004: + return "CHIP_BC02_EXTERNAL"; + case 0x0005: + return "BUILD_HCI"; + case 0x0006: + return "BUILD_RFCOMM"; + case 0x0007: + return "BT_VER_1_1"; + case 0x0008: + return "TRANSPORT_ALL"; + case 0x0009: + return "TRANSPORT_BCSP"; + case 0x000a: + return "TRANSPORT_H4"; + case 0x000b: + return "TRANSPORT_USB"; + case 0x000c: + return "MAX_CRYPT_KEY_LEN_56"; + case 0x000d: + return "MAX_CRYPT_KEY_LEN_128"; + case 0x000e: + return "TRANSPORT_USER"; + case 0x000f: + return "CHIP_BC02K"; + case 0x0010: + return "TRANSPORT_NONE"; + case 0x0012: + return "REQUIRE_8MBIT"; + case 0x0013: + return "RADIOTEST"; + case 0x0014: + return "RADIOTEST_LITE"; + case 0x0015: + return "INSTALL_FLASH"; + case 0x0016: + return "INSTALL_EEPROM"; + case 0x0017: + return "INSTALL_COMBO_DOT11"; + case 0x0018: + return "LOWPOWER_TX"; + case 0x0019: + return "TRANSPORT_TWUTL"; + case 0x001a: + return "COMPILER_GCC"; + case 0x001b: + return "CHIP_BC02C"; + case 0x001c: + return "CHIP_BC02T"; + case 0x001d: + return "CHIP_BASE_BC3"; + case 0x001e: + return "CHIP_BC3N"; + case 0x001f: + return "CHIP_BC3K"; + case 0x0020: + return "INSTALL_HCI_MODULE"; + case 0x0021: + return "INSTALL_L2CAP_MODULE"; + case 0x0022: + return "INSTALL_DM_MODULE"; + case 0x0023: + return "INSTALL_SDP_MODULE"; + case 0x0024: + return "INSTALL_RFCOMM_MODULE"; + case 0x0025: + return "INSTALL_HIDIO_MODULE"; + case 0x0026: + return "INSTALL_PAN_MODULE"; + case 0x0027: + return "INSTALL_IPV4_MODULE"; + case 0x0028: + return "INSTALL_IPV6_MODULE"; + case 0x0029: + return "INSTALL_TCP_MODULE"; + case 0x002a: + return "BT_VER_1_2"; + case 0x002b: + return "INSTALL_UDP_MODULE"; + case 0x002c: + return "REQUIRE_0_WAIT_STATES"; + case 0x002d: + return "CHIP_BC3_PADDYWACK"; + case 0x002e: + return "CHIP_BC4_COYOTE"; + case 0x002f: + return "CHIP_BC4_ODDJOB"; + case 0x0030: + return "TRANSPORT_H4DS"; + case 0x0031: + return "CHIP_BASE_BC4"; + default: + return "UNKNOWN"; + } +} + char *csr_buildidtostr(uint16_t id) { static char str[12]; @@ -370,10 +476,13 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) case 0x00: return "BlueCore01a"; case 0x01: - if (rev == 0x64) + switch (rev) { + case 0x64: return "BlueCore01b (ES)"; - else + case 0x65: + default: return "BlueCore01b"; + } case 0x02: switch (rev) { case 0x89: diff --git a/tools/csr.h b/tools/csr.h index 319c863e..aead1f17 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -495,6 +495,7 @@ #define CSR_PSKEY_LOCAL_NAME_SIMPLIFIED 0x0423 /* local_name_complete */ #define CSR_PSKEY_EXTENDED_STUB 0x2001 /* uint16 */ +char *csr_builddeftostr(uint16_t def); char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); -- cgit From 7dbda16a2352e6c935c47b49ecca3336bdc2a5da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 01:55:51 +0000 Subject: Add support for reading the build definitions --- tools/bccmd.8 | 3 +++ tools/bccmd.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'tools') diff --git a/tools/bccmd.8 b/tools/bccmd.8 index a51be28e..58e8814f 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -23,6 +23,9 @@ devices. If run without the argument, a short help page will be diapla Specify a particular device to operate on. If not specified, default is the first available device. .SH COMMANDS .TP +.BI builddef +Get build definitions +.TP .BI keylen\ Get current crypt key length .TP diff --git a/tools/bccmd.c b/tools/bccmd.c index e476165e..4d32c089 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -42,6 +42,41 @@ #include "csr.h" +static int cmd_builddef(int dd, int argc, char *argv[]) +{ + uint8_t buf[8]; + uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; + int err = 0; + + printf("Build definitions:"); + + while (1) { + memset(buf, 0, sizeof(buf)); + buf[0] = def & 0xff; + buf[1] = def >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_GET_NEXT_BUILDDEF, buf, sizeof(buf)); + if (err < 0) { + errno = -err; + break; + } + + nextdef = buf[2] | (buf[3] << 8); + + if (nextdef == 0x0000) + break; + + def = nextdef; + + printf(" %s (0x%02x)", csr_builddeftostr(def), def); + } + + printf("\n"); + + return err; +} + static int cmd_keylen(int dd, int argc, char *argv[]) { uint8_t buf[8]; @@ -171,6 +206,7 @@ static struct { char *arg; char *doc; } commands[] = { + { "builddef", cmd_builddef, "", "Get build definitions" }, { "keylen", cmd_keylen, "", "Get current crypt key length" }, { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { "rand", cmd_rand, "", "Get random number" }, -- cgit From ed31ef0927bc60f9ecb24c1733aabb8540adc72b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 01:59:11 +0000 Subject: Display one build definition per line --- tools/bccmd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index 4d32c089..18d38766 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -48,7 +48,7 @@ static int cmd_builddef(int dd, int argc, char *argv[]) uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; int err = 0; - printf("Build definitions:"); + printf("Build definitions:\n"); while (1) { memset(buf, 0, sizeof(buf)); @@ -69,11 +69,9 @@ static int cmd_builddef(int dd, int argc, char *argv[]) def = nextdef; - printf(" %s (0x%02x)", csr_builddeftostr(def), def); + printf("0x%04x - %s\n", def, csr_builddeftostr(def)); } - printf("\n"); - return err; } -- cgit From 4634453164622a49ee06f530ddf8a2a5b82edfec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 02:12:46 +0000 Subject: Update build ids --- tools/csr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 11068298..0470e5b2 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -262,6 +262,7 @@ static struct { { 1586, "HCI 18.2" }, { 1591, "HCI 18.2" }, { 1592, "HCI 18.2" }, + { 1593, "HCI 18.2.1" }, { 1733, "HCI 18.3" }, { 1734, "HCI 18.3" }, { 1735, "HCI 18.3" }, @@ -282,6 +283,8 @@ static struct { { 2259, "Unified 20d" }, { 2361, "Unified 20e" }, { 2362, "Unified 20e" }, + { 2386, "Unified 21a" }, + { 2387, "Unified 21a" }, { 2423, "Unified 21a" }, { 2424, "Unified 21a" }, { 195, "Sniff 1 (2001-11-27)" }, -- cgit From 403a8b252f7e27b97b4db18fbc31173d51f407c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 09:36:44 +0000 Subject: Add PS key to value transformation routine --- tools/csr.c | 858 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 859 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 0470e5b2..765a6d90 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -1375,6 +1375,864 @@ char *csr_pskeytostr(uint16_t pskey) } } +char *csr_pskeytoval(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_BDADDR: + return "BDADDR"; + case CSR_PSKEY_COUNTRYCODE: + return "COUNTRYCODE"; + case CSR_PSKEY_CLASSOFDEVICE: + return "CLASSOFDEVICE"; + case CSR_PSKEY_DEVICE_DRIFT: + return "DEVICE_DRIFT"; + case CSR_PSKEY_DEVICE_JITTER: + return "DEVICE_JITTER"; + case CSR_PSKEY_MAX_ACLS: + return "MAX_ACLS"; + case CSR_PSKEY_MAX_SCOS: + return "MAX_SCOS"; + case CSR_PSKEY_MAX_REMOTE_MASTERS: + return "MAX_REMOTE_MASTERS"; + case CSR_PSKEY_ENABLE_MASTERY_WITH_SLAVERY: + return "ENABLE_MASTERY_WITH_SLAVERY"; + case CSR_PSKEY_H_HC_FC_MAX_ACL_PKT_LEN: + return "H_HC_FC_MAX_ACL_PKT_LEN"; + case CSR_PSKEY_H_HC_FC_MAX_SCO_PKT_LEN: + return "H_HC_FC_MAX_SCO_PKT_LEN"; + case CSR_PSKEY_H_HC_FC_MAX_ACL_PKTS: + return "H_HC_FC_MAX_ACL_PKTS"; + case CSR_PSKEY_H_HC_FC_MAX_SCO_PKTS: + return "H_HC_FC_MAX_SCO_PKTS"; + case CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK: + return "LC_FC_BUFFER_LOW_WATER_MARK"; + case CSR_PSKEY_LC_MAX_TX_POWER: + return "LC_MAX_TX_POWER"; + case CSR_PSKEY_TX_GAIN_RAMP: + return "TX_GAIN_RAMP"; + case CSR_PSKEY_LC_PEER_POWER_PERIOD: + return "LC_PEER_POWER_PERIOD"; + case CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK: + return "LC_FC_POOLS_LOW_WATER_MARK"; + case CSR_PSKEY_LC_DEFAULT_TX_POWER: + return "LC_DEFAULT_TX_POWER"; + case CSR_PSKEY_LC_RSSI_GOLDEN_RANGE: + return "LC_RSSI_GOLDEN_RANGE"; + case CSR_PSKEY_LC_COMBO_DISABLE_PIO_MASK: + return "LC_COMBO_DISABLE_PIO_MASK"; + case CSR_PSKEY_LC_COMBO_PRIORITY_PIO_MASK: + return "LC_COMBO_PRIORITY_PIO_MASK"; + case CSR_PSKEY_LC_COMBO_DOT11_CHANNEL_PIO_BASE: + return "LC_COMBO_DOT11_CHANNEL_PIO_BASE"; + case CSR_PSKEY_LC_COMBO_DOT11_BLOCK_CHANNELS: + return "LC_COMBO_DOT11_BLOCK_CHANNELS"; + case CSR_PSKEY_LC_MAX_TX_POWER_NO_RSSI: + return "LC_MAX_TX_POWER_NO_RSSI"; + case CSR_PSKEY_LC_CONNECTION_RX_WINDOW: + return "LC_CONNECTION_RX_WINDOW"; + case CSR_PSKEY_LC_COMBO_DOT11_TX_PROTECTION_MODE: + return "LC_COMBO_DOT11_TX_PROTECTION_MODE"; + case CSR_PSKEY_LC_ENHANCED_POWER_TABLE: + return "LC_ENHANCED_POWER_TABLE"; + case CSR_PSKEY_LC_WIDEBAND_RSSI_CONFIG: + return "LC_WIDEBAND_RSSI_CONFIG"; + case CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_LEAD: + return "LC_COMBO_DOT11_PRIORITY_LEAD"; + case CSR_PSKEY_BT_CLOCK_INIT: + return "BT_CLOCK_INIT"; + case CSR_PSKEY_TX_MR_MOD_DELAY: + return "TX_MR_MOD_DELAY"; + case CSR_PSKEY_RX_MR_SYNC_TIMING: + return "RX_MR_SYNC_TIMING"; + case CSR_PSKEY_RX_MR_SYNC_CONFIG: + return "RX_MR_SYNC_CONFIG"; + case CSR_PSKEY_LC_LOST_SYNC_SLOTS: + return "LC_LOST_SYNC_SLOTS"; + case CSR_PSKEY_RX_MR_SAMP_CONFIG: + return "RX_MR_SAMP_CONFIG"; + case CSR_PSKEY_AGC_HYST_LEVELS: + return "AGC_HYST_LEVELS"; + case CSR_PSKEY_RX_LEVEL_LOW_SIGNAL: + return "RX_LEVEL_LOW_SIGNAL"; + case CSR_PSKEY_AGC_IQ_LVL_VALUES: + return "AGC_IQ_LVL_VALUES"; + case CSR_PSKEY_MR_FTRIM_OFFSET_12DB: + return "MR_FTRIM_OFFSET_12DB"; + case CSR_PSKEY_MR_FTRIM_OFFSET_6DB: + return "MR_FTRIM_OFFSET_6DB"; + case CSR_PSKEY_NO_CAL_ON_BOOT: + return "NO_CAL_ON_BOOT"; + case CSR_PSKEY_RSSI_HI_TARGET: + return "RSSI_HI_TARGET"; + case CSR_PSKEY_PREFERRED_MIN_ATTENUATION: + return "PREFERRED_MIN_ATTENUATION"; + case CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_OVERRIDE: + return "LC_COMBO_DOT11_PRIORITY_OVERRIDE"; + case CSR_PSKEY_LC_MULTISLOT_HOLDOFF: + return "LC_MULTISLOT_HOLDOFF"; + case CSR_PSKEY_FREE_KEY_PIGEON_HOLE: + return "FREE_KEY_PIGEON_HOLE"; + case CSR_PSKEY_LINK_KEY_BD_ADDR0: + return "LINK_KEY_BD_ADDR0"; + case CSR_PSKEY_LINK_KEY_BD_ADDR1: + return "LINK_KEY_BD_ADDR1"; + case CSR_PSKEY_LINK_KEY_BD_ADDR2: + return "LINK_KEY_BD_ADDR2"; + case CSR_PSKEY_LINK_KEY_BD_ADDR3: + return "LINK_KEY_BD_ADDR3"; + case CSR_PSKEY_LINK_KEY_BD_ADDR4: + return "LINK_KEY_BD_ADDR4"; + case CSR_PSKEY_LINK_KEY_BD_ADDR5: + return "LINK_KEY_BD_ADDR5"; + case CSR_PSKEY_LINK_KEY_BD_ADDR6: + return "LINK_KEY_BD_ADDR6"; + case CSR_PSKEY_LINK_KEY_BD_ADDR7: + return "LINK_KEY_BD_ADDR7"; + case CSR_PSKEY_LINK_KEY_BD_ADDR8: + return "LINK_KEY_BD_ADDR8"; + case CSR_PSKEY_LINK_KEY_BD_ADDR9: + return "LINK_KEY_BD_ADDR9"; + case CSR_PSKEY_LINK_KEY_BD_ADDR10: + return "LINK_KEY_BD_ADDR10"; + case CSR_PSKEY_LINK_KEY_BD_ADDR11: + return "LINK_KEY_BD_ADDR11"; + case CSR_PSKEY_LINK_KEY_BD_ADDR12: + return "LINK_KEY_BD_ADDR12"; + case CSR_PSKEY_LINK_KEY_BD_ADDR13: + return "LINK_KEY_BD_ADDR13"; + case CSR_PSKEY_LINK_KEY_BD_ADDR14: + return "LINK_KEY_BD_ADDR14"; + case CSR_PSKEY_LINK_KEY_BD_ADDR15: + return "LINK_KEY_BD_ADDR15"; + case CSR_PSKEY_ENC_KEY_LMIN: + return "ENC_KEY_LMIN"; + case CSR_PSKEY_ENC_KEY_LMAX: + return "ENC_KEY_LMAX"; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return "LOCAL_SUPPORTED_FEATURES"; + case CSR_PSKEY_LM_USE_UNIT_KEY: + return "LM_USE_UNIT_KEY"; + case CSR_PSKEY_HCI_NOP_DISABLE: + return "HCI_NOP_DISABLE"; + case CSR_PSKEY_LM_MAX_EVENT_FILTERS: + return "LM_MAX_EVENT_FILTERS"; + case CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE: + return "LM_TEST_SEND_ACCEPTED_TWICE"; + case CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME: + return "LM_MAX_PAGE_HOLD_TIME"; + case CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME: + return "AFH_ADAPTATION_RESPONSE_TIME"; + case CSR_PSKEY_AFH_OPTIONS: + return "AFH_OPTIONS"; + case CSR_PSKEY_AFH_RSSI_RUN_PERIOD: + return "AFH_RSSI_RUN_PERIOD"; + case CSR_PSKEY_AFH_REENABLE_CHANNEL_TIME: + return "AFH_REENABLE_CHANNEL_TIME"; + case CSR_PSKEY_NO_DROP_ON_ACR_MS_FAIL: + return "NO_DROP_ON_ACR_MS_FAIL"; + case CSR_PSKEY_MAX_PRIVATE_KEYS: + return "MAX_PRIVATE_KEYS"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR0: + return "PRIVATE_LINK_KEY_BD_ADDR0"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR1: + return "PRIVATE_LINK_KEY_BD_ADDR1"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR2: + return "PRIVATE_LINK_KEY_BD_ADDR2"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR3: + return "PRIVATE_LINK_KEY_BD_ADDR3"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR4: + return "PRIVATE_LINK_KEY_BD_ADDR4"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR5: + return "PRIVATE_LINK_KEY_BD_ADDR5"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR6: + return "PRIVATE_LINK_KEY_BD_ADDR6"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR7: + return "PRIVATE_LINK_KEY_BD_ADDR7"; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return "LOCAL_SUPPORTED_COMMANDS"; + case CSR_PSKEY_LM_MAX_ABSENCE_INDEX: + return "LM_MAX_ABSENCE_INDEX"; + case CSR_PSKEY_DEVICE_NAME: + return "DEVICE_NAME"; + case CSR_PSKEY_AFH_RSSI_THRESHOLD: + return "AFH_RSSI_THRESHOLD"; + case CSR_PSKEY_LM_CASUAL_SCAN_INTERVAL: + return "LM_CASUAL_SCAN_INTERVAL"; + case CSR_PSKEY_AFH_MIN_MAP_CHANGE: + return "AFH_MIN_MAP_CHANGE"; + case CSR_PSKEY_AFH_RSSI_LP_RUN_PERIOD: + return "AFH_RSSI_LP_RUN_PERIOD"; + case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: + return "HCI_LMP_LOCAL_VERSION"; + case CSR_PSKEY_LMP_REMOTE_VERSION: + return "LMP_REMOTE_VERSION"; + case CSR_PSKEY_HOLD_ERROR_MESSAGE_NUMBER: + return "HOLD_ERROR_MESSAGE_NUMBER"; + case CSR_PSKEY_DFU_ATTRIBUTES: + return "DFU_ATTRIBUTES"; + case CSR_PSKEY_DFU_DETACH_TO: + return "DFU_DETACH_TO"; + case CSR_PSKEY_DFU_TRANSFER_SIZE: + return "DFU_TRANSFER_SIZE"; + case CSR_PSKEY_DFU_ENABLE: + return "DFU_ENABLE"; + case CSR_PSKEY_DFU_LIN_REG_ENABLE: + return "DFU_LIN_REG_ENABLE"; + case CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_MSB: + return "DFUENC_VMAPP_PK_MODULUS_MSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_LSB: + return "DFUENC_VMAPP_PK_MODULUS_LSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_M_DASH: + return "DFUENC_VMAPP_PK_M_DASH"; + case CSR_PSKEY_DFUENC_VMAPP_PK_R2N_MSB: + return "DFUENC_VMAPP_PK_R2N_MSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_R2N_LSB: + return "DFUENC_VMAPP_PK_R2N_LSB"; + case CSR_PSKEY_BCSP_LM_PS_BLOCK: + return "BCSP_LM_PS_BLOCK"; + case CSR_PSKEY_HOSTIO_FC_PS_BLOCK: + return "HOSTIO_FC_PS_BLOCK"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO0: + return "HOSTIO_PROTOCOL_INFO0"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO1: + return "HOSTIO_PROTOCOL_INFO1"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO2: + return "HOSTIO_PROTOCOL_INFO2"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO3: + return "HOSTIO_PROTOCOL_INFO3"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO4: + return "HOSTIO_PROTOCOL_INFO4"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO5: + return "HOSTIO_PROTOCOL_INFO5"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO6: + return "HOSTIO_PROTOCOL_INFO6"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO7: + return "HOSTIO_PROTOCOL_INFO7"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO8: + return "HOSTIO_PROTOCOL_INFO8"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO9: + return "HOSTIO_PROTOCOL_INFO9"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO10: + return "HOSTIO_PROTOCOL_INFO10"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO11: + return "HOSTIO_PROTOCOL_INFO11"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO12: + return "HOSTIO_PROTOCOL_INFO12"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO13: + return "HOSTIO_PROTOCOL_INFO13"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO14: + return "HOSTIO_PROTOCOL_INFO14"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO15: + return "HOSTIO_PROTOCOL_INFO15"; + case CSR_PSKEY_HOSTIO_UART_RESET_TIMEOUT: + return "HOSTIO_UART_RESET_TIMEOUT"; + case CSR_PSKEY_HOSTIO_USE_HCI_EXTN: + return "HOSTIO_USE_HCI_EXTN"; + case CSR_PSKEY_HOSTIO_USE_HCI_EXTN_CCFC: + return "HOSTIO_USE_HCI_EXTN_CCFC"; + case CSR_PSKEY_HOSTIO_HCI_EXTN_PAYLOAD_SIZE: + return "HOSTIO_HCI_EXTN_PAYLOAD_SIZE"; + case CSR_PSKEY_BCSP_LM_CNF_CNT_LIMIT: + return "BCSP_LM_CNF_CNT_LIMIT"; + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: + return "HOSTIO_MAP_SCO_PCM"; + case CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC: + return "HOSTIO_AWKWARD_PCM_SYNC"; + case CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD: + return "HOSTIO_BREAK_POLL_PERIOD"; + case CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE: + return "HOSTIO_MIN_UART_HCI_SCO_SIZE"; + case CSR_PSKEY_HOSTIO_MAP_SCO_CODEC: + return "HOSTIO_MAP_SCO_CODEC"; + case CSR_PSKEY_PCM_CVSD_TX_HI_FREQ_BOOST: + return "PCM_CVSD_TX_HI_FREQ_BOOST"; + case CSR_PSKEY_PCM_CVSD_RX_HI_FREQ_BOOST: + return "PCM_CVSD_RX_HI_FREQ_BOOST"; + case CSR_PSKEY_PCM_CONFIG32: + return "PCM_CONFIG32"; + case CSR_PSKEY_USE_OLD_BCSP_LE: + return "USE_OLD_BCSP_LE"; + case CSR_PSKEY_PCM_CVSD_USE_NEW_FILTER: + return "PCM_CVSD_USE_NEW_FILTER"; + case CSR_PSKEY_PCM_FORMAT: + return "PCM_FORMAT"; + case CSR_PSKEY_CODEC_OUT_GAIN: + return "CODEC_OUT_GAIN"; + case CSR_PSKEY_CODEC_IN_GAIN: + return "CODEC_IN_GAIN"; + case CSR_PSKEY_CODEC_PIO: + return "CODEC_PIO"; + case CSR_PSKEY_PCM_LOW_JITTER_CONFIG: + return "PCM_LOW_JITTER_CONFIG"; + case CSR_PSKEY_HOSTIO_SCO_PCM_THRESHOLDS: + return "HOSTIO_SCO_PCM_THRESHOLDS"; + case CSR_PSKEY_HOSTIO_SCO_HCI_THRESHOLDS: + return "HOSTIO_SCO_HCI_THRESHOLDS"; + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM_SLOT: + return "HOSTIO_MAP_SCO_PCM_SLOT"; + case CSR_PSKEY_UART_BAUDRATE: + return "UART_BAUDRATE"; + case CSR_PSKEY_UART_CONFIG_BCSP: + return "UART_CONFIG_BCSP"; + case CSR_PSKEY_UART_CONFIG_H4: + return "UART_CONFIG_H4"; + case CSR_PSKEY_UART_CONFIG_H5: + return "UART_CONFIG_H5"; + case CSR_PSKEY_UART_CONFIG_USR: + return "UART_CONFIG_USR"; + case CSR_PSKEY_UART_TX_CRCS: + return "UART_TX_CRCS"; + case CSR_PSKEY_UART_ACK_TIMEOUT: + return "UART_ACK_TIMEOUT"; + case CSR_PSKEY_UART_TX_MAX_ATTEMPTS: + return "UART_TX_MAX_ATTEMPTS"; + case CSR_PSKEY_UART_TX_WINDOW_SIZE: + return "UART_TX_WINDOW_SIZE"; + case CSR_PSKEY_UART_HOST_WAKE: + return "UART_HOST_WAKE"; + case CSR_PSKEY_HOSTIO_THROTTLE_TIMEOUT: + return "HOSTIO_THROTTLE_TIMEOUT"; + case CSR_PSKEY_PCM_ALWAYS_ENABLE: + return "PCM_ALWAYS_ENABLE"; + case CSR_PSKEY_UART_HOST_WAKE_SIGNAL: + return "UART_HOST_WAKE_SIGNAL"; + case CSR_PSKEY_UART_CONFIG_H4DS: + return "UART_CONFIG_H4DS"; + case CSR_PSKEY_H4DS_WAKE_DURATION: + return "H4DS_WAKE_DURATION"; + case CSR_PSKEY_H4DS_MAXWU: + return "H4DS_MAXWU"; + case CSR_PSKEY_H4DS_LE_TIMER_PERIOD: + return "H4DS_LE_TIMER_PERIOD"; + case CSR_PSKEY_H4DS_TWU_TIMER_PERIOD: + return "H4DS_TWU_TIMER_PERIOD"; + case CSR_PSKEY_H4DS_UART_IDLE_TIMER_PERIOD: + return "H4DS_UART_IDLE_TIMER_PERIOD"; + case CSR_PSKEY_ANA_FTRIM: + return "ANA_FTRIM"; + case CSR_PSKEY_WD_TIMEOUT: + return "WD_TIMEOUT"; + case CSR_PSKEY_WD_PERIOD: + return "WD_PERIOD"; + case CSR_PSKEY_HOST_INTERFACE: + return "HOST_INTERFACE"; + case CSR_PSKEY_HQ_HOST_TIMEOUT: + return "HQ_HOST_TIMEOUT"; + case CSR_PSKEY_HQ_ACTIVE: + return "HQ_ACTIVE"; + case CSR_PSKEY_BCCMD_SECURITY_ACTIVE: + return "BCCMD_SECURITY_ACTIVE"; + case CSR_PSKEY_ANA_FREQ: + return "ANA_FREQ"; + case CSR_PSKEY_PIO_PROTECT_MASK: + return "PIO_PROTECT_MASK"; + case CSR_PSKEY_PMALLOC_SIZES: + return "PMALLOC_SIZES"; + case CSR_PSKEY_UART_BAUD_RATE: + return "UART_BAUD_RATE"; + case CSR_PSKEY_UART_CONFIG: + return "UART_CONFIG"; + case CSR_PSKEY_STUB: + return "STUB"; + case CSR_PSKEY_TXRX_PIO_CONTROL: + return "TXRX_PIO_CONTROL"; + case CSR_PSKEY_ANA_RX_LEVEL: + return "ANA_RX_LEVEL"; + case CSR_PSKEY_ANA_RX_FTRIM: + return "ANA_RX_FTRIM"; + case CSR_PSKEY_PSBC_DATA_VERSION: + return "PSBC_DATA_VERSION"; + case CSR_PSKEY_PCM0_ATTENUATION: + return "PCM0_ATTENUATION"; + case CSR_PSKEY_LO_LVL_MAX: + return "LO_LVL_MAX"; + case CSR_PSKEY_LO_ADC_AMPL_MIN: + return "LO_ADC_AMPL_MIN"; + case CSR_PSKEY_LO_ADC_AMPL_MAX: + return "LO_ADC_AMPL_MAX"; + case CSR_PSKEY_IQ_TRIM_CHANNEL: + return "IQ_TRIM_CHANNEL"; + case CSR_PSKEY_IQ_TRIM_GAIN: + return "IQ_TRIM_GAIN"; + case CSR_PSKEY_TX_OFFSET_HALF_MHZ: + return "TX_OFFSET_HALF_MHZ"; + case CSR_PSKEY_GBL_MISC_ENABLES: + return "GBL_MISC_ENABLES"; + case CSR_PSKEY_UART_SLEEP_TIMEOUT: + return "UART_SLEEP_TIMEOUT"; + case CSR_PSKEY_DEEP_SLEEP_STATE: + return "DEEP_SLEEP_STATE"; + case CSR_PSKEY_IQ_ENABLE_PHASE_TRIM: + return "IQ_ENABLE_PHASE_TRIM"; + case CSR_PSKEY_HCI_HANDLE_FREEZE_PERIOD: + return "HCI_HANDLE_FREEZE_PERIOD"; + case CSR_PSKEY_MAX_FROZEN_HCI_HANDLES: + return "MAX_FROZEN_HCI_HANDLES"; + case CSR_PSKEY_PAGETABLE_DESTRUCTION_DELAY: + return "PAGETABLE_DESTRUCTION_DELAY"; + case CSR_PSKEY_IQ_TRIM_PIO_SETTINGS: + return "IQ_TRIM_PIO_SETTINGS"; + case CSR_PSKEY_USE_EXTERNAL_CLOCK: + return "USE_EXTERNAL_CLOCK"; + case CSR_PSKEY_DEEP_SLEEP_WAKE_CTS: + return "DEEP_SLEEP_WAKE_CTS"; + case CSR_PSKEY_FC_HC2H_FLUSH_DELAY: + return "FC_HC2H_FLUSH_DELAY"; + case CSR_PSKEY_RX_HIGHSIDE: + return "RX_HIGHSIDE"; + case CSR_PSKEY_TX_PRE_LVL: + return "TX_PRE_LVL"; + case CSR_PSKEY_RX_SINGLE_ENDED: + return "RX_SINGLE_ENDED"; + case CSR_PSKEY_TX_FILTER_CONFIG: + return "TX_FILTER_CONFIG"; + case CSR_PSKEY_CLOCK_REQUEST_ENABLE: + return "CLOCK_REQUEST_ENABLE"; + case CSR_PSKEY_RX_MIN_ATTEN: + return "RX_MIN_ATTEN"; + case CSR_PSKEY_XTAL_TARGET_AMPLITUDE: + return "XTAL_TARGET_AMPLITUDE"; + case CSR_PSKEY_PCM_MIN_CPU_CLOCK: + return "PCM_MIN_CPU_CLOCK"; + case CSR_PSKEY_HOST_INTERFACE_PIO_USB: + return "HOST_INTERFACE_PIO_USB"; + case CSR_PSKEY_CPU_IDLE_MODE: + return "CPU_IDLE_MODE"; + case CSR_PSKEY_DEEP_SLEEP_CLEAR_RTS: + return "DEEP_SLEEP_CLEAR_RTS"; + case CSR_PSKEY_RF_RESONANCE_TRIM: + return "RF_RESONANCE_TRIM"; + case CSR_PSKEY_DEEP_SLEEP_PIO_WAKE: + return "DEEP_SLEEP_PIO_WAKE"; + case CSR_PSKEY_DRAIN_BORE_TIMERS: + return "DRAIN_BORE_TIMERS"; + case CSR_PSKEY_DRAIN_TX_POWER_BASE: + return "DRAIN_TX_POWER_BASE"; + case CSR_PSKEY_MODULE_ID: + return "MODULE_ID"; + case CSR_PSKEY_MODULE_DESIGN: + return "MODULE_DESIGN"; + case CSR_PSKEY_MODULE_SECURITY_CODE: + return "MODULE_SECURITY_CODE"; + case CSR_PSKEY_VM_DISABLE: + return "VM_DISABLE"; + case CSR_PSKEY_MOD_MANUF0: + return "MOD_MANUF0"; + case CSR_PSKEY_MOD_MANUF1: + return "MOD_MANUF1"; + case CSR_PSKEY_MOD_MANUF2: + return "MOD_MANUF2"; + case CSR_PSKEY_MOD_MANUF3: + return "MOD_MANUF3"; + case CSR_PSKEY_MOD_MANUF4: + return "MOD_MANUF4"; + case CSR_PSKEY_MOD_MANUF5: + return "MOD_MANUF5"; + case CSR_PSKEY_MOD_MANUF6: + return "MOD_MANUF6"; + case CSR_PSKEY_MOD_MANUF7: + return "MOD_MANUF7"; + case CSR_PSKEY_MOD_MANUF8: + return "MOD_MANUF8"; + case CSR_PSKEY_MOD_MANUF9: + return "MOD_MANUF9"; + case CSR_PSKEY_DUT_VM_DISABLE: + return "DUT_VM_DISABLE"; + case CSR_PSKEY_USR0: + return "USR0"; + case CSR_PSKEY_USR1: + return "USR1"; + case CSR_PSKEY_USR2: + return "USR2"; + case CSR_PSKEY_USR3: + return "USR3"; + case CSR_PSKEY_USR4: + return "USR4"; + case CSR_PSKEY_USR5: + return "USR5"; + case CSR_PSKEY_USR6: + return "USR6"; + case CSR_PSKEY_USR7: + return "USR7"; + case CSR_PSKEY_USR8: + return "USR8"; + case CSR_PSKEY_USR9: + return "USR9"; + case CSR_PSKEY_USR10: + return "USR10"; + case CSR_PSKEY_USR11: + return "USR11"; + case CSR_PSKEY_USR12: + return "USR12"; + case CSR_PSKEY_USR13: + return "USR13"; + case CSR_PSKEY_USR14: + return "USR14"; + case CSR_PSKEY_USR15: + return "USR15"; + case CSR_PSKEY_USR16: + return "USR16"; + case CSR_PSKEY_USR17: + return "USR17"; + case CSR_PSKEY_USR18: + return "USR18"; + case CSR_PSKEY_USR19: + return "USR19"; + case CSR_PSKEY_USR20: + return "USR20"; + case CSR_PSKEY_USR21: + return "USR21"; + case CSR_PSKEY_USR22: + return "USR22"; + case CSR_PSKEY_USR23: + return "USR23"; + case CSR_PSKEY_USR24: + return "USR24"; + case CSR_PSKEY_USR25: + return "USR25"; + case CSR_PSKEY_USR26: + return "USR26"; + case CSR_PSKEY_USR27: + return "USR27"; + case CSR_PSKEY_USR28: + return "USR28"; + case CSR_PSKEY_USR29: + return "USR29"; + case CSR_PSKEY_USR30: + return "USR30"; + case CSR_PSKEY_USR31: + return "USR31"; + case CSR_PSKEY_USR32: + return "USR32"; + case CSR_PSKEY_USR33: + return "USR33"; + case CSR_PSKEY_USR34: + return "USR34"; + case CSR_PSKEY_USR35: + return "USR35"; + case CSR_PSKEY_USR36: + return "USR36"; + case CSR_PSKEY_USR37: + return "USR37"; + case CSR_PSKEY_USR38: + return "USR38"; + case CSR_PSKEY_USR39: + return "USR39"; + case CSR_PSKEY_USR40: + return "USR40"; + case CSR_PSKEY_USR41: + return "USR41"; + case CSR_PSKEY_USR42: + return "USR42"; + case CSR_PSKEY_USR43: + return "USR43"; + case CSR_PSKEY_USR44: + return "USR44"; + case CSR_PSKEY_USR45: + return "USR45"; + case CSR_PSKEY_USR46: + return "USR46"; + case CSR_PSKEY_USR47: + return "USR47"; + case CSR_PSKEY_USR48: + return "USR48"; + case CSR_PSKEY_USR49: + return "USR49"; + case CSR_PSKEY_USB_VERSION: + return "USB_VERSION"; + case CSR_PSKEY_USB_DEVICE_CLASS_CODES: + return "USB_DEVICE_CLASS_CODES"; + case CSR_PSKEY_USB_VENDOR_ID: + return "USB_VENDOR_ID"; + case CSR_PSKEY_USB_PRODUCT_ID: + return "USB_PRODUCT_ID"; + case CSR_PSKEY_USB_MANUF_STRING: + return "USB_MANUF_STRING"; + case CSR_PSKEY_USB_PRODUCT_STRING: + return "USB_PRODUCT_STRING"; + case CSR_PSKEY_USB_SERIAL_NUMBER_STRING: + return "USB_SERIAL_NUMBER_STRING"; + case CSR_PSKEY_USB_CONFIG_STRING: + return "USB_CONFIG_STRING"; + case CSR_PSKEY_USB_ATTRIBUTES: + return "USB_ATTRIBUTES"; + case CSR_PSKEY_USB_MAX_POWER: + return "USB_MAX_POWER"; + case CSR_PSKEY_USB_BT_IF_CLASS_CODES: + return "USB_BT_IF_CLASS_CODES"; + case CSR_PSKEY_USB_LANGID: + return "USB_LANGID"; + case CSR_PSKEY_USB_DFU_CLASS_CODES: + return "USB_DFU_CLASS_CODES"; + case CSR_PSKEY_USB_DFU_PRODUCT_ID: + return "USB_DFU_PRODUCT_ID"; + case CSR_PSKEY_USB_PIO_DETACH: + return "USB_PIO_DETACH"; + case CSR_PSKEY_USB_PIO_WAKEUP: + return "USB_PIO_WAKEUP"; + case CSR_PSKEY_USB_PIO_PULLUP: + return "USB_PIO_PULLUP"; + case CSR_PSKEY_USB_PIO_VBUS: + return "USB_PIO_VBUS"; + case CSR_PSKEY_USB_PIO_WAKE_TIMEOUT: + return "USB_PIO_WAKE_TIMEOUT"; + case CSR_PSKEY_USB_PIO_RESUME: + return "USB_PIO_RESUME"; + case CSR_PSKEY_USB_BT_SCO_IF_CLASS_CODES: + return "USB_BT_SCO_IF_CLASS_CODES"; + case CSR_PSKEY_USB_SUSPEND_PIO_LEVEL: + return "USB_SUSPEND_PIO_LEVEL"; + case CSR_PSKEY_USB_SUSPEND_PIO_DIR: + return "USB_SUSPEND_PIO_DIR"; + case CSR_PSKEY_USB_SUSPEND_PIO_MASK: + return "USB_SUSPEND_PIO_MASK"; + case CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE: + return "USB_ENDPOINT_0_MAX_PACKET_SIZE"; + case CSR_PSKEY_USB_CONFIG: + return "USB_CONFIG"; + case CSR_PSKEY_RADIOTEST_ATTEN_INIT: + return "RADIOTEST_ATTEN_INIT"; + case CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME: + return "RADIOTEST_FIRST_TRIM_TIME"; + case CSR_PSKEY_RADIOTEST_SUBSEQUENT_TRIM_TIME: + return "RADIOTEST_SUBSEQUENT_TRIM_TIME"; + case CSR_PSKEY_RADIOTEST_LO_LVL_TRIM_ENABLE: + return "RADIOTEST_LO_LVL_TRIM_ENABLE"; + case CSR_PSKEY_RADIOTEST_DISABLE_MODULATION: + return "RADIOTEST_DISABLE_MODULATION"; + case CSR_PSKEY_RFCOMM_FCON_THRESHOLD: + return "RFCOMM_FCON_THRESHOLD"; + case CSR_PSKEY_RFCOMM_FCOFF_THRESHOLD: + return "RFCOMM_FCOFF_THRESHOLD"; + case CSR_PSKEY_IPV6_STATIC_ADDR: + return "IPV6_STATIC_ADDR"; + case CSR_PSKEY_IPV4_STATIC_ADDR: + return "IPV4_STATIC_ADDR"; + case CSR_PSKEY_IPV6_STATIC_PREFIX_LEN: + return "IPV6_STATIC_PREFIX_LEN"; + case CSR_PSKEY_IPV6_STATIC_ROUTER_ADDR: + return "IPV6_STATIC_ROUTER_ADDR"; + case CSR_PSKEY_IPV4_STATIC_SUBNET_MASK: + return "IPV4_STATIC_SUBNET_MASK"; + case CSR_PSKEY_IPV4_STATIC_ROUTER_ADDR: + return "IPV4_STATIC_ROUTER_ADDR"; + case CSR_PSKEY_MDNS_NAME: + return "MDNS_NAME"; + case CSR_PSKEY_FIXED_PIN: + return "FIXED_PIN"; + case CSR_PSKEY_MDNS_PORT: + return "MDNS_PORT"; + case CSR_PSKEY_MDNS_TTL: + return "MDNS_TTL"; + case CSR_PSKEY_MDNS_IPV4_ADDR: + return "MDNS_IPV4_ADDR"; + case CSR_PSKEY_ARP_CACHE_TIMEOUT: + return "ARP_CACHE_TIMEOUT"; + case CSR_PSKEY_HFP_POWER_TABLE: + return "HFP_POWER_TABLE"; + case CSR_PSKEY_DRAIN_BORE_TIMER_COUNTERS: + return "DRAIN_BORE_TIMER_COUNTERS"; + case CSR_PSKEY_DRAIN_BORE_COUNTERS: + return "DRAIN_BORE_COUNTERS"; + case CSR_PSKEY_LOOP_FILTER_TRIM: + return "LOOP_FILTER_TRIM"; + case CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK: + return "DRAIN_BORE_CURRENT_PEAK"; + case CSR_PSKEY_FORCE_16MHZ_REF_PIO: + return "FORCE_16MHZ_REF_PIO"; + case CSR_PSKEY_CDMA_LO_REF_LIMITS: + return "CDMA_LO_REF_LIMITS"; + case CSR_PSKEY_CDMA_LO_ERROR_LIMITS: + return "CDMA_LO_ERROR_LIMITS"; + case CSR_PSKEY_CLOCK_STARTUP_DELAY: + return "CLOCK_STARTUP_DELAY"; + case CSR_PSKEY_DEEP_SLEEP_CORRECTION_FACTOR: + return "DEEP_SLEEP_CORRECTION_FACTOR"; + case CSR_PSKEY_TEMPERATURE_CALIBRATION: + return "TEMPERATURE_CALIBRATION"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA: + return "TEMPERATURE_VS_DELTA_INTERNAL_PA"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL: + return "TEMPERATURE_VS_DELTA_TX_PRE_LVL"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB: + return "TEMPERATURE_VS_DELTA_TX_BB"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_ANA_FTRIM: + return "TEMPERATURE_VS_DELTA_ANA_FTRIM"; + case CSR_PSKEY_TEST_DELTA_OFFSET: + return "TEST_DELTA_OFFSET"; + case CSR_PSKEY_RX_DYNAMIC_LVL_OFFSET: + return "RX_DYNAMIC_LVL_OFFSET"; + case CSR_PSKEY_TEST_FORCE_OFFSET: + return "TEST_FORCE_OFFSET"; + case CSR_PSKEY_RF_TRAP_BAD_DIVISION_RATIOS: + return "RF_TRAP_BAD_DIVISION_RATIOS"; + case CSR_PSKEY_RADIOTEST_CDMA_LO_REF_LIMITS: + return "RADIOTEST_CDMA_LO_REF_LIMITS"; + case CSR_PSKEY_INITIAL_BOOTMODE: + return "INITIAL_BOOTMODE"; + case CSR_PSKEY_ONCHIP_HCI_CLIENT: + return "ONCHIP_HCI_CLIENT"; + case CSR_PSKEY_RX_ATTEN_BACKOFF: + return "RX_ATTEN_BACKOFF"; + case CSR_PSKEY_RX_ATTEN_UPDATE_RATE: + return "RX_ATTEN_UPDATE_RATE"; + case CSR_PSKEY_SYNTH_TXRX_THRESHOLDS: + return "SYNTH_TXRX_THRESHOLDS"; + case CSR_PSKEY_MIN_WAIT_STATES: + return "MIN_WAIT_STATES"; + case CSR_PSKEY_RSSI_CORRECTION: + return "RSSI_CORRECTION"; + case CSR_PSKEY_SCHED_THROTTLE_TIMEOUT: + return "SCHED_THROTTLE_TIMEOUT"; + case CSR_PSKEY_DEEP_SLEEP_USE_EXTERNAL_CLOCK: + return "DEEP_SLEEP_USE_EXTERNAL_CLOCK"; + case CSR_PSKEY_TRIM_RADIO_FILTERS: + return "TRIM_RADIO_FILTERS"; + case CSR_PSKEY_TRANSMIT_OFFSET: + return "TRANSMIT_OFFSET"; + case CSR_PSKEY_USB_VM_CONTROL: + return "USB_VM_CONTROL"; + case CSR_PSKEY_MR_ANA_RX_FTRIM: + return "MR_ANA_RX_FTRIM"; + case CSR_PSKEY_I2C_CONFIG: + return "I2C_CONFIG"; + case CSR_PSKEY_MR_TX_FILTER_CONFIG: + return "MR_TX_FILTER_CONFIG"; + case CSR_PSKEY_MR_TX_CONFIG2: + return "MR_TX_CONFIG2"; + case CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET: + return "USB_DONT_RESET_BOOTMODE_ON_HOST_RESET"; + case CSR_PSKEY_LC_USE_THROTTLING: + return "LC_USE_THROTTLING"; + case CSR_PSKEY_CHARGER_TRIM: + return "CHARGER_TRIM"; + case CSR_PSKEY_CLOCK_REQUEST_FEATURES: + return "CLOCK_REQUEST_FEATURES"; + case CSR_PSKEY_TRANSMIT_OFFSET_CLASS1: + return "TRANSMIT_OFFSET_CLASS1"; + case CSR_PSKEY_TX_AVOID_PA_CLASS1_PIO: + return "TX_AVOID_PA_CLASS1_PIO"; + case CSR_PSKEY_MR_PIO_CONFIG: + return "MR_PIO_CONFIG"; + case CSR_PSKEY_UART_CONFIG2: + return "UART_CONFIG2"; + case CSR_PSKEY_CLASS1_IQ_LVL: + return "CLASS1_IQ_LVL"; + case CSR_PSKEY_CLASS1_TX_CONFIG2: + return "CLASS1_TX_CONFIG2"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1: + return "TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1: + return "TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR: + return "TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER: + return "TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD: + return "TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD"; + case CSR_PSKEY_RX_MR_EQ_TAPS: + return "RX_MR_EQ_TAPS"; + case CSR_PSKEY_TX_PRE_LVL_CLASS1: + return "TX_PRE_LVL_CLASS1"; + case CSR_PSKEY_ANALOGUE_ATTENUATOR: + return "ANALOGUE_ATTENUATOR"; + case CSR_PSKEY_MR_RX_FILTER_TRIM: + return "MR_RX_FILTER_TRIM"; + case CSR_PSKEY_MR_RX_FILTER_RESPONSE: + return "MR_RX_FILTER_RESPONSE"; + case CSR_PSKEY_PIO_WAKEUP_STATE: + return "PIO_WAKEUP_STATE"; + case CSR_PSKEY_MR_TX_IF_ATTEN_OFF_TEMP: + return "MR_TX_IF_ATTEN_OFF_TEMP"; + case CSR_PSKEY_LO_DIV_LATCH_BYPASS: + return "LO_DIV_LATCH_BYPASS"; + case CSR_PSKEY_LO_VCO_STANDBY: + return "LO_VCO_STANDBY"; + case CSR_PSKEY_SLOW_CLOCK_FILTER_SHIFT: + return "SLOW_CLOCK_FILTER_SHIFT"; + case CSR_PSKEY_SLOW_CLOCK_FILTER_DIVIDER: + return "SLOW_CLOCK_FILTER_DIVIDER"; + case CSR_PSKEY_USB_ATTRIBUTES_POWER: + return "USB_ATTRIBUTES_POWER"; + case CSR_PSKEY_USB_ATTRIBUTES_WAKEUP: + return "USB_ATTRIBUTES_WAKEUP"; + case CSR_PSKEY_DFU_ATTRIBUTES_MANIFESTATION_TOLERANT: + return "DFU_ATTRIBUTES_MANIFESTATION_TOLERANT"; + case CSR_PSKEY_DFU_ATTRIBUTES_CAN_UPLOAD: + return "DFU_ATTRIBUTES_CAN_UPLOAD"; + case CSR_PSKEY_DFU_ATTRIBUTES_CAN_DOWNLOAD: + return "DFU_ATTRIBUTES_CAN_DOWNLOAD"; + case CSR_PSKEY_UART_CONFIG_STOP_BITS: + return "UART_CONFIG_STOP_BITS"; + case CSR_PSKEY_UART_CONFIG_PARITY_BIT: + return "UART_CONFIG_PARITY_BIT"; + case CSR_PSKEY_UART_CONFIG_FLOW_CTRL_EN: + return "UART_CONFIG_FLOW_CTRL_EN"; + case CSR_PSKEY_UART_CONFIG_RTS_AUTO_EN: + return "UART_CONFIG_RTS_AUTO_EN"; + case CSR_PSKEY_UART_CONFIG_RTS: + return "UART_CONFIG_RTS"; + case CSR_PSKEY_UART_CONFIG_TX_ZERO_EN: + return "UART_CONFIG_TX_ZERO_EN"; + case CSR_PSKEY_UART_CONFIG_NON_BCSP_EN: + return "UART_CONFIG_NON_BCSP_EN"; + case CSR_PSKEY_UART_CONFIG_RX_RATE_DELAY: + return "UART_CONFIG_RX_RATE_DELAY"; + case CSR_PSKEY_UART_SEQ_TIMEOUT: + return "UART_SEQ_TIMEOUT"; + case CSR_PSKEY_UART_SEQ_RETRIES: + return "UART_SEQ_RETRIES"; + case CSR_PSKEY_UART_SEQ_WINSIZE: + return "UART_SEQ_WINSIZE"; + case CSR_PSKEY_UART_USE_CRC_ON_TX: + return "UART_USE_CRC_ON_TX"; + case CSR_PSKEY_UART_HOST_INITIAL_STATE: + return "UART_HOST_INITIAL_STATE"; + case CSR_PSKEY_UART_HOST_ATTENTION_SPAN: + return "UART_HOST_ATTENTION_SPAN"; + case CSR_PSKEY_UART_HOST_WAKEUP_TIME: + return "UART_HOST_WAKEUP_TIME"; + case CSR_PSKEY_UART_HOST_WAKEUP_WAIT: + return "UART_HOST_WAKEUP_WAIT"; + case CSR_PSKEY_BCSP_LM_MODE: + return "BCSP_LM_MODE"; + case CSR_PSKEY_BCSP_LM_SYNC_RETRIES: + return "BCSP_LM_SYNC_RETRIES"; + case CSR_PSKEY_BCSP_LM_TSHY: + return "BCSP_LM_TSHY"; + case CSR_PSKEY_UART_DFU_CONFIG_STOP_BITS: + return "UART_DFU_CONFIG_STOP_BITS"; + case CSR_PSKEY_UART_DFU_CONFIG_PARITY_BIT: + return "UART_DFU_CONFIG_PARITY_BIT"; + case CSR_PSKEY_UART_DFU_CONFIG_FLOW_CTRL_EN: + return "UART_DFU_CONFIG_FLOW_CTRL_EN"; + case CSR_PSKEY_UART_DFU_CONFIG_RTS_AUTO_EN: + return "UART_DFU_CONFIG_RTS_AUTO_EN"; + case CSR_PSKEY_UART_DFU_CONFIG_RTS: + return "UART_DFU_CONFIG_RTS"; + case CSR_PSKEY_UART_DFU_CONFIG_TX_ZERO_EN: + return "UART_DFU_CONFIG_TX_ZERO_EN"; + case CSR_PSKEY_UART_DFU_CONFIG_NON_BCSP_EN: + return "UART_DFU_CONFIG_NON_BCSP_EN"; + case CSR_PSKEY_UART_DFU_CONFIG_RX_RATE_DELAY: + return "UART_DFU_CONFIG_RX_RATE_DELAY"; + case CSR_PSKEY_AMUX_AIO0: + return "AMUX_AIO0"; + case CSR_PSKEY_AMUX_AIO1: + return "AMUX_AIO1"; + case CSR_PSKEY_AMUX_AIO2: + return "AMUX_AIO2"; + case CSR_PSKEY_AMUX_AIO3: + return "AMUX_AIO3"; + case CSR_PSKEY_LOCAL_NAME_SIMPLIFIED: + return "LOCAL_NAME_SIMPLIFIED"; + case CSR_PSKEY_EXTENDED_STUB: + return "EXTENDED_STUB"; + default: + return "UNKNOWN"; + } +} + int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid) { unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, diff --git a/tools/csr.h b/tools/csr.h index aead1f17..e46b90ca 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -499,6 +499,7 @@ char *csr_builddeftostr(uint16_t def); char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); +char *csr_pskeytoval(uint16_t pskey); int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); -- cgit From 0a403feb8c67b6c36c92711c6880598345ca78f2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 09:43:01 +0000 Subject: Add support for reading all available PS keys --- tools/pskey.c | 163 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 125 insertions(+), 38 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index bf044dd3..b1f6a319 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -48,8 +48,107 @@ #define CSR_TYPE_UINT16 3 #define CSR_TYPE_UINT32 4 +enum { + NONE = 0, + LIST, + READ, +}; + static int transient = 0; +static int cmd_list(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t length, seqnum = 0x0000, pskey = 0x0000; + int err; + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, sizeof(array)); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, sizeof(array)); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + + printf("0x%04x - %s (%d bytes)\n", pskey, + csr_pskeytostr(pskey), length * 2); + } + + return 0; +} + +static int cmd_read(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t length, seqnum = 0x0000, pskey = 0x0000; + char *str, val[7]; + int i, err; + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, 8); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + continue; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, + 0x0000, array, length * 2); + if (err < 0) + continue; + + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", + str ? str : val, pskey); + for (i = 0; i < length; i++) + printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf("\n"); + } + + return 0; +} + static int pskey_size(uint16_t pskey) { switch (pskey) { @@ -215,7 +314,8 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" "\tpskey [-i ] [-r] [-t] [value]\n" - "\tpskey [-i ] --list\n\n"); + "\tpskey [-i ] --list\n" + "\tpskey [-i ] --read\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -233,7 +333,8 @@ static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, { "transient", 0, 0, 't' }, - { "list", 0, 0, 'l' }, + { "list", 0, 0, 'L' }, + { "read", 0, 0, 'R' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -242,9 +343,9 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0, list = 0, reset = 0; + int i, err, dd, opt, dev = 0, reset = 0, mode = NONE; - while ((opt=getopt_long(argc, argv, "+i:rtlh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rtLRh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -262,8 +363,12 @@ int main(int argc, char *argv[]) transient = 1; break; - case 'l': - list = 1; + case 'L': + mode = LIST; + break; + + case 'R': + mode = READ; break; case 'h': @@ -277,7 +382,7 @@ int main(int argc, char *argv[]) argv += optind; optind = 0; - if (!list && argc < 1) { + if (mode == NONE && argc < 1) { usage(); exit(1); } @@ -309,42 +414,24 @@ int main(int argc, char *argv[]) exit(1); } - if (list) { - uint8_t array[8]; - uint16_t length, seqnum = 0x0000, pskey = 0x0000; - int err; - - while (1) { - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, sizeof(array)); - if (err < 0) - break; - - pskey = array[4] + (array[5] << 8); - if (pskey == 0x0000) - break; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, sizeof(array)); - if (err < 0) - continue; + if (mode > 0) { + switch (mode) { + case LIST: + err = cmd_list(dd, argc, argv); + break; - length = array[2] + (array[3] << 8); + case READ: + err = cmd_read(dd, argc, argv); + break; - printf("0x%04x - %s (%d bytes)\n", pskey, - csr_pskeytostr(pskey), length * 2); + default: + usage(); + err = -1; + break; } hci_close_dev(dd); - exit(0); + exit(err < 0 ? 1 : 0); } for (i = 0; storage[i].pskey; i++) { -- cgit From fdf8c10513c0f4d3eab0dc0c75c878825f35f979 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Oct 2005 21:51:04 +0000 Subject: Add support for the PSR file format --- tools/csr.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 5 ++ 2 files changed, 181 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 765a6d90..f02540a6 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -32,7 +32,13 @@ #include #include +#include +#include +#include +#include #include +#include +#include #include #include @@ -41,6 +47,15 @@ #include "csr.h" +struct psr_data { + uint16_t pskey; + uint8_t *value; + uint8_t size; + struct psr_data *next; +}; + +static struct psr_data *head = NULL, *tail = NULL; + static struct { uint16_t id; char *str; @@ -2523,3 +2538,164 @@ int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 4); } + +int psr_put(uint16_t pskey, uint8_t *value, uint16_t size) +{ + struct psr_data *item; + + item = malloc(sizeof(*item)); + if (!item) + return -ENOMEM; + + item->pskey = pskey; + + if (size > 0) { + item->value = malloc(size); + if (!item->value) { + free(item); + return -ENOMEM; + } + + memcpy(item->value, value, size); + item->size = size; + } else { + item->value = NULL; + item->size = 0; + } + + item->next = NULL; + + if (!head) + head = item; + else + tail->next = item; + + tail = item; + + return 0; +} + +int psr_get(uint16_t *pskey, uint8_t *value, uint16_t *size) +{ + struct psr_data *item = head; + + if (!head) + return -ENOENT; + + *pskey = item->pskey; + + if (item->value) { + if (value && item->size > 0) + memcpy(value, item->value, item->size); + free(item->value); + *size = item->size; + } else + *size = 0; + + if (head == tail) + tail = NULL; + + head = head->next; + free(item); + + return 0; +} + +static int parse_line(char *str) +{ + uint8_t array[256]; + uint16_t value, pskey, length = 0; + char *tmp, *end; + + pskey = strtol(str + 1, NULL, 16); + tmp = strstr(str, "=") + 1; + + while (1) { + value = strtol(tmp, &end, 16); + if (value == 0 && tmp == end) + break; + + array[length++] = value & 0xff; + array[length++] = value >> 8; + + tmp = end + 1; + } + + return psr_put(pskey, array, length); +} + +int psr_read(const char *filename) +{ + struct stat st; + char *str, *map, *off, *end; + int fd, err = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return fd; + + if (fstat(fd, &st) < 0) { + err = -errno; + goto close; + } + + map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { + err = -errno; + goto close; + } + + off = map; + + while (1) { + end = strpbrk(off, "\r\n"); + if (!end) + break; + + str = malloc(end - off + 1); + if (!str) + break; + + memset(str, 0, end - off + 1); + strncpy(str, off, end - off); + if (*str == '&') + parse_line(str); + + free(str); + off = end + 1; + } + + munmap(map, st.st_size); + +close: + close(fd); + + return err; +} + +int psr_print(void) +{ + uint8_t array[256]; + uint16_t pskey, length; + char *str, val[7]; + int i; + + while (1) { + if (psr_get(&pskey, array, &length) < 0) + break; + + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", + str ? str : val, pskey); + for (i = 0; i < length / 2; i++) + printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf("\n"); + } + + return 0; +} diff --git a/tools/csr.h b/tools/csr.h index e46b90ca..fe46f4b4 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -511,3 +511,8 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stor int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value); int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value); + +int psr_put(uint16_t pskey, uint8_t *value, uint16_t size); +int psr_get(uint16_t *pskey, uint8_t *value, uint16_t *size); +int psr_read(const char *filename); +int psr_print(void); -- cgit From c9d47fdc3cc13c9a581701001de8bfdec47002ab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Oct 2005 20:40:02 +0000 Subject: Add build ids for the "marcel" specific firmware --- tools/csr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index f02540a6..41677d22 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -302,6 +302,9 @@ static struct { { 2387, "Unified 21a" }, { 2423, "Unified 21a" }, { 2424, "Unified 21a" }, + { 2526, "Marcel 1 (2005-09-26)" }, + { 2543, "Marcel 2 (2005-09-28)" }, + { 2622, "Marcel 3 (2005-10-27)" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From dd3e8a6ab8938c4d8f62765e7c03a005807fbb64 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Oct 2005 22:49:49 +0000 Subject: Update security filter for Extended Inquiry Response (EIR) --- tools/hcisecfilter.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 5827f143..ce0082e9 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -69,7 +69,7 @@ int main(void) hci_set_bit(EVT_READ_REMOTE_EXT_FEATURES_COMPLETE, event_mask); hci_set_bit(EVT_SYNC_CONN_COMPLETE, event_mask); hci_set_bit(EVT_SYNC_CONN_CHANGED, event_mask); - //hci_set_bit(EVT_EXTENDED_INQUIRY_RESULT, event_mask); + hci_set_bit(EVT_EXTENDED_INQUIRY_RESULT, event_mask); printf("Event mask: { 0x%08x, 0x%08x }\n", event_mask[0], event_mask[1]); @@ -86,7 +86,7 @@ int main(void) hci_set_bit(OCF_READ_CLOCK_OFFSET, ocf_mask); hci_set_bit(OCF_READ_LMP_HANDLE, ocf_mask); - printf("OGF_LINK_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_LINK_CTL: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_LINK_POLICY */ @@ -95,7 +95,7 @@ int main(void) hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); hci_set_bit(OCF_READ_DEFAULT_LINK_POLICY, ocf_mask); - printf("OGF_LINK_POLICY: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_LINK_POLICY: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_HOST_CTL */ @@ -124,9 +124,9 @@ int main(void) hci_set_bit(OCF_READ_INQUIRY_MODE, ocf_mask); hci_set_bit(OCF_READ_PAGE_SCAN_TYPE, ocf_mask); hci_set_bit(OCF_READ_AFH_MODE, ocf_mask); - //hci_set_bit(OCF_READ_EXT_INQUIRY_RESPONSE, ocf_mask); + hci_set_bit(OCF_READ_EXT_INQUIRY_RESPONSE, ocf_mask); - printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_INFO_PARAM */ @@ -139,7 +139,7 @@ int main(void) hci_set_bit(OCF_READ_COUNTRY_CODE, ocf_mask); hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); - printf("OGF_INFO_PARAM: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_INFO_PARAM: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_STATUS_PARAM */ @@ -150,7 +150,7 @@ int main(void) hci_set_bit(OCF_READ_AFH_MAP, ocf_mask); hci_set_bit(OCF_READ_CLOCK, ocf_mask); - printf("OGF_STATUS_PARAM: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_STATUS_PARAM: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); return 0; -- cgit From b5b9479c9afc42666245261d5864f410c59a9ef2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 19:03:41 +0000 Subject: Update support for extended inquiry response --- tools/hciconfig.8 | 4 +-- tools/hciconfig.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 90 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 0547ae3a..96990b06 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -133,11 +133,11 @@ With no prints out the current inquiry mode. Otherwise, sets inquiry mode to .IR mode . .TP -.BI inqdata " [name]" +.BI inqdata " [data]" With no .IR name , prints out the current inquiry data. Otherwise, sets inquiry data to -.IR name . +.IR data . .TP .BI inqtype " [type]" With no diff --git a/tools/hciconfig.c b/tools/hciconfig.c index f85f5272..7267d564 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -434,34 +434,66 @@ static void cmd_features(int ctl, int hdev, char *opt) static void cmd_name(int ctl, int hdev, char *opt) { - int s = hci_open_dev(hdev); + int dd; - if (s < 0) { + dd = hci_open_dev(hdev); + if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } + if (opt) { - if (hci_write_local_name(s, opt, 2000) < 0) { + uint8_t fec = 0, data[240]; + int len, eir = 0; + + if (di.features[6] & LMP_EXT_INQ) { + if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) == 0) + eir = 1; + } + + memset(data, 0, sizeof(data)); + len = strlen(opt); + if (len > 48) { + len = 48; + data[1] = 0x08; + } else + data[1] = 0x09; + data[0] = len + 1; + memcpy(data + 2, opt, len); + + if (hci_write_local_name(dd, opt, 2000) < 0) { fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } + + if (eir) { + if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { + fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + } + } } else { char name[249]; int i; - if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { + + if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) { fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } + for (i = 0; i < 248 && name[i]; i++) if (!isprint(name[i])) name[i] = '.'; name[248] = '\0'; + print_dev_hdr(&di); printf("\tName: '%s'\n", name); } + + hci_close_dev(dd); } /* @@ -918,6 +950,8 @@ static void cmd_inq_mode(int ctl, int hdev, char *opt) break; } } + + hci_close_dev(dd); } static void cmd_inq_data(int ctl, int hdev, char *opt) @@ -932,12 +966,21 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) } if (opt) { - uint8_t fec = 0, data[248]; + uint8_t fec = 0, data[240]; + char tmp[3]; + int i, size; memset(data, 0, sizeof(data)); - data[0] = strlen(opt) + 1; - data[1] = 0x09; - memcpy(data + 2, opt, strlen(opt)); + + memset(tmp, 0, sizeof(tmp)); + size = (strlen(opt) + 1) / 2; + if (size > 240) + size = 240; + + for (i = 0; i < size; i++) { + memcpy(tmp, opt + (i * 2), 2); + data[i] = strtol(tmp, NULL, 16); + } if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n", @@ -945,7 +988,8 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) exit(1); } } else { - uint8_t fec, data[240]; + uint8_t fec, data[240], len, type, *ptr; + char *str; if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) { fprintf(stderr, "Can't read extended inquiry response on hci%d: %s (%d)\n", @@ -954,12 +998,42 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) } print_dev_hdr(&di); - printf("\tFEC: %d\n\t", fec); + printf("\tFEC %s\n\t\t", fec ? "enabled" : "disabled"); for (i = 0; i < 240; i++) printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ", - (i + 1) % 16 ? " " : "\n\t"); + (i + 1) % 16 ? " " : (i < 239 ? "\n\t\t" : "\n")); + + ptr = data; + while (*ptr) { + len = *ptr++; + type = *ptr++; + switch (type) { + case 0x08: + case 0x09: + str = malloc(len); + if (str) { + snprintf(str, len, "%s", ptr); + for (i = 0; i < len - 1; i++) + if (!isprint(str[i])) + str[i] = '.'; + printf("\t%s local name: \'%s\'\n", + type == 0x08 ? "Shortened" : "Complete", str); + free(str); + } + break; + default: + printf("\tUnknown type 0x%02x with %d bytes data\n", + type, len - 1); + break; + } + + ptr += (len - 1); + } + printf("\n"); } + + hci_close_dev(dd); } static void cmd_inq_type(int ctl, int hdev, char *opt) @@ -994,6 +1068,8 @@ static void cmd_inq_type(int ctl, int hdev, char *opt) printf("\tInquiry scan type: %s\n", type == 1 ? "Interlaced Inquiry Scan" : "Standard Inquiry Scan"); } + + hci_close_dev(dd); } static void cmd_inq_parms(int ctl, int hdev, char *opt) @@ -1430,7 +1506,7 @@ static struct { { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { "inqmode", cmd_inq_mode, "[mode]", "Get/Set inquiry mode" }, - { "inqdata", cmd_inq_data, "[name]", "Get/Set inquiry data (device name)" }, + { "inqdata", cmd_inq_data, "[data]", "Get/Set inquiry data" }, { "inqtype", cmd_inq_type, "[type]", "Get/Set inquiry scan type" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, -- cgit From 632a9432774ff3a0c6e556e8f32a565b38890767 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 22:36:31 +0000 Subject: Big cleanup of CVS relics --- tools/Makefile.am | 3 --- tools/avctrl.c | 25 ++++++++++--------------- tools/bccmd.c | 25 ++++++++++--------------- tools/ciptool.c | 27 +++++++++++---------------- tools/csr.c | 25 ++++++++++--------------- tools/csr.h | 25 ++++++++++--------------- tools/csrinit.c | 25 ++++++++++--------------- tools/dfu.c | 17 ++++++++--------- tools/dfu.h | 17 ++++++++--------- tools/dfutool.c | 17 ++++++++--------- tools/hciattach.c | 27 +++++++++++---------------- tools/hciconfig.c | 25 ++++++++++--------------- tools/hcisecfilter.c | 25 ++++++++++--------------- tools/hcitool.c | 25 ++++++++++--------------- tools/hid2hci.c | 27 +++++++++++---------------- tools/l2ping.c | 25 ++++++++++--------------- tools/oui.c | 25 ++++++++++--------------- tools/oui.h | 25 ++++++++++--------------- tools/ppporc.c | 27 +++++++++++---------------- tools/pskey.c | 25 ++++++++++--------------- tools/sdptool.c | 25 ++++++++++--------------- 21 files changed, 198 insertions(+), 289 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 8a2241c6..479011ec 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if AVCTRL avctrl_programs = avctrl diff --git a/tools/avctrl.c b/tools/avctrl.c index 03b54117..06540ef5 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/bccmd.c b/tools/bccmd.c index 18d38766..46cc2be1 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/ciptool.c b/tools/ciptool.c index 263e0573..e30db09a 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/csr.c b/tools/csr.c index 41677d22..066ff154 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/csr.h b/tools/csr.h index fe46f4b4..bb87fd9f 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #define CSR_VARID_PS_CLR_ALL 0x000b /* valueless */ diff --git a/tools/csrinit.c b/tools/csrinit.c index 5d939539..a56dbde9 100644 --- a/tools/csrinit.c +++ b/tools/csrinit.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/dfu.c b/tools/dfu.c index bfbc0f2d..436b2e02 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -6,20 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/dfu.h b/tools/dfu.h index 915efd8c..54992e03 100644 --- a/tools/dfu.h +++ b/tools/dfu.h @@ -6,20 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #include diff --git a/tools/dfutool.c b/tools/dfutool.c index 06da5248..451ce957 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -6,20 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hciattach.c b/tools/hciattach.c index b7f6dab6..8091d655 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -649,7 +644,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) /* * Silicon Wave specific initialization - * Thomas Moser + * Thomas Moser */ static int swave(int fd, struct uart_t *u, struct termios *ti) { diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 7267d564..527c9632 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index ce0082e9..1d557ce1 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -7,24 +7,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hcitool.c b/tools/hcitool.c index 75b09b77..9ae42a12 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hid2hci.c b/tools/hid2hci.c index a5c2722c..8a19a880 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/l2ping.c b/tools/l2ping.c index 9741dc0e..3b46675d 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/oui.c b/tools/oui.c index 985e6e20..0a1d67bc 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/oui.h b/tools/oui.h index 918a248b..93cc7b01 100644 --- a/tools/oui.h +++ b/tools/oui.h @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ char *ouitocomp(const char *oui); diff --git a/tools/ppporc.c b/tools/ppporc.c index 60aefd39..e8275641 100644 --- a/tools/ppporc.c +++ b/tools/ppporc.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/pskey.c b/tools/pskey.c index b1f6a319..d9bda6a8 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/sdptool.c b/tools/sdptool.c index 6c07cfab..052c0b05 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -10,24 +10,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From c0635ace793c507f7a9ffd57977eeb96d3685a44 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 12:17:08 +0000 Subject: Update some missing PS keys --- tools/csr.c | 20 ++++++++++++++++++++ tools/csr.h | 5 +++++ 2 files changed, 25 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 066ff154..086c204e 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -565,6 +565,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Maximum transmit power"; case CSR_PSKEY_TX_GAIN_RAMP: return "Transmit gain ramp rate"; + case CSR_PSKEY_LC_POWER_TABLE: + return "Radio power table"; case CSR_PSKEY_LC_PEER_POWER_PERIOD: return "Peer transmit power control interval"; case CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK: @@ -671,6 +673,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Disable the HCI Command_Status event on boot"; case CSR_PSKEY_LM_MAX_EVENT_FILTERS: return "Maximum number of event filters"; + case CSR_PSKEY_LM_USE_ENC_MODE_BROADCAST: + return "Allow LM to use enc_mode=2"; case CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE: return "LM sends two LMP_accepted messages in test mode"; case CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME: @@ -909,6 +913,8 @@ char *csr_pskeytostr(uint16_t pskey) return "IQ calibration channel"; case CSR_PSKEY_IQ_TRIM_GAIN: return "IQ calibration gain"; + case CSR_PSKEY_IQ_TRIM_ENABLE: + return "IQ calibration enable"; case CSR_PSKEY_TX_OFFSET_HALF_MHZ: return "Transmit offset"; case CSR_PSKEY_GBL_MISC_ENABLES: @@ -1193,6 +1199,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Trim value to optimise loop filter"; case CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK: return "Energy consumption estimation current peak"; + case CSR_PSKEY_VM_E2_CACHE_LIMIT: + return "Maximum RAM for caching EEPROM VM application"; case CSR_PSKEY_FORCE_16MHZ_REF_PIO: return "PIO line to force 16 MHz reference to be assumed"; case CSR_PSKEY_CDMA_LO_REF_LIMITS: @@ -1251,6 +1259,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Medium rate value for the ANA_RX_FTRIM register"; case CSR_PSKEY_I2C_CONFIG: return "I2C configuration"; + case CSR_PSKEY_IQ_LVL_RX: + return "IQ demand level for reception"; case CSR_PSKEY_MR_TX_FILTER_CONFIG: return "TX filter configuration used for enhanced data rate"; case CSR_PSKEY_MR_TX_CONFIG2: @@ -1423,6 +1433,8 @@ char *csr_pskeytoval(uint16_t pskey) return "LC_MAX_TX_POWER"; case CSR_PSKEY_TX_GAIN_RAMP: return "TX_GAIN_RAMP"; + case CSR_PSKEY_LC_POWER_TABLE: + return "LC_POWER_TABLE"; case CSR_PSKEY_LC_PEER_POWER_PERIOD: return "LC_PEER_POWER_PERIOD"; case CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK: @@ -1529,6 +1541,8 @@ char *csr_pskeytoval(uint16_t pskey) return "HCI_NOP_DISABLE"; case CSR_PSKEY_LM_MAX_EVENT_FILTERS: return "LM_MAX_EVENT_FILTERS"; + case CSR_PSKEY_LM_USE_ENC_MODE_BROADCAST: + return "LM_USE_ENC_MODE_BROADCAST"; case CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE: return "LM_TEST_SEND_ACCEPTED_TWICE"; case CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME: @@ -1767,6 +1781,8 @@ char *csr_pskeytoval(uint16_t pskey) return "IQ_TRIM_CHANNEL"; case CSR_PSKEY_IQ_TRIM_GAIN: return "IQ_TRIM_GAIN"; + case CSR_PSKEY_IQ_TRIM_ENABLE: + return "IQ_TRIM_ENABLE"; case CSR_PSKEY_TX_OFFSET_HALF_MHZ: return "TX_OFFSET_HALF_MHZ"; case CSR_PSKEY_GBL_MISC_ENABLES: @@ -2051,6 +2067,8 @@ char *csr_pskeytoval(uint16_t pskey) return "LOOP_FILTER_TRIM"; case CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK: return "DRAIN_BORE_CURRENT_PEAK"; + case CSR_PSKEY_VM_E2_CACHE_LIMIT: + return "VM_E2_CACHE_LIMIT"; case CSR_PSKEY_FORCE_16MHZ_REF_PIO: return "FORCE_16MHZ_REF_PIO"; case CSR_PSKEY_CDMA_LO_REF_LIMITS: @@ -2109,6 +2127,8 @@ char *csr_pskeytoval(uint16_t pskey) return "MR_ANA_RX_FTRIM"; case CSR_PSKEY_I2C_CONFIG: return "I2C_CONFIG"; + case CSR_PSKEY_IQ_LVL_RX: + return "IQ_LVL_RX"; case CSR_PSKEY_MR_TX_FILTER_CONFIG: return "MR_TX_FILTER_CONFIG"; case CSR_PSKEY_MR_TX_CONFIG2: diff --git a/tools/csr.h b/tools/csr.h index bb87fd9f..d366d19b 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -80,6 +80,7 @@ #define CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK 0x0015 /* lc_fc_lwm */ #define CSR_PSKEY_LC_MAX_TX_POWER 0x0017 /* int16 */ #define CSR_PSKEY_TX_GAIN_RAMP 0x001d /* uint16 */ +#define CSR_PSKEY_LC_POWER_TABLE 0x001e /* power_setting[] */ #define CSR_PSKEY_LC_PEER_POWER_PERIOD 0x001f /* TIME */ #define CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK 0x0020 /* lc_fc_lwm */ #define CSR_PSKEY_LC_DEFAULT_TX_POWER 0x0021 /* int16 */ @@ -133,6 +134,7 @@ #define CSR_PSKEY_LM_USE_UNIT_KEY 0x00f0 /* bool */ #define CSR_PSKEY_HCI_NOP_DISABLE 0x00f2 /* bool */ #define CSR_PSKEY_LM_MAX_EVENT_FILTERS 0x00f4 /* uint8 */ +#define CSR_PSKEY_LM_USE_ENC_MODE_BROADCAST 0x00f5 /* bool */ #define CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE 0x00f6 /* bool */ #define CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME 0x00f7 /* uint16 */ #define CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME 0x00f8 /* uint16 */ @@ -252,6 +254,7 @@ #define CSR_PSKEY_LO_ADC_AMPL_MAX 0x0213 /* uint16 */ #define CSR_PSKEY_IQ_TRIM_CHANNEL 0x0214 /* uint16 */ #define CSR_PSKEY_IQ_TRIM_GAIN 0x0215 /* uint16 */ +#define CSR_PSKEY_IQ_TRIM_ENABLE 0x0216 /* iq_trim_enable_flag */ #define CSR_PSKEY_TX_OFFSET_HALF_MHZ 0x0217 /* int16 */ #define CSR_PSKEY_GBL_MISC_ENABLES 0x0221 /* uint16 */ #define CSR_PSKEY_UART_SLEEP_TIMEOUT 0x0222 /* uint16 */ @@ -394,6 +397,7 @@ #define CSR_PSKEY_DRAIN_BORE_COUNTERS 0x03e6 /* uint32[] */ #define CSR_PSKEY_LOOP_FILTER_TRIM 0x03e4 /* uint16 */ #define CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK 0x03e3 /* uint32[] */ +#define CSR_PSKEY_VM_E2_CACHE_LIMIT 0x03e2 /* uint16 */ #define CSR_PSKEY_FORCE_16MHZ_REF_PIO 0x03e1 /* uint16 */ #define CSR_PSKEY_CDMA_LO_REF_LIMITS 0x03df /* uint16 */ #define CSR_PSKEY_CDMA_LO_ERROR_LIMITS 0x03de /* uint16 */ @@ -423,6 +427,7 @@ #define CSR_PSKEY_USB_VM_CONTROL 0x03c0 /* bool */ #define CSR_PSKEY_MR_ANA_RX_FTRIM 0x03bf /* uint16 */ #define CSR_PSKEY_I2C_CONFIG 0x03be /* uint16 */ +#define CSR_PSKEY_IQ_LVL_RX 0x03bd /* uint16 */ #define CSR_PSKEY_MR_TX_FILTER_CONFIG 0x03bb /* uint32 */ #define CSR_PSKEY_MR_TX_CONFIG2 0x03ba /* uint16 */ #define CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET 0x03b9 /* bool */ -- cgit From d20aa9a7a44fea8be06906c7354f4fabc72e5a06 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 12:25:14 +0000 Subject: Fix typos --- tools/csr.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 086c204e..3bd25b46 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -752,33 +752,33 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_HOSTIO_FC_PS_BLOCK: return "HCI flow control block"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO0: - return "Host transport channel 0 settings (BCSP ACK"; + return "Host transport channel 0 settings (BCSP ACK)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO1: - return "Host transport channel 1 settings (BCSP-LE"; + return "Host transport channel 1 settings (BCSP-LE)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO2: - return "Host transport channel 2 settings (BCCMD"; + return "Host transport channel 2 settings (BCCMD)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO3: - return "Host transport channel 3 settings (HQ"; + return "Host transport channel 3 settings (HQ)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO4: - return "Host transport channel 4 settings (DM"; + return "Host transport channel 4 settings (DM)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO5: - return "Host transport channel 5 settings (HCI CMD/EVT"; + return "Host transport channel 5 settings (HCI CMD/EVT)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO6: - return "Host transport channel 6 settings (HCI ACL"; + return "Host transport channel 6 settings (HCI ACL)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO7: - return "Host transport channel 7 settings (HCI SCO"; + return "Host transport channel 7 settings (HCI SCO)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO8: - return "Host transport channel 8 settings (L2CAP"; + return "Host transport channel 8 settings (L2CAP)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO9: - return "Host transport channel 9 settings (RFCOMM"; + return "Host transport channel 9 settings (RFCOMM)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO10: - return "Host transport channel 10 settings (SDP"; + return "Host transport channel 10 settings (SDP)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO11: - return "Host transport channel 11 settings (TEST"; + return "Host transport channel 11 settings (TEST)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO12: - return "Host transport channel 12 settings (DFU"; + return "Host transport channel 12 settings (DFU)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO13: - return "Host transport channel 13 settings (VM"; + return "Host transport channel 13 settings (VM)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO14: return "Host transport channel 14 settings"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO15: @@ -798,7 +798,7 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC: return "PCM interface synchronisation is difficult"; case CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD: - return "Break poll period (microseconds"; + return "Break poll period (microseconds)"; case CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE: return "Minimum SCO packet size sent to host over UART HCI"; case CSR_PSKEY_HOSTIO_MAP_SCO_CODEC: @@ -870,9 +870,9 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_ANA_FTRIM: return "Crystal frequency trim"; case CSR_PSKEY_WD_TIMEOUT: - return "Watchdog timeout (microseconds"; + return "Watchdog timeout (microseconds)"; case CSR_PSKEY_WD_PERIOD: - return "Watchdog period (microseconds"; + return "Watchdog period (microseconds)"; case CSR_PSKEY_HOST_INTERFACE: return "Host interface"; case CSR_PSKEY_HQ_HOST_TIMEOUT: @@ -888,7 +888,7 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_PMALLOC_SIZES: return "pmalloc sizes array"; case CSR_PSKEY_UART_BAUD_RATE: - return "UART Baud rate (pre 18"; + return "UART Baud rate (pre 18)"; case CSR_PSKEY_UART_CONFIG: return "UART configuration bitfield"; case CSR_PSKEY_STUB: @@ -1150,7 +1150,7 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE: return "The maxmimum packet size for USB endpoint 0"; case CSR_PSKEY_USB_CONFIG: - return "USB config params for new chips (>bc2"; + return "USB config params for new chips (>bc2)"; case CSR_PSKEY_RADIOTEST_ATTEN_INIT: return "Radio test initial attenuator"; case CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME: @@ -1390,7 +1390,7 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_AMUX_AIO3: return "Multiplexer for AIO 3"; case CSR_PSKEY_LOCAL_NAME_SIMPLIFIED: - return "Local Name (simplified"; + return "Local Name (simplified)"; case CSR_PSKEY_EXTENDED_STUB: return "Extended stub"; default: -- cgit From f1ba02d0f86e0e954ac7a27d4beee3a6ee386223 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 23:56:42 +0000 Subject: Add support for big endian architectures --- tools/dfutool.c | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/dfutool.c b/tools/dfutool.c index 451ce957..0de67bb1 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -43,6 +45,20 @@ #include "dfu.h" +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le16(d) (d) +#define cpu_to_le32(d) (d) +#define le16_to_cpu(d) (d) +#define le32_to_cpu(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le16(d) bswap_16(d) +#define cpu_to_le32(d) bswap_32(d) +#define le16_to_cpu(d) bswap_16(d) +#define le32_to_cpu(d) bswap_32(d) +#else +#error "Unknown byte order" +#endif + #ifdef NEED_USB_GET_BUSSES static inline struct usb_bus *usb_get_busses(void) { @@ -211,9 +227,9 @@ static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffi fflush(stdout); if (suffix) { - suffix->idVendor = dfu_dev[sel]->descriptor.idVendor; - suffix->idProduct = dfu_dev[sel]->descriptor.idProduct; - suffix->bcdDevice = dfu_dev[sel]->descriptor.bcdDevice; + suffix->idVendor = cpu_to_le16(dfu_dev[sel]->descriptor.idVendor); + suffix->idProduct = cpu_to_le16(dfu_dev[sel]->descriptor.idProduct); + suffix->bcdDevice = cpu_to_le16(dfu_dev[sel]->descriptor.bcdDevice); } if (dfu_detach(udev, intf) < 0) { @@ -302,6 +318,7 @@ static void cmd_verify(char *device, int argc, char **argv) struct stat st; struct dfu_suffix *suffix; uint32_t crc; + uint16_t bcd; char str[16]; unsigned char *buf; unsigned long size; @@ -358,17 +375,19 @@ static void cmd_verify(char *device, int argc, char **argv) suffix = (struct dfu_suffix *) (buf + size - DFU_SUFFIX_SIZE); - printf("idVendor\t%04x\n", suffix->idVendor); - printf("idProduct\t%04x\n", suffix->idProduct); - printf("bcdDevice\t%x\n", suffix->bcdDevice); + printf("idVendor\t%04x\n", le16_to_cpu(suffix->idVendor)); + printf("idProduct\t%04x\n", le16_to_cpu(suffix->idProduct)); + printf("bcdDevice\t%x\n", le16_to_cpu(suffix->bcdDevice)); printf("\n"); - printf("bcdDFU\t\t%x.%x\n", suffix->bcdDFU >> 8, suffix->bcdDFU & 0xff); + bcd = le16_to_cpu(suffix->bcdDFU); + + printf("bcdDFU\t\t%x.%x\n", bcd >> 8, bcd & 0xff); printf("ucDfuSignature\t%c%c%c\n", suffix->ucDfuSignature[2], suffix->ucDfuSignature[1], suffix->ucDfuSignature[0]); printf("bLength\t\t%d\n", suffix->bLength); - printf("dwCRC\t\t%08x\n", suffix->dwCRC); + printf("dwCRC\t\t%08x\n", le32_to_cpu(suffix->dwCRC)); printf("\n"); memset(str, 0, sizeof(str)); @@ -402,7 +421,7 @@ static void cmd_upgrade(char *device, int argc, char **argv) char *buf; unsigned long filesize, count, timeout = 0; char *filename; - uint32_t crc; + uint32_t crc, dwCRC; int fd, i, block, len, size, sent = 0, try = 10; if (argc < 2) { @@ -438,6 +457,7 @@ static void cmd_upgrade(char *device, int argc, char **argv) } memcpy(&suffix, buf + filesize - DFU_SUFFIX_SIZE, sizeof(suffix)); + dwCRC = le32_to_cpu(suffix.dwCRC); printf("Filename\t%s\n", basename(filename)); printf("Filesize\t%ld\n", filesize); @@ -445,10 +465,11 @@ static void cmd_upgrade(char *device, int argc, char **argv) crc = crc32_init(); for (i = 0; i < filesize - 4; i++) crc = crc32_byte(crc, buf[i]); + printf("Checksum\t%08x (%s)\n", crc, - crc == suffix.dwCRC ? "valid" : "corrupt"); + crc == dwCRC ? "valid" : "corrupt"); - if (crc != suffix.dwCRC) { + if (crc != dwCRC) { free(buf); close(fd); exit(1); @@ -654,7 +675,7 @@ static void cmd_archive(char *device, int argc, char **argv) } printf("\n"); - suffix.bcdDFU = 0x0100; + suffix.bcdDFU = cpu_to_le16(0x0100); suffix.ucDfuSignature[0] = 'U'; suffix.ucDfuSignature[1] = 'F'; suffix.ucDfuSignature[2] = 'D'; @@ -664,7 +685,7 @@ static void cmd_archive(char *device, int argc, char **argv) for (i = 0; i < DFU_SUFFIX_SIZE - 4; i++) crc = crc32_byte(crc, buf[i]); - suffix.dwCRC = crc; + suffix.dwCRC = cpu_to_le32(crc); write(fd, &suffix, DFU_SUFFIX_SIZE); -- cgit From 4b623ab3d9307b4790a5228309b83804bead8777 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 17:42:24 +0000 Subject: The parameter is called stores and not store --- tools/csr.c | 24 ++++++++++++------------ tools/csr.h | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 3bd25b46..b3d26adf 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2433,13 +2433,13 @@ int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *val return 0; } -int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length) +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, pskey & 0xff, pskey >> 8, (length / 2) & 0xff, (length / 2) >> 8, - store & 0xff, store >> 8, 0x00, 0x00 }; + stores & 0xff, stores >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; struct hci_request rq; @@ -2475,13 +2475,13 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto return 0; } -int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length) +int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x02, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, pskey & 0xff, pskey >> 8, (length / 2) & 0xff, (length / 2) >> 8, - store & 0xff, store >> 8, 0x00, 0x00 }; + stores & 0xff, stores >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; struct hci_request rq; @@ -2517,31 +2517,31 @@ int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t st return 0; } -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value) +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t *value) { uint8_t array[2] = { 0x00, 0x00 }; int err; - err = csr_read_pskey_complex(dd, seqnum, pskey, store, array, 2); + err = csr_read_pskey_complex(dd, seqnum, pskey, stores, array, 2); *value = array[0] + (array[1] << 8); return err; } -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value) +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t value) { uint8_t array[2] = { value & 0xff, value >> 8 }; - return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 2); + return csr_write_pskey_complex(dd, seqnum, pskey, stores, array, 2); } -int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value) +int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t *value) { uint8_t array[4] = { 0x00, 0x00, 0x00, 0x00 }; int err; - err = csr_read_pskey_complex(dd, seqnum, pskey, store, array, 4); + err = csr_read_pskey_complex(dd, seqnum, pskey, stores, array, 4); *value = ((array[0] + (array[1] << 8)) << 16) + (array[2] + (array[3] << 8)); @@ -2549,12 +2549,12 @@ int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stor return err; } -int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value) +int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t value) { uint8_t array[4] = { (value & 0xff0000) >> 16, value >> 24, value & 0xff, (value & 0xff00) >> 8 }; - return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 4); + return csr_write_pskey_complex(dd, seqnum, pskey, stores, array, 4); } int psr_put(uint16_t pskey, uint8_t *value, uint16_t size) diff --git a/tools/csr.h b/tools/csr.h index d366d19b..af5af63f 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -505,12 +505,12 @@ int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); -int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); -int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value); -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); -int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value); -int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value); +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length); +int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length); +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t *value); +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t value); +int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t *value); +int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t value); int psr_put(uint16_t pskey, uint8_t *value, uint16_t size); int psr_get(uint16_t *pskey, uint8_t *value, uint16_t *size); -- cgit From bbf0b522084d22e9fa1ec5ab6e5d850a298d55d6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 17:43:22 +0000 Subject: Add support for different stores --- tools/pskey.c | 72 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 24 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index d9bda6a8..f6bc0a7e 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -49,9 +49,7 @@ enum { READ, }; -static int transient = 0; - -static int cmd_list(int dd, int argc, char *argv[]) +static int cmd_list(int dd, uint16_t stores, int argc, char *argv[]) { uint8_t array[8]; uint16_t length, seqnum = 0x0000, pskey = 0x0000; @@ -61,6 +59,8 @@ static int cmd_list(int dd, int argc, char *argv[]) memset(array, 0, sizeof(array)); array[0] = pskey & 0xff; array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_PS_NEXT, array, sizeof(array)); @@ -74,6 +74,8 @@ static int cmd_list(int dd, int argc, char *argv[]) memset(array, 0, sizeof(array)); array[0] = pskey & 0xff; array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_PS_SIZE, array, sizeof(array)); @@ -89,7 +91,7 @@ static int cmd_list(int dd, int argc, char *argv[]) return 0; } -static int cmd_read(int dd, int argc, char *argv[]) +static int cmd_read(int dd, uint16_t stores, int argc, char *argv[]) { uint8_t array[256]; uint16_t length, seqnum = 0x0000, pskey = 0x0000; @@ -100,9 +102,11 @@ static int cmd_read(int dd, int argc, char *argv[]) memset(array, 0, sizeof(array)); array[0] = pskey & 0xff; array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, 8); + CSR_VARID_PS_NEXT, array, 8); if (err < 0) break; @@ -113,9 +117,11 @@ static int cmd_read(int dd, int argc, char *argv[]) memset(array, 0, sizeof(array)); array[0] = pskey & 0xff; array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); + CSR_VARID_PS_SIZE, array, 8); if (err < 0) continue; @@ -124,7 +130,7 @@ static int cmd_read(int dd, int argc, char *argv[]) continue; err = csr_read_pskey_complex(dd, seqnum++, pskey, - 0x0000, array, length * 2); + stores, array, length * 2); if (err < 0) continue; @@ -158,7 +164,7 @@ static int pskey_size(uint16_t pskey) } } -static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) +static int write_pskey(int dd, uint16_t pskey, uint16_t stores, int type, int argc, char *argv[]) { uint8_t array[64]; uint16_t value; @@ -183,7 +189,7 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) array[i] = atoi(argv[i]); err = csr_write_pskey_complex(dd, 0x4711, pskey, - transient ? 0x0008 : 0x0000, array, size); + stores, array, size); break; case CSR_TYPE_UINT8: @@ -198,8 +204,7 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) else value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, 0x4711, pskey, - transient ? 0x0008 : 0x0000, value); + err = csr_write_pskey_uint16(dd, 0x4711, pskey, stores, value); break; case CSR_TYPE_UINT32: @@ -213,8 +218,7 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) else val32 = atoi(argv[0]); - err = csr_write_pskey_uint32(dd, 0x4711, pskey, - transient ? 0x0008 : 0x0000, val32); + err = csr_write_pskey_uint32(dd, 0x4711, pskey, stores, val32); break; default: @@ -226,7 +230,7 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) return err; } -static int read_pskey(int dd, uint16_t pskey, int type) +static int read_pskey(int dd, uint16_t pskey, uint16_t stores, int type) { uint8_t array[64]; uint16_t value = 0; @@ -239,7 +243,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) case CSR_TYPE_ARRAY: size = pskey_size(pskey); - err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); + err = csr_read_pskey_complex(dd, 0x4711, pskey, stores, array, size); if (err < 0) return err; @@ -251,7 +255,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) case CSR_TYPE_UINT8: case CSR_TYPE_UINT16: - err = csr_read_pskey_uint16(dd, 0x4711, pskey, 0x0000, &value); + err = csr_read_pskey_uint16(dd, 0x4711, pskey, stores, &value); if (err < 0) return err; @@ -259,7 +263,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) break; case CSR_TYPE_UINT32: - err = csr_read_pskey_uint32(dd, 0x4711, pskey, 0x0000, &val32); + err = csr_read_pskey_uint32(dd, 0x4711, pskey, stores, &val32); if (err < 0) return err; @@ -308,7 +312,7 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [-r] [-t] [value]\n" + "\tpskey [-i ] [-r] [-s stores] [-t] [value]\n" "\tpskey [-i ] --list\n" "\tpskey [-i ] --read\n\n"); @@ -327,6 +331,7 @@ static void usage(void) static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, + { "stores", 1, 0, 's' }, { "transient", 0, 0, 't' }, { "list", 0, 0, 'L' }, { "read", 0, 0, 'R' }, @@ -338,9 +343,10 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; + uint16_t stores = 0x0001; int i, err, dd, opt, dev = 0, reset = 0, mode = NONE; - while ((opt=getopt_long(argc, argv, "+i:rtLRh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rs:tLRh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -354,8 +360,25 @@ int main(int argc, char *argv[]) reset = 1; break; + case 's': + if (!strcasecmp(optarg, "default")) + stores = 0x0000; + else if (!strcasecmp(optarg, "psi")) + stores = 0x0001; + else if (!strcasecmp(optarg, "psf")) + stores = 0x0002; + else if (!strcasecmp(optarg, "psrom")) + stores = 0x0004; + else if (!strcasecmp(optarg, "psram")) + stores = 0x0008; + else if (!strncasecmp(optarg, "0x", 2)) + stores = strtol(optarg, NULL, 16); + else + stores = atoi(optarg); + break; + case 't': - transient = 1; + stores = 0x0008; break; case 'L': @@ -412,11 +435,11 @@ int main(int argc, char *argv[]) if (mode > 0) { switch (mode) { case LIST: - err = cmd_list(dd, argc, argv); + err = cmd_list(dd, stores, argc, argv); break; case READ: - err = cmd_read(dd, argc, argv); + err = cmd_read(dd, stores, argc, argv); break; default: @@ -434,14 +457,15 @@ int main(int argc, char *argv[]) continue; if (argc > 1) { - err = write_pskey(dd, storage[i].pskey, + err = write_pskey(dd, storage[i].pskey, stores, storage[i].type, argc - 1, argv + 1); if (!err && reset) csr_write_varid_valueless(dd, 0x0000, CSR_VARID_WARM_RESET); } else - err = read_pskey(dd, storage[i].pskey, storage[i].type); + err = read_pskey(dd, storage[i].pskey, + stores, storage[i].type); hci_close_dev(dd); -- cgit From 5adba470b7929bf1ae8355484d08b353b3d8f77e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 17:49:00 +0000 Subject: Add alternate names for the stores --- tools/pskey.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index f6bc0a7e..701a47fd 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -363,6 +363,14 @@ int main(int argc, char *argv[]) case 's': if (!strcasecmp(optarg, "default")) stores = 0x0000; + else if (!strcasecmp(optarg, "implementation")) + stores = 0x0001; + else if (!strcasecmp(optarg, "factory")) + stores = 0x0002; + else if (!strcasecmp(optarg, "rom")) + stores = 0x0004; + else if (!strcasecmp(optarg, "ram")) + stores = 0x0008; else if (!strcasecmp(optarg, "psi")) stores = 0x0001; else if (!strcasecmp(optarg, "psf")) -- cgit From 37c4010967b3e87fa1d510a66adb1c61526fef09 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 18:28:04 +0000 Subject: Use psi, psf and psram as default store --- tools/pskey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 701a47fd..46d837d4 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -343,7 +343,7 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - uint16_t stores = 0x0001; + uint16_t stores = 0x0001 | 0x0002 | 0x0008; int i, err, dd, opt, dev = 0, reset = 0, mode = NONE; while ((opt=getopt_long(argc, argv, "+i:rs:tLRh", main_options, NULL)) != -1) { -- cgit From e6f085ddedd4159c9c07fba0c2babaa0f0053b01 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:05:48 +0000 Subject: Add support for writing complex BCCMD commands --- tools/csr.c | 39 +++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 40 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index b3d26adf..698122dc 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2312,6 +2312,45 @@ int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid) return 0; } +int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + unsigned char cmd[] = { 0x02, 0x00, ((length / 2) + 5) & 0xff, ((length / 2) + 5) >> 8, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + memcpy(cp + 11, value, length); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} + int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 5) & 0xff, ((length / 2) + 5) >> 8, diff --git a/tools/csr.h b/tools/csr.h index af5af63f..760235b1 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -502,6 +502,7 @@ char *csr_pskeytostr(uint16_t pskey); char *csr_pskeytoval(uint16_t pskey); int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); +int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); -- cgit From d320d7de71d05d4aeffee7481b8efa3d5c626d21 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:09:03 +0000 Subject: Add support for deleting PS keys --- tools/pskey.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 46d837d4..247f0c35 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -279,6 +279,23 @@ static int read_pskey(int dd, uint16_t pskey, uint16_t stores, int type) return err; } +static int delete_pskey(int dd, uint16_t pskey, uint16_t stores) +{ + uint8_t array[8]; + int err; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_write_varid_complex(dd, 0x4711, + CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + + return err; +} + static struct { uint16_t pskey; int type; @@ -312,7 +329,8 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [-r] [-s stores] [-t] [value]\n" + "\tpskey [-i ] [-r] [-s stores] [value]\n" + "\tpskey [-i ] [-r] [-s stores] --clear \n" "\tpskey [-i ] --list\n" "\tpskey [-i ] --read\n\n"); @@ -332,7 +350,7 @@ static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, { "stores", 1, 0, 's' }, - { "transient", 0, 0, 't' }, + { "clear", 0, 0, 'c' }, { "list", 0, 0, 'L' }, { "read", 0, 0, 'R' }, { "help", 0, 0, 'h' }, @@ -344,9 +362,9 @@ int main(int argc, char *argv[]) struct hci_dev_info di; struct hci_version ver; uint16_t stores = 0x0001 | 0x0002 | 0x0008; - int i, err, dd, opt, dev = 0, reset = 0, mode = NONE; + int i, err, dd, opt, dev = 0, reset = 0, clear = 0, mode = NONE; - while ((opt=getopt_long(argc, argv, "+i:rs:tLRh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rs:cLRh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -385,8 +403,8 @@ int main(int argc, char *argv[]) stores = atoi(optarg); break; - case 't': - stores = 0x0008; + case 'c': + clear = 1; break; case 'L': @@ -471,9 +489,13 @@ int main(int argc, char *argv[]) if (!err && reset) csr_write_varid_valueless(dd, 0x0000, CSR_VARID_WARM_RESET); - } else - err = read_pskey(dd, storage[i].pskey, - stores, storage[i].type); + } else { + if (clear) + err = delete_pskey(dd, storage[i].pskey, stores); + else + err = read_pskey(dd, storage[i].pskey, + stores, storage[i].type); + } hci_close_dev(dd); -- cgit From 9168e1f8c1e19c14b4b49d13bc91c6041c646f0d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:38:02 +0000 Subject: Add missing definition for memory type --- tools/csr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index 760235b1..cd807c38 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -40,6 +40,7 @@ #define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */ #define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ #define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ +#define CSR_VARID_PS_MEMORY_TYPE 0x3012 /* complex */ #define CSR_VARID_COLD_RESET 0x4001 /* valueless */ #define CSR_VARID_WARM_RESET 0x4002 /* valueless */ #define CSR_VARID_COLD_HALT 0x4003 /* valueless */ -- cgit From b525d3b600bc325a4d1937b0bb6920d51b99dd79 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:38:29 +0000 Subject: Add support for checking the memory type --- tools/pskey.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/pskey.c b/tools/pskey.c index 247f0c35..c185cf58 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -45,10 +45,68 @@ enum { NONE = 0, + MEMORY, LIST, READ, }; +static char *storestostr(uint16_t stores) +{ + switch (stores) { + case 0x0000: + return "Default"; + case 0x0001: + return "psi"; + case 0x0002: + return "psf"; + case 0x0004: + return "psrom"; + case 0x0008: + return "psram"; + default: + return "Unknown"; + } +} + +static char *memorytostr(uint16_t type) +{ + switch (type) { + case 0x0000: + return "Flash memory"; + case 0x0001: + return "EEPROM"; + case 0x0002: + return "RAM (transient)"; + case 0x0003: + return "ROM (or \"read-only\" flash memory)"; + default: + return "Unknown"; + } +} + +static int cmd_memory(int dd, uint16_t stores, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t type; + int err; + + memset(array, 0, sizeof(array)); + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, 0x4711, + CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + if (err < 0) + return err; + + type = array[4] + (array[5] << 8); + + printf("%s (0x%04x) = %s (%d)\n", storestostr(stores), stores, + memorytostr(type), type); + + return 0; +} + static int cmd_list(int dd, uint16_t stores, int argc, char *argv[]) { uint8_t array[8]; @@ -331,8 +389,9 @@ static void usage(void) printf("Usage:\n" "\tpskey [-i ] [-r] [-s stores] [value]\n" "\tpskey [-i ] [-r] [-s stores] --clear \n" - "\tpskey [-i ] --list\n" - "\tpskey [-i ] --read\n\n"); + "\tpskey [-i ] [-s stores] --memory\n" + "\tpskey [-i ] [-s stores] --list\n" + "\tpskey [-i ] [-s stores] --read\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -351,6 +410,7 @@ static struct option main_options[] = { { "reset", 0, 0, 'r' }, { "stores", 1, 0, 's' }, { "clear", 0, 0, 'c' }, + { "memory", 0, 0, 'M' }, { "list", 0, 0, 'L' }, { "read", 0, 0, 'R' }, { "help", 0, 0, 'h' }, @@ -364,7 +424,7 @@ int main(int argc, char *argv[]) uint16_t stores = 0x0001 | 0x0002 | 0x0008; int i, err, dd, opt, dev = 0, reset = 0, clear = 0, mode = NONE; - while ((opt=getopt_long(argc, argv, "+i:rs:cLRh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rs:cMLRh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -407,6 +467,10 @@ int main(int argc, char *argv[]) clear = 1; break; + case 'M': + mode = MEMORY; + break; + case 'L': mode = LIST; break; @@ -460,14 +524,15 @@ int main(int argc, char *argv[]) if (mode > 0) { switch (mode) { + case MEMORY: + err = cmd_memory(dd, stores, argc, argv); + break; case LIST: err = cmd_list(dd, stores, argc, argv); break; - case READ: err = cmd_read(dd, stores, argc, argv); break; - default: usage(); err = -1; -- cgit From 50a8cc8a256f3ef56a6144cabd2ae6ee5848e46d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:00:58 +0000 Subject: Update to the new BCCMD interface utility --- tools/Makefile.am | 36 +-- tools/bccmd.c | 749 ++++++++++++++++++++++++++++++++++++++++++++++++++---- tools/csrinit.8 | 35 --- tools/csrinit.c | 97 ------- tools/pskey.c | 581 ------------------------------------------ 5 files changed, 718 insertions(+), 780 deletions(-) delete mode 100644 tools/csrinit.8 delete mode 100644 tools/csrinit.c delete mode 100644 tools/pskey.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 479011ec..238a2df1 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,12 @@ +if BCCMD +bccmd_programs = bccmd +bccmd_manfiles = bccmd.8 +else +bccmd_programs = +bccmd_manfiles = +endif + if AVCTRL avctrl_programs = avctrl avctrl_manfiles = avctrl.8 @@ -15,14 +23,6 @@ hid2hci_programs = hid2hci_manfiles = endif -if CSRINIT -csrinit_programs = csrinit -csrinit_manfiles = csrinit.8 -else -csrinit_programs = -csrinit_manfiles = -endif - if DFUTOOL dfutool_programs = dfutool dfutool_manfiles = dfutool.1 @@ -31,11 +31,11 @@ dfutool_programs = dfutool_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) $(csrinit_programs) +sbin_PROGRAMS = hciattach hciconfig $(bccmd_programs) $(avctrl_programs) $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) -noinst_PROGRAMS = hcisecfilter ppporc pskey bccmd +noinst_PROGRAMS = hcisecfilter ppporc hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a @@ -51,11 +51,10 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -pskey_SOURCES = pskey.c csr.h csr.c -pskey_LDADD = @BLUEZ_LIBS@ - +if BCCMD bccmd_SOURCES = bccmd.c csr.h csr.c bccmd_LDADD = @BLUEZ_LIBS@ +endif if AVCTRL avctrl_LDADD = @USB_LIBS@ @@ -65,11 +64,6 @@ if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif -if CSRINIT -csrinit_SOURCES = csrinit.c csr.h -csrinit_LDADD = @USB_LIBS@ -endif - if DFUTOOL dfutool_SOURCES = dfutool.c dfu.h dfu.c dfutool_LDADD = @USB_LIBS@ @@ -80,10 +74,8 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - $(avctrl_manfiles) $(hid2hci_manfiles) $(csrinit_manfiles) $(dfutool_manfiles) - -noinst_MANS = bccmd.8 + $(bccmd_manfiles) $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 bccmd.8 example.psr +EXTRA_DIST = $(man_MANS) bccmd.8 avctrl.8 hid2hci.8 dfutool.1 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/bccmd.c b/tools/bccmd.c index 46cc2be1..e41f08f5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -37,12 +37,144 @@ #include "csr.h" +#define CSR_TRANSPORT_UNKNOWN 0 +#define CSR_TRANSPORT_HCI 1 +#define CSR_TRANSPORT_USB 2 +#define CSR_TRANSPORT_BCSP 3 +#define CSR_TRANSPORT_H4 4 +#define CSR_TRANSPORT_3WIRE 5 + +#define CSR_STORES_PSI (0x0001) +#define CSR_STORES_PSF (0x0002) +#define CSR_STORES_PSROM (0x0004) +#define CSR_STORES_PSRAM (0x0008) +#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF | CSR_STORES_PSRAM) + +#define CSR_TYPE_NULL 0 +#define CSR_TYPE_COMPLEX 1 +#define CSR_TYPE_UINT8 2 +#define CSR_TYPE_UINT16 3 +#define CSR_TYPE_UINT32 4 + +#define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX +#define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX + +static uint16_t seqnum = 0x0000; + +static struct { + uint16_t pskey; + int type; + int size; + char *str; +} storage[] = { + { CSR_PSKEY_BDADDR, CSR_TYPE_BDADDR, 8, "bdaddr" }, + { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, 0, "country" }, + { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, 0, "devclass" }, + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, 0, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, 0, "keymax" }, + { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, 8, "features" }, + { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, 18, "commands" }, + { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, 0, "version" }, + { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, 0, "remver" }, + { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, 0, "hciextn" }, + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, 0, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, 0, "baudrate" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, 0, "hostintf" }, + { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, 0, "anafreq" }, + { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, 0, "anaftrim" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, 0, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, 0, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, 0, "dfupid" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, 0, "bootmode" }, + { 0x0000 }, +}; + +static int pskey_size(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_BDADDR: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return 18; + default: + return 64; + } +} + +static char *storestostr(uint16_t stores) +{ + switch (stores) { + case 0x0000: + return "Default"; + case 0x0001: + return "psi"; + case 0x0002: + return "psf"; + case 0x0004: + return "psrom"; + case 0x0008: + return "psram"; + default: + return "Unknown"; + } +} + +static char *memorytostr(uint16_t type) +{ + switch (type) { + case 0x0000: + return "Flash memory"; + case 0x0001: + return "EEPROM"; + case 0x0002: + return "RAM (transient)"; + case 0x0003: + return "ROM (or \"read-only\" flash memory)"; + default: + return "Unknown"; + } +} + +#define OPT_RANGE(range) \ + if (argc < (range)) { errno = EINVAL; return -1; } \ + if (argc > (range)) { errno = E2BIG; return -1; } + +static struct option help_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int opt_help(int argc, char *argv[], int *help) +{ + int opt; + + while ((opt=getopt_long(argc, argv, "+h", help_options, NULL)) != EOF) { + switch (opt) { + case 'h': + if (help) + *help = 1; + break; + } + } + + return optind; +} + +#define OPT_HELP(range, help) \ + opt_help(argc, argv, (help)); \ + argc -= optind; argv += optind; optind = 0; \ + OPT_RANGE((range)) + static int cmd_builddef(int dd, int argc, char *argv[]) { uint8_t buf[8]; - uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; + uint16_t def = 0x0000, nextdef = 0x0000; int err = 0; + OPT_HELP(0, NULL); + printf("Build definitions:\n"); while (1) { @@ -76,15 +208,7 @@ static int cmd_keylen(int dd, int argc, char *argv[]) uint16_t handle, keylen; int err; - if (argc < 1) { - errno = EINVAL; - return -1; - } - - if (argc > 1) { - errno = E2BIG; - return -1; - } + OPT_HELP(1, NULL); handle = atoi(argv[0]); @@ -92,7 +216,7 @@ static int cmd_keylen(int dd, int argc, char *argv[]) buf[0] = handle & 0xff; buf[1] = handle >> 8; - err = csr_read_varid_complex(dd, 0x4711, + err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); if (err < 0) { errno = -err; @@ -112,7 +236,9 @@ static int cmd_clock(int dd, int argc, char *argv[]) uint32_t clock = 0; int err; - err = csr_read_varid_uint32(dd, 0x4711, CSR_VARID_BT_CLOCK, &clock); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint32(dd, seqnum++, CSR_VARID_BT_CLOCK, &clock); if (err < 0) { errno = -err; return -1; @@ -128,7 +254,9 @@ static int cmd_rand(int dd, int argc, char *argv[]) uint16_t rand = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_RAND, &rand); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_RAND, &rand); if (err < 0) { errno = -err; return -1; @@ -144,7 +272,9 @@ static int cmd_panicarg(int dd, int argc, char *argv[]) uint16_t error = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_PANIC_ARG, &error); if (err < 0) { errno = -err; return -1; @@ -161,7 +291,9 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) uint16_t error = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_FAULT_ARG, &error); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_FAULT_ARG, &error); if (err < 0) { errno = -err; return -1; @@ -175,60 +307,555 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) static int cmd_coldreset(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_COLD_RESET); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_COLD_RESET); } static int cmd_warmreset(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_WARM_RESET); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); } static int cmd_disabletx(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_DISABLE_TX); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_DISABLE_TX); } static int cmd_enabletx(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_ENABLE_TX); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_ENABLE_TX); +} + +static int cmd_memtypes(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 }; + int i, err; + + OPT_HELP(0, NULL); + + for (i = 0; i < 4; i++) { + memset(array, 0, sizeof(array)); + array[2] = stores[i] & 0xff; + array[3] = stores[i] >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + if (err < 0) + break; + + type = array[4] + (array[5] << 8); + + printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]), + stores[i], memorytostr(type), type); + } + + return err; +} + +static struct option pskey_options[] = { + { "stores", 1, 0, 's' }, + { "reset", 0, 0, 'r' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int *help) +{ + int opt; + + while ((opt=getopt_long(argc, argv, "+s:rh", pskey_options, NULL)) != EOF) { + switch (opt) { + case 's': + if (!stores) + break; + if (!strcasecmp(optarg, "default")) + *stores = 0x0000; + else if (!strcasecmp(optarg, "implementation")) + *stores = 0x0001; + else if (!strcasecmp(optarg, "factory")) + *stores = 0x0002; + else if (!strcasecmp(optarg, "rom")) + *stores = 0x0004; + else if (!strcasecmp(optarg, "ram")) + *stores = 0x0008; + else if (!strcasecmp(optarg, "psi")) + *stores = 0x0001; + else if (!strcasecmp(optarg, "psf")) + *stores = 0x0002; + else if (!strcasecmp(optarg, "psrom")) + *stores = 0x0004; + else if (!strcasecmp(optarg, "psram")) + *stores = 0x0008; + else if (!strncasecmp(optarg, "0x", 2)) + *stores = strtol(optarg, NULL, 16); + else + *stores = atoi(optarg); + break; + + case 'r': + if (reset) + *reset = 1; + break; + + case 'h': + if (help) + *help = 1; + break; + } + } + + return optind; +} + +#define OPT_PSKEY(range, stores, reset, help) \ + opt_pskey(argc, argv, (stores), (reset), (help)); \ + argc -= optind; argv += optind; optind = 0; \ + OPT_RANGE((range)) + +static int cmd_psget(int dd, int argc, char *argv[]) +{ + uint8_t array[64]; + uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT; + uint32_t val32; + int i, err, size, reset = 0, type = CSR_TYPE_NULL; + + memset(array, 0, sizeof(array)); + + OPT_PSKEY(1, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + type = storage[i].type; + size = storage[i].type; + break; + } + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } else { + pskey = strtol(argv[0] + 2, NULL, 16); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } + + switch (type) { + case CSR_TYPE_COMPLEX: + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + return -EIO; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, stores, + array, length * 2); + if (err < 0) + return err; + + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < length; i++) + printf(" 0x%02x%02x", array[i * 2], array[(i * 2) + 1]); + printf("\n"); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: + err = csr_read_pskey_uint16(dd, seqnum++, pskey, stores, &value); + if (err < 0) + return err; + + printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); + break; + + case CSR_TYPE_UINT32: + err = csr_read_pskey_uint32(dd, seqnum++, pskey, stores, &val32); + if (err < 0) + return err; + + printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; + } + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_psset(int dd, int argc, char *argv[]) +{ + uint8_t array[64]; + uint16_t pskey, value, stores = CSR_STORES_PSRAM; + uint32_t val32; + int i, err, size, reset = 0, type = CSR_TYPE_NULL; + + memset(array, 0, sizeof(array)); + + OPT_PSKEY(2, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + type = storage[i].type; + size = storage[i].type; + break; + } + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } else { + pskey = strtol(argv[0] + 2, NULL, 16); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } + + argc--; + argv++; + + switch (type) { + case CSR_TYPE_COMPLEX: + size = pskey_size(pskey); + + if (argc != size) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < size; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i] = strtol(argv[i] + 2, NULL, 16); + else + array[i] = atoi(argv[i]); + + err = csr_write_pskey_complex(dd, seqnum++, pskey, + stores, array, size); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: + if (argc != 1) { + errno = E2BIG; + return -1; + } + + if (!strncasecmp(argv[0], "0x", 2)) + value = strtol(argv[0] + 2, NULL, 16); + else + value = atoi(argv[0]); + + err = csr_write_pskey_uint16(dd, seqnum++, pskey, stores, value); + break; + + case CSR_TYPE_UINT32: + if (argc != 1) { + errno = E2BIG; + return -1; + } + + if (!strncasecmp(argv[0], "0x", 2)) + val32 = strtol(argv[0] + 2, NULL, 16); + else + val32 = atoi(argv[0]); + + err = csr_write_pskey_uint32(dd, seqnum++, pskey, stores, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; + } + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_psclr(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t pskey, stores = CSR_STORES_PSRAM; + int i, err, reset = 0; + + OPT_PSKEY(1, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + break; + } + pskey = atoi(argv[0]); + } else + pskey = strtol(argv[0] + 2, NULL, 16); + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_write_varid_complex(dd, seqnum++, + CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_pslist(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; + int err, reset = 0; + + OPT_PSKEY(0, &stores, &reset, NULL); + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, sizeof(array)); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, sizeof(array)); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + + printf("0x%04x - %s (%d bytes)\n", pskey, + csr_pskeytostr(pskey), length * 2); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_psread(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; + char *str, val[7]; + int i, err, reset = 0; + + OPT_PSKEY(0, &stores, &reset, NULL); + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, 8); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + continue; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, + stores, array, length * 2); + if (err < 0) + continue; + + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", + str ? str : val, pskey); + for (i = 0; i < length; i++) + printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf("\n"); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_psload(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey, size, stores = CSR_STORES_PSRAM; + char *str, val[7]; + int err, reset = 0; + + OPT_PSKEY(1, &stores, &reset, NULL); + + psr_read(argv[0]); + + while (psr_get(&pskey, array, &size) == 0) { + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("Loading %s%s ... ", str ? "PSKEY_" : "", + str ? str : val); + fflush(stdout); + + err = csr_write_pskey_complex(dd, seqnum++, pskey, + stores, array, size); + + printf("%s\n", err < 0 ? "failed" : "done"); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_pscheck(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey, size; + int i; + + OPT_HELP(1, NULL); + + psr_read(argv[0]); + + while (psr_get(&pskey, array, &size) == 0) { + printf("0x%04x =", pskey); + for (i = 0; i < size; i++) + printf(" 0x%02x", array[i]); + printf("\n"); + } + + return 0; } static struct { char *str; - int (*func)(int dd, int argc, char **argv); + int (*func)(int dd, int argc, char *argv[]); char *arg; char *doc; } commands[] = { - { "builddef", cmd_builddef, "", "Get build definitions" }, - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "rand", cmd_rand, "", "Get random number" }, - { "panicarg", cmd_panicarg, "", "Get panic code argument" }, - { "faultarg", cmd_faultarg, "", "Get fault code argument" }, - { "coldreset", cmd_coldreset, "", "Perform cold reset" }, - { "warmreset", cmd_warmreset, "", "Perform warm reset" }, - { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, - { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, - { NULL }, + { "builddef", cmd_builddef, "", "Get build definitions" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "coldreset", cmd_coldreset, "", "Perform cold reset" }, + { "warmreset", cmd_warmreset, "", "Perform warm reset" }, + { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, + { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "memtypes", cmd_memtypes, NULL, "Get memory types" }, + { "psget", cmd_psget, "", "Get value for PS key" }, + { "psset", cmd_psset, " ", "Set value for PS key" }, + { "psclr", cmd_psclr, "", "Clear value for PS key" }, + { "pslist", cmd_pslist, NULL, "List all PS keys" }, + { "psread", cmd_psread, NULL, "Read all PS keys" }, + { "psload", cmd_psload, "", "Load all PS keys from PSR file" }, + { "pscheck", cmd_pscheck, "", "Check PSR file" }, + { NULL } }; static void usage(void) { - int i; + int i, pos = 0; printf("bccmd - Utility for the CSR BCCMD interface\n\n"); printf("Usage:\n" - "\tbccmd [-i ] \n\n"); + "\tbccmd [options] \n\n"); + + printf("Options:\n" + "\t-t Select the transport\n" + "\t-d Select the device\n" + "\t-h, --help Display help\n" + "\n"); printf("Commands:\n"); - for (i = 0; commands[i].str; i++) - printf("\t%-10s%-8s\t%s\n", commands[i].str, - commands[i].arg, commands[i].doc); + for (i = 0; commands[i].str; i++) + printf("\t%-10s %-14s\t%s\n", commands[i].str, + commands[i].arg ? commands[i].arg : " ", + commands[i].doc); + printf("\n"); + + printf("Keys:\n\t"); + for (i = 0; storage[i].pskey; i++) { + printf("%s ", storage[i].str); + pos += strlen(storage[i].str) + 1; + if (pos > 60) { + printf("\n\t"); + pos = 0; + } + } + printf("\n"); } static struct option main_options[] = { + { "transport", 1, 0, 't' }, + { "device", 1, 0, 'd' }, { "help", 0, 0, 'h' }, - { "device", 1, 0, 'i' }, { 0, 0, 0, 0 } }; @@ -236,16 +863,33 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0; + char *device = NULL; + int i, err, opt, dd, dev, transport = CSR_TRANSPORT_HCI; - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) { switch (opt) { + case 't': + if (!strcasecmp(optarg, "hci")) + transport = CSR_TRANSPORT_HCI; + else if (!strcasecmp(optarg, "usb")) + transport = CSR_TRANSPORT_USB; + else if (!strcasecmp(optarg, "bcsp")) + transport = CSR_TRANSPORT_BCSP; + else if (!strcasecmp(optarg, "h4")) + transport = CSR_TRANSPORT_H4; + else if (!strcasecmp(optarg, "h5")) + transport = CSR_TRANSPORT_3WIRE; + else if (!strcasecmp(optarg, "3wire")) + transport = CSR_TRANSPORT_3WIRE; + else if (!strcasecmp(optarg, "twutl")) + transport = CSR_TRANSPORT_3WIRE; + else + transport = CSR_TRANSPORT_UNKNOWN; + break; + + case 'd': case 'i': - dev = hci_devid(optarg); - if (dev < 0) { - perror("Invalid device"); - exit(1); - } + device = strdup(optarg); break; case 'h': @@ -264,6 +908,21 @@ int main(int argc, char *argv[]) exit(1); } + if (transport != CSR_TRANSPORT_HCI) { + fprintf(stderr, "Unsupported transport\n"); + exit(1); + } + + if (device) { + dev = hci_devid(device); + if (dev < 0) { + fprintf(stderr, "Device not available\n"); + exit(1); + } + free(device); + } else + dev = 0; + dd = hci_open_dev(dev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", @@ -295,7 +954,7 @@ int main(int argc, char *argv[]) if (strcasecmp(commands[i].str, argv[0])) continue; - err = commands[i].func(dd, argc - 1, argv + 1); + err = commands[i].func(dd, argc, argv); hci_close_dev(dd); diff --git a/tools/csrinit.8 b/tools/csrinit.8 deleted file mode 100644 index 35a033d9..00000000 --- a/tools/csrinit.8 +++ /dev/null @@ -1,35 +0,0 @@ -.\" -.\" This program is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2 of the License, or -.\" (at your option) any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program; if not, write to the Free Software -.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -.\" -.\" -.TH CSRINIT 8 "SEPTEMBER 8, 2005" "" "" - -.SH NAME -csrinit \- Utility for the setting up CSR ROM chips -.SH SYNOPSIS -.BR "csrinit -[ -.I options -] -.SH DESCRIPTION -.B csrinit -is used to setup the ROM chips from CSR. -.SH OPTIONS -.TP -.BI -h -Gives a list of possible options. -.SH AUTHOR -Written by Marcel Holtmann . -.br diff --git a/tools/csrinit.c b/tools/csrinit.c deleted file mode 100644 index a56dbde9..00000000 --- a/tools/csrinit.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2005 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include - -#include "csr.h" - -#ifdef NEED_USB_GET_BUSSES -static inline struct usb_bus *usb_get_busses(void) -{ - return usb_busses; -} -#endif - -#ifndef USB_DIR_OUT -#define USB_DIR_OUT 0x00 -#endif - -#ifndef USB_DIR_IN -#define USB_DIR_IN 0x80 -#endif - -static void usage(void) -{ - printf("csrinit - Utility for the setting up CSR ROM chips\n\n"); - - printf("Usage:\n" - "\tcsrinit [options]\n" - "\n"); - - printf("Options:\n" - "\t-h, --help Display help\n" - "\n"); -} - -static struct option main_options[] = { - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char *argv[]) -{ - int opt; - - while ((opt = getopt_long(argc, argv, "+h", main_options, NULL)) != -1) { - switch (opt) { - case 'h': - usage(); - exit(0); - - default: - exit(0); - } - } - - argc -= optind; - argv += optind; - optind = 0; - - if (argc < 1) { - usage(); - exit(1); - } - - usb_init(); - - return 0; -} diff --git a/tools/pskey.c b/tools/pskey.c deleted file mode 100644 index c185cf58..00000000 --- a/tools/pskey.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2005 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "csr.h" - -#define CSR_TYPE_NULL 0 -#define CSR_TYPE_ARRAY 1 -#define CSR_TYPE_UINT8 2 -#define CSR_TYPE_UINT16 3 -#define CSR_TYPE_UINT32 4 - -enum { - NONE = 0, - MEMORY, - LIST, - READ, -}; - -static char *storestostr(uint16_t stores) -{ - switch (stores) { - case 0x0000: - return "Default"; - case 0x0001: - return "psi"; - case 0x0002: - return "psf"; - case 0x0004: - return "psrom"; - case 0x0008: - return "psram"; - default: - return "Unknown"; - } -} - -static char *memorytostr(uint16_t type) -{ - switch (type) { - case 0x0000: - return "Flash memory"; - case 0x0001: - return "EEPROM"; - case 0x0002: - return "RAM (transient)"; - case 0x0003: - return "ROM (or \"read-only\" flash memory)"; - default: - return "Unknown"; - } -} - -static int cmd_memory(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[8]; - uint16_t type; - int err; - - memset(array, 0, sizeof(array)); - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, 0x4711, - CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); - if (err < 0) - return err; - - type = array[4] + (array[5] << 8); - - printf("%s (0x%04x) = %s (%d)\n", storestostr(stores), stores, - memorytostr(type), type); - - return 0; -} - -static int cmd_list(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[8]; - uint16_t length, seqnum = 0x0000, pskey = 0x0000; - int err; - - while (1) { - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, sizeof(array)); - if (err < 0) - break; - - pskey = array[4] + (array[5] << 8); - if (pskey == 0x0000) - break; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, sizeof(array)); - if (err < 0) - continue; - - length = array[2] + (array[3] << 8); - - printf("0x%04x - %s (%d bytes)\n", pskey, - csr_pskeytostr(pskey), length * 2); - } - - return 0; -} - -static int cmd_read(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[256]; - uint16_t length, seqnum = 0x0000, pskey = 0x0000; - char *str, val[7]; - int i, err; - - while (1) { - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, 8); - if (err < 0) - break; - - pskey = array[4] + (array[5] << 8); - if (pskey == 0x0000) - break; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); - if (err < 0) - continue; - - length = array[2] + (array[3] << 8); - if (length > sizeof(array) / 2) - continue; - - err = csr_read_pskey_complex(dd, seqnum++, pskey, - stores, array, length * 2); - if (err < 0) - continue; - - str = csr_pskeytoval(pskey); - if (!strcasecmp(str, "UNKNOWN")) { - sprintf(val, "0x%04x", pskey); - str = NULL; - } - - printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", - str ? str : val, pskey); - for (i = 0; i < length; i++) - printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); - printf("\n"); - } - - return 0; -} - -static int pskey_size(uint16_t pskey) -{ - switch (pskey) { - case CSR_PSKEY_BDADDR: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - return 18; - default: - return 64; - } -} - -static int write_pskey(int dd, uint16_t pskey, uint16_t stores, int type, int argc, char *argv[]) -{ - uint8_t array[64]; - uint16_t value; - uint32_t val32; - int i, err, size = sizeof(array); - - memset(array, 0, sizeof(array)); - - switch (type) { - case CSR_TYPE_ARRAY: - size = pskey_size(pskey); - - if (argc != size) { - errno = EINVAL; - return -1; - } - - for (i = 0; i < size; i++) - if (!strncasecmp(argv[0], "0x", 2)) - array[i] = strtol(argv[i] + 2, NULL, 16); - else - array[i] = atoi(argv[i]); - - err = csr_write_pskey_complex(dd, 0x4711, pskey, - stores, array, size); - break; - - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: - if (argc != 1) { - errno = E2BIG; - return -1; - } - - if (!strncasecmp(argv[0], "0x", 2)) - value = strtol(argv[0] + 2, NULL, 16); - else - value = atoi(argv[0]); - - err = csr_write_pskey_uint16(dd, 0x4711, pskey, stores, value); - break; - - case CSR_TYPE_UINT32: - if (argc != 1) { - errno = E2BIG; - return -1; - } - - if (!strncasecmp(argv[0], "0x", 2)) - val32 = strtol(argv[0] + 2, NULL, 16); - else - val32 = atoi(argv[0]); - - err = csr_write_pskey_uint32(dd, 0x4711, pskey, stores, val32); - break; - - default: - errno = EFAULT; - err = -1; - break; - } - - return err; -} - -static int read_pskey(int dd, uint16_t pskey, uint16_t stores, int type) -{ - uint8_t array[64]; - uint16_t value = 0; - uint32_t val32 = 0; - int i, err, size = sizeof(array); - - memset(array, 0, sizeof(array)); - - switch (type) { - case CSR_TYPE_ARRAY: - size = pskey_size(pskey); - - err = csr_read_pskey_complex(dd, 0x4711, pskey, stores, array, size); - if (err < 0) - return err; - - printf("%s:", csr_pskeytostr(pskey)); - for (i = 0; i < size; i++) - printf(" 0x%02x", array[i]); - printf("\n"); - break; - - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: - err = csr_read_pskey_uint16(dd, 0x4711, pskey, stores, &value); - if (err < 0) - return err; - - printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); - break; - - case CSR_TYPE_UINT32: - err = csr_read_pskey_uint32(dd, 0x4711, pskey, stores, &val32); - if (err < 0) - return err; - - printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); - break; - - default: - errno = EFAULT; - err = -1; - break; - } - - return err; -} - -static int delete_pskey(int dd, uint16_t pskey, uint16_t stores) -{ - uint8_t array[8]; - int err; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_write_varid_complex(dd, 0x4711, - CSR_VARID_PS_CLR_STORES, array, sizeof(array)); - - return err; -} - -static struct { - uint16_t pskey; - int type; - char *str; -} storage[] = { - { CSR_PSKEY_BDADDR, CSR_TYPE_ARRAY, "bdaddr" }, - { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, "country" }, - { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, "devclass" }, - { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, - { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, - { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, - { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, "commands" }, - { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, - { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, - { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, "hciextn" }, - { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, - { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, - { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, - { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, "anafreq" }, - { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, "anaftrim" }, - { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, - { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, - { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, - { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, - { 0x0000, CSR_TYPE_NULL, NULL }, -}; - -static void usage(void) -{ - int i, pos = 0; - - printf("pskey - Utility for changing CSR persistent storage\n\n"); - printf("Usage:\n" - "\tpskey [-i ] [-r] [-s stores] [value]\n" - "\tpskey [-i ] [-r] [-s stores] --clear \n" - "\tpskey [-i ] [-s stores] --memory\n" - "\tpskey [-i ] [-s stores] --list\n" - "\tpskey [-i ] [-s stores] --read\n\n"); - - printf("Keys:\n\t"); - for (i = 0; storage[i].pskey; i++) { - printf("%s ", storage[i].str); - pos += strlen(storage[i].str) + 1; - if (pos > 60) { - printf("\n\t"); - pos = 0; - } - } - printf("\n"); -} - -static struct option main_options[] = { - { "device", 1, 0, 'i' }, - { "reset", 0, 0, 'r' }, - { "stores", 1, 0, 's' }, - { "clear", 0, 0, 'c' }, - { "memory", 0, 0, 'M' }, - { "list", 0, 0, 'L' }, - { "read", 0, 0, 'R' }, - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char *argv[]) -{ - struct hci_dev_info di; - struct hci_version ver; - uint16_t stores = 0x0001 | 0x0002 | 0x0008; - int i, err, dd, opt, dev = 0, reset = 0, clear = 0, mode = NONE; - - while ((opt=getopt_long(argc, argv, "+i:rs:cMLRh", main_options, NULL)) != -1) { - switch (opt) { - case 'i': - dev = hci_devid(optarg); - if (dev < 0) { - perror("Invalid device"); - exit(1); - } - break; - - case 'r': - reset = 1; - break; - - case 's': - if (!strcasecmp(optarg, "default")) - stores = 0x0000; - else if (!strcasecmp(optarg, "implementation")) - stores = 0x0001; - else if (!strcasecmp(optarg, "factory")) - stores = 0x0002; - else if (!strcasecmp(optarg, "rom")) - stores = 0x0004; - else if (!strcasecmp(optarg, "ram")) - stores = 0x0008; - else if (!strcasecmp(optarg, "psi")) - stores = 0x0001; - else if (!strcasecmp(optarg, "psf")) - stores = 0x0002; - else if (!strcasecmp(optarg, "psrom")) - stores = 0x0004; - else if (!strcasecmp(optarg, "psram")) - stores = 0x0008; - else if (!strncasecmp(optarg, "0x", 2)) - stores = strtol(optarg, NULL, 16); - else - stores = atoi(optarg); - break; - - case 'c': - clear = 1; - break; - - case 'M': - mode = MEMORY; - break; - - case 'L': - mode = LIST; - break; - - case 'R': - mode = READ; - break; - - case 'h': - default: - usage(); - exit(0); - } - } - - argc -= optind; - argv += optind; - optind = 0; - - if (mode == NONE && argc < 1) { - usage(); - exit(1); - } - - dd = hci_open_dev(dev); - if (dd < 0) { - fprintf(stderr, "Can't open device hci%d: %s (%d)\n", - dev, strerror(errno), errno); - exit(1); - } - - if (hci_devinfo(dev, &di) < 0) { - fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (ver.manufacturer != 10) { - fprintf(stderr, "Unsupported manufacturer\n"); - hci_close_dev(dd); - exit(1); - } - - if (mode > 0) { - switch (mode) { - case MEMORY: - err = cmd_memory(dd, stores, argc, argv); - break; - case LIST: - err = cmd_list(dd, stores, argc, argv); - break; - case READ: - err = cmd_read(dd, stores, argc, argv); - break; - default: - usage(); - err = -1; - break; - } - - hci_close_dev(dd); - exit(err < 0 ? 1 : 0); - } - - for (i = 0; storage[i].pskey; i++) { - if (strcasecmp(storage[i].str, argv[0])) - continue; - - if (argc > 1) { - err = write_pskey(dd, storage[i].pskey, stores, - storage[i].type, argc - 1, argv + 1); - - if (!err && reset) - csr_write_varid_valueless(dd, 0x0000, - CSR_VARID_WARM_RESET); - } else { - if (clear) - err = delete_pskey(dd, storage[i].pskey, stores); - else - err = read_pskey(dd, storage[i].pskey, - stores, storage[i].type); - } - - hci_close_dev(dd); - - if (err < 0) { - fprintf(stderr, "Can't %s persistent storage: %s (%d)\n", - argc > 1 ? "write" : "read", strerror(errno), errno); - exit(1); - } - - exit(0); - } - - fprintf(stderr, "Unsupported persistent storage\n"); - - hci_close_dev(dd); - - exit(1); -} -- cgit From 14d3b87c5357f5df85d167084ba8048a48f8df7e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:21:19 +0000 Subject: Some more big endian fixes --- tools/dfutool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/dfutool.c b/tools/dfutool.c index 0de67bb1..eb087011 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -211,9 +211,9 @@ static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffi if (status.bState == DFU_STATE_DFU_IDLE) { if (suffix) { - suffix->idVendor = 0x0000; - suffix->idProduct = 0x0000; - suffix->bcdDevice = 0x0000; + suffix->idVendor = cpu_to_le16(0x0000); + suffix->idProduct = cpu_to_le16(0x0000); + suffix->bcdDevice = cpu_to_le16(0x0000); } return udev; } @@ -262,7 +262,7 @@ static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffi if (dev->descriptor.bDeviceClass != USB_CLASS_APPLICATION) continue; - if (suffix && dev->descriptor.idVendor != suffix->idVendor) + if (suffix && dev->descriptor.idVendor != le16_to_cpu(suffix->idVendor)) continue; if (num > 9 || get_interface_number(dev) != 0) -- cgit From 226949879e3ed5578d678c817a955bd38597eddb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 09:31:00 +0000 Subject: Fix the memory types command --- tools/bccmd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index e41f08f5..902555e5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -335,21 +335,21 @@ static int cmd_memtypes(int dd, int argc, char *argv[]) for (i = 0; i < 4; i++) { memset(array, 0, sizeof(array)); - array[2] = stores[i] & 0xff; - array[3] = stores[i] >> 8; + array[0] = stores[i] & 0xff; + array[1] = stores[i] >> 8; err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); if (err < 0) - break; + continue; - type = array[4] + (array[5] << 8); + type = array[2] + (array[3] << 8); printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]), stores[i], memorytostr(type), type); } - return err; + return 0; } static struct option pskey_options[] = { -- cgit From ff1e0556d0a88335924aea13cfbce67de82d9c19 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 09:41:28 +0000 Subject: Fix parsing of the PS key identifier --- tools/bccmd.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index 902555e5..50de4f17 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -424,6 +424,10 @@ static int cmd_psget(int dd, int argc, char *argv[]) OPT_PSKEY(1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -433,9 +437,6 @@ static int cmd_psget(int dd, int argc, char *argv[]) size = storage[i].type; break; } - pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); } else { pskey = strtol(argv[0] + 2, NULL, 16); type = CSR_TYPE_COMPLEX; @@ -511,6 +512,10 @@ static int cmd_psset(int dd, int argc, char *argv[]) OPT_PSKEY(2, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -520,9 +525,6 @@ static int cmd_psset(int dd, int argc, char *argv[]) size = storage[i].type; break; } - pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); } else { pskey = strtol(argv[0] + 2, NULL, 16); type = CSR_TYPE_COMPLEX; @@ -601,6 +603,8 @@ static int cmd_psclr(int dd, int argc, char *argv[]) OPT_PSKEY(1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -608,7 +612,6 @@ static int cmd_psclr(int dd, int argc, char *argv[]) pskey = storage[i].pskey; break; } - pskey = atoi(argv[0]); } else pskey = strtol(argv[0] + 2, NULL, 16); -- cgit From 254b7892bcfdbbc4ba6c8118f3d0aafc424d1f58 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 14:32:29 +0000 Subject: Only use psi and psf stores as default --- tools/bccmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index 50de4f17..357620f5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -48,7 +48,7 @@ #define CSR_STORES_PSF (0x0002) #define CSR_STORES_PSROM (0x0004) #define CSR_STORES_PSRAM (0x0008) -#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF | CSR_STORES_PSRAM) +#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF) #define CSR_TYPE_NULL 0 #define CSR_TYPE_COMPLEX 1 -- cgit From db176529529c142333f668f2c1334753f7f406bf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Nov 2005 00:04:15 +0000 Subject: Include checks for mmap() returning NULL --- tools/csr.c | 2 +- tools/oui.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 698122dc..3f671740 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2697,7 +2697,7 @@ int psr_read(const char *filename) } map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (map == MAP_FAILED) { + if (!map || map == MAP_FAILED) { err = -errno; goto close; } diff --git a/tools/oui.c b/tools/oui.c index 0a1d67bc..6ebf91a5 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -65,7 +65,7 @@ char *ouitocomp(const char *oui) memset(str, 0, 128); map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (map == MAP_FAILED) { + if (!map || map == MAP_FAILED) { free(str); close(fd); return NULL; -- cgit From fee89e0ae84a9fe54252872e6badec024573f70d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Nov 2005 14:44:14 +0000 Subject: Add build ids for Unified 21c firmwares --- tools/csr.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 3f671740..c101422b 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -297,6 +297,29 @@ static struct { { 2387, "Unified 21a" }, { 2423, "Unified 21a" }, { 2424, "Unified 21a" }, + { 2623, "Unified 21c" }, + { 2624, "Unified 21c" }, + { 2625, "Unified 21c" }, + { 2626, "Unified 21c" }, + { 2627, "Unified 21c" }, + { 2628, "Unified 21c" }, + { 2629, "Unified 21c" }, + { 2630, "Unified 21c" }, + { 2631, "Unified 21c" }, + { 2632, "Unified 21c" }, + { 2633, "Unified 21c" }, + { 2634, "Unified 21c" }, + { 2635, "Unified 21c" }, + { 2636, "Unified 21c" }, + { 2649, "Unified 21c" }, + { 2650, "Unified 21c" }, + { 2651, "Unified 21c" }, + { 2652, "Unified 21c" }, + { 2653, "Unified 21c" }, + { 2654, "Unified 21c" }, + { 2655, "Unified 21c" }, + { 2656, "Unified 21c" }, + { 2658, "Unified 21c" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, -- cgit From 2ba0839002159cd293bb1a3d85645f04010cf33b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 20:23:47 +0000 Subject: Add USB transport to the bccmd utility --- tools/Makefile.am | 4 +- tools/bccmd.c | 465 +++++++++++++++++++++++++++++------------------------- tools/csr.c | 4 +- tools/csr.h | 12 +- tools/csr_hci.c | 160 +++++++++++++++++++ tools/csr_usb.c | 173 ++++++++++++++++++++ 6 files changed, 596 insertions(+), 222 deletions(-) create mode 100644 tools/csr_hci.c create mode 100644 tools/csr_usb.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 238a2df1..9d7065b2 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -52,8 +52,8 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c -bccmd_LDADD = @BLUEZ_LIBS@ +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c +bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ endif if AVCTRL diff --git a/tools/bccmd.c b/tools/bccmd.c index 357620f5..f39686eb 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -59,7 +59,56 @@ #define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX #define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX -static uint16_t seqnum = 0x0000; +static inline int transport_open(int transport, char *device) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_open_hci(device); + case CSR_TRANSPORT_USB: + return csr_open_usb(device); + default: + fprintf(stderr, "Unsupported transport\n"); + return -1; + } +} + +static inline void transport_close(int transport) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + csr_close_hci(); + break; + case CSR_TRANSPORT_USB: + csr_close_usb(); + break; + } +} + +static inline int transport_read(int transport, uint16_t varid, uint8_t *value, uint16_t length) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_read_hci(varid, value, length); + case CSR_TRANSPORT_USB: + return csr_read_usb(varid, value, length); + default: + errno = EOPNOTSUPP; + return -1; + } +} + +static inline int transport_write(int transport, uint16_t varid, uint8_t *value, uint16_t length) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_write_hci(varid, value, length); + case CSR_TRANSPORT_USB: + return csr_write_usb(varid, value, length); + default: + errno = EOPNOTSUPP; + return -1; + } +} static struct { uint16_t pskey; @@ -89,20 +138,6 @@ static struct { { 0x0000 }, }; -static int pskey_size(uint16_t pskey) -{ - switch (pskey) { - case CSR_PSKEY_BDADDR: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - return 18; - default: - return 64; - } -} - static char *storestostr(uint16_t stores) { switch (stores) { @@ -167,9 +202,9 @@ static int opt_help(int argc, char *argv[], int *help) argc -= optind; argv += optind; optind = 0; \ OPT_RANGE((range)) -static int cmd_builddef(int dd, int argc, char *argv[]) +static int cmd_builddef(int transport, int argc, char *argv[]) { - uint8_t buf[8]; + uint8_t array[8]; uint16_t def = 0x0000, nextdef = 0x0000; int err = 0; @@ -178,18 +213,17 @@ static int cmd_builddef(int dd, int argc, char *argv[]) printf("Build definitions:\n"); while (1) { - memset(buf, 0, sizeof(buf)); - buf[0] = def & 0xff; - buf[1] = def >> 8; + memset(array, 0, sizeof(array)); + array[0] = def & 0xff; + array[1] = def >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_GET_NEXT_BUILDDEF, buf, sizeof(buf)); + err = transport_read(transport, CSR_VARID_GET_NEXT_BUILDDEF, array, 8); if (err < 0) { errno = -err; break; } - nextdef = buf[2] | (buf[3] << 8); + nextdef = array[2] | (array[3] << 8); if (nextdef == 0x0000) break; @@ -202,9 +236,9 @@ static int cmd_builddef(int dd, int argc, char *argv[]) return err; } -static int cmd_keylen(int dd, int argc, char *argv[]) +static int cmd_keylen(int transport, int argc, char *argv[]) { - uint8_t buf[8]; + uint8_t array[8]; uint16_t handle, keylen; int err; @@ -212,120 +246,139 @@ static int cmd_keylen(int dd, int argc, char *argv[]) handle = atoi(argv[0]); - memset(buf, 0, sizeof(buf)); - buf[0] = handle & 0xff; - buf[1] = handle >> 8; + memset(array, 0, sizeof(array)); + array[0] = handle & 0xff; + array[1] = handle >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); + err = transport_read(transport, CSR_VARID_CRYPT_KEY_LENGTH, array, 8); if (err < 0) { errno = -err; return -1; } - handle = buf[0] | (buf[1] << 8); - keylen = buf[2] | (buf[3] << 8); + handle = array[0] | (array[1] << 8); + keylen = array[2] | (array[3] << 8); printf("Crypt key length: %d bit\n", keylen * 8); return 0; } -static int cmd_clock(int dd, int argc, char *argv[]) +static int cmd_clock(int transport, int argc, char *argv[]) { - uint32_t clock = 0; + uint8_t array[8]; + uint32_t clock; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint32(dd, seqnum++, CSR_VARID_BT_CLOCK, &clock); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_BT_CLOCK, array, 8); if (err < 0) { errno = -err; return -1; } + clock = array[2] | (array[3] << 8) | (array[0] << 16) | (array[1] << 24); + printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock); return 0; } -static int cmd_rand(int dd, int argc, char *argv[]) +static int cmd_rand(int transport, int argc, char *argv[]) { - uint16_t rand = 0; + uint8_t array[8]; + uint16_t rand; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_RAND, &rand); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_RAND, array, 8); if (err < 0) { errno = -err; return -1; } + rand = array[0] | (array[1] << 8); + printf("Random number: 0x%02x (%d)\n", rand, rand); return 0; } -static int cmd_panicarg(int dd, int argc, char *argv[]) +static int cmd_panicarg(int transport, int argc, char *argv[]) { - uint16_t error = 0; + uint8_t array[8]; + uint16_t error; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_PANIC_ARG, &error); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_PANIC_ARG, array, 8); if (err < 0) { errno = -err; return -1; } + error = array[0] | (array[1] << 8); + printf("Panic code: 0x%02x (%s)\n", error, error < 0x100 ? "valid" : "invalid"); return 0; } -static int cmd_faultarg(int dd, int argc, char *argv[]) +static int cmd_faultarg(int transport, int argc, char *argv[]) { - uint16_t error = 0; + uint8_t array[8]; + uint16_t error; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_FAULT_ARG, &error); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_FAULT_ARG, array, 8); if (err < 0) { errno = -err; return -1; } + error = array[0] | (array[1] << 8); + printf("Fault code: 0x%02x (%s)\n", error, error < 0x100 ? "valid" : "invalid"); return 0; } -static int cmd_coldreset(int dd, int argc, char *argv[]) +static int cmd_coldreset(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_COLD_RESET); + return transport_write(transport, CSR_VARID_COLD_RESET, NULL, 0); } -static int cmd_warmreset(int dd, int argc, char *argv[]) +static int cmd_warmreset(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + return transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); } -static int cmd_disabletx(int dd, int argc, char *argv[]) +static int cmd_disabletx(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_DISABLE_TX); + return transport_write(transport, CSR_VARID_DISABLE_TX, NULL, 0); } -static int cmd_enabletx(int dd, int argc, char *argv[]) +static int cmd_enabletx(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_ENABLE_TX); + return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0); } -static int cmd_memtypes(int dd, int argc, char *argv[]) +static int cmd_memtypes(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 }; @@ -338,8 +391,7 @@ static int cmd_memtypes(int dd, int argc, char *argv[]) array[0] = stores[i] & 0xff; array[1] = stores[i] >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_MEMORY_TYPE, array, 8); if (err < 0) continue; @@ -412,12 +464,12 @@ static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int * argc -= optind; argv += optind; optind = 0; \ OPT_RANGE((range)) -static int cmd_psget(int dd, int argc, char *argv[]) +static int cmd_psget(int transport, int argc, char *argv[]) { - uint8_t array[64]; + uint8_t array[128]; uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT; uint32_t val32; - int i, err, size, reset = 0, type = CSR_TYPE_NULL; + int i, err, reset = 0; memset(array, 0, sizeof(array)); @@ -425,87 +477,74 @@ static int cmd_psget(int dd, int argc, char *argv[]) if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; pskey = storage[i].pskey; - type = storage[i].type; - size = storage[i].type; break; } - } else { + } else pskey = strtol(argv[0] + 2, NULL, 16); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); - } - - switch (type) { - case CSR_TYPE_COMPLEX: - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); - if (err < 0) - return err; - - length = array[2] + (array[3] << 8); - if (length > sizeof(array) / 2) - return -EIO; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; - err = csr_read_pskey_complex(dd, seqnum++, pskey, stores, - array, length * 2); - if (err < 0) - return err; + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; - printf("%s:", csr_pskeytostr(pskey)); - for (i = 0; i < length; i++) - printf(" 0x%02x%02x", array[i * 2], array[(i * 2) + 1]); - printf("\n"); - break; - - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: - err = csr_read_pskey_uint16(dd, seqnum++, pskey, stores, &value); - if (err < 0) - return err; + length = array[2] + (array[3] << 8); + if (length + 6 > sizeof(array) / 2) + return -EIO; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2); + if (err < 0) + return err; + + switch (length) { + case 1: + value = array[6] | (array[7] << 8); printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); break; - case CSR_TYPE_UINT32: - err = csr_read_pskey_uint32(dd, seqnum++, pskey, stores, &val32); - if (err < 0) - return err; - + case 2: + val32 = array[8] | (array[9] << 8) | (array[6] << 16) | (array[7] << 24); printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); break; default: - errno = EFAULT; - err = -1; + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < length; i++) + printf(" 0x%02x%02x", array[(i * 2) + 6], array[(i * 2) + 7]); + printf("\n"); break; } - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_psset(int dd, int argc, char *argv[]) +static int cmd_psset(int transport, int argc, char *argv[]) { - uint8_t array[64]; - uint16_t pskey, value, stores = CSR_STORES_PSRAM; + uint8_t array[128]; + uint16_t pskey, length, value, stores = CSR_STORES_PSRAM; uint32_t val32; - int i, err, size, reset = 0, type = CSR_TYPE_NULL; + int i, err, reset = 0; memset(array, 0, sizeof(array)); @@ -513,48 +552,44 @@ static int cmd_psset(int dd, int argc, char *argv[]) if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; pskey = storage[i].pskey; - type = storage[i].type; - size = storage[i].type; break; } - } else { + } else pskey = strtol(argv[0] + 2, NULL, 16); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); - } - argc--; - argv++; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; - switch (type) { - case CSR_TYPE_COMPLEX: - size = pskey_size(pskey); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; - if (argc != size) { - errno = EINVAL; - return -1; - } + length = array[2] + (array[3] << 8); + if (length + 6 > sizeof(array) / 2) + return -EIO; - for (i = 0; i < size; i++) - if (!strncasecmp(argv[0], "0x", 2)) - array[i] = strtol(argv[i] + 2, NULL, 16); - else - array[i] = atoi(argv[i]); + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; - err = csr_write_pskey_complex(dd, seqnum++, pskey, - stores, array, size); - break; + argc--; + argv++; - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: + switch (length) { + case 1: if (argc != 1) { errno = E2BIG; return -1; @@ -565,10 +600,11 @@ static int cmd_psset(int dd, int argc, char *argv[]) else value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, seqnum++, pskey, stores, value); + array[6] = value & 0xff; + array[7] = value >> 8; break; - case CSR_TYPE_UINT32: + case 2: if (argc != 1) { errno = E2BIG; return -1; @@ -579,22 +615,37 @@ static int cmd_psset(int dd, int argc, char *argv[]) else val32 = atoi(argv[0]); - err = csr_write_pskey_uint32(dd, seqnum++, pskey, stores, val32); + array[6] = (val32 & 0xff0000) >> 16; + array[7] = val32 >> 24; + array[8] = val32 & 0xff; + array[9] = (val32 & 0xff00) >> 8; break; default: - errno = EFAULT; - err = -1; + if (argc != length * 2) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < length * 2; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i + 6] = strtol(argv[i] + 2, NULL, 16); + else + array[i + 6] = atoi(argv[i]); break; } - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + err = transport_write(transport, CSR_VARID_PS, array, (length + 3) * 2); + if (err < 0) + return err; + + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_psclr(int dd, int argc, char *argv[]) +static int cmd_psclr(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t pskey, stores = CSR_STORES_PSRAM; @@ -621,16 +672,17 @@ static int cmd_psclr(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_write_varid_complex(dd, seqnum++, - CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + err = transport_write(transport, CSR_VARID_PS_CLR_STORES, array, 8); + if (err < 0) + return err; - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_pslist(int dd, int argc, char *argv[]) +static int cmd_pslist(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; @@ -645,8 +697,7 @@ static int cmd_pslist(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8); if (err < 0) break; @@ -660,8 +711,7 @@ static int cmd_pslist(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); if (err < 0) continue; @@ -672,12 +722,12 @@ static int cmd_pslist(int dd, int argc, char *argv[]) } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_psread(int dd, int argc, char *argv[]) +static int cmd_psread(int transport, int argc, char *argv[]) { uint8_t array[256]; uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; @@ -693,8 +743,7 @@ static int cmd_psread(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, 8); + err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8); if (err < 0) break; @@ -708,17 +757,23 @@ static int cmd_psread(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); if (err < 0) continue; length = array[2] + (array[3] << 8); - if (length > sizeof(array) / 2) + if (length + 6 > sizeof(array) / 2) continue; - err = csr_read_pskey_complex(dd, seqnum++, pskey, - stores, array, length * 2); + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2); if (err < 0) continue; @@ -731,20 +786,20 @@ static int cmd_psread(int dd, int argc, char *argv[]) printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", str ? str : val, pskey); for (i = 0; i < length; i++) - printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf(" %02x%02x", array[(i * 2) + 7], array[(i * 2) + 6]); printf("\n"); } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_psload(int dd, int argc, char *argv[]) +static int cmd_psload(int transport, int argc, char *argv[]) { uint8_t array[256]; - uint16_t pskey, size, stores = CSR_STORES_PSRAM; + uint16_t pskey, length, size, stores = CSR_STORES_PSRAM; char *str, val[7]; int err, reset = 0; @@ -752,7 +807,10 @@ static int cmd_psload(int dd, int argc, char *argv[]) psr_read(argv[0]); - while (psr_get(&pskey, array, &size) == 0) { + memset(array, 0, sizeof(array)); + size = sizeof(array) - 6; + + while (psr_get(&pskey, array + 6, &size) == 0) { str = csr_pskeytoval(pskey); if (!strcasecmp(str, "UNKNOWN")) { sprintf(val, "0x%04x", pskey); @@ -763,19 +821,30 @@ static int cmd_psload(int dd, int argc, char *argv[]) str ? str : val); fflush(stdout); - err = csr_write_pskey_complex(dd, seqnum++, pskey, - stores, array, size); + length = size / 2; + + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_write(transport, CSR_VARID_PS, array, size + 6); printf("%s\n", err < 0 ? "failed" : "done"); + + memset(array, 0, sizeof(array)); + size = sizeof(array) - 6; } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_pscheck(int dd, int argc, char *argv[]) +static int cmd_pscheck(int transport, int argc, char *argv[]) { uint8_t array[256]; uint16_t pskey, size; @@ -797,7 +866,7 @@ static int cmd_pscheck(int dd, int argc, char *argv[]) static struct { char *str; - int (*func)(int dd, int argc, char *argv[]); + int (*func)(int transport, int argc, char *argv[]); char *arg; char *doc; } commands[] = { @@ -864,10 +933,8 @@ static struct option main_options[] = { int main(int argc, char *argv[]) { - struct hci_dev_info di; - struct hci_version ver; char *device = NULL; - int i, err, opt, dd, dev, transport = CSR_TRANSPORT_HCI; + int i, err, opt, transport = CSR_TRANSPORT_HCI; while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) { switch (opt) { @@ -911,55 +978,19 @@ int main(int argc, char *argv[]) exit(1); } - if (transport != CSR_TRANSPORT_HCI) { - fprintf(stderr, "Unsupported transport\n"); + if (transport_open(transport, device) < 0) exit(1); - } - if (device) { - dev = hci_devid(device); - if (dev < 0) { - fprintf(stderr, "Device not available\n"); - exit(1); - } + if (device) free(device); - } else - dev = 0; - - dd = hci_open_dev(dev); - if (dd < 0) { - fprintf(stderr, "Can't open device hci%d: %s (%d)\n", - dev, strerror(errno), errno); - exit(1); - } - - if (hci_devinfo(dev, &di) < 0) { - fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (ver.manufacturer != 10) { - fprintf(stderr, "Unsupported manufacturer\n"); - hci_close_dev(dd); - exit(1); - } for (i = 0; commands[i].str; i++) { if (strcasecmp(commands[i].str, argv[0])) continue; - err = commands[i].func(dd, argc, argv); + err = commands[i].func(transport, argc, argv); - hci_close_dev(dd); + transport_close(transport); if (err < 0) { fprintf(stderr, "Can't execute command: %s (%d)\n", @@ -972,7 +1003,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Unsupported command\n"); - hci_close_dev(dd); + transport_close(transport); exit(1); } diff --git a/tools/csr.c b/tools/csr.c index c101422b..10856749 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2354,7 +2354,7 @@ int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *va rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; + rq.clen = sizeof(cmd) + length + 1; rq.rparam = rp; rq.rlen = sizeof(rp); @@ -2393,7 +2393,7 @@ int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *val rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; + rq.clen = sizeof(cmd) + length + 1; rq.rparam = rp; rq.rlen = sizeof(rp); diff --git a/tools/csr.h b/tools/csr.h index cd807c38..ec066b81 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -63,7 +63,7 @@ #define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */ #define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ -#define CSR_VARID_PS 0x7002 /* complex */ +#define CSR_VARID_PS 0x7003 /* complex */ #define CSR_PSKEY_BDADDR 0x0001 /* bdaddr / uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ #define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ @@ -502,6 +502,16 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); char *csr_pskeytoval(uint16_t pskey); +int csr_open_hci(char *device); +int csr_read_hci(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_hci(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_hci(void); + +int csr_open_usb(char *device); +int csr_read_usb(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_usb(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_usb(void); + int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); diff --git a/tools/csr_hci.c b/tools/csr_hci.c new file mode 100644 index 00000000..ebeb8aa7 --- /dev/null +++ b/tools/csr_hci.c @@ -0,0 +1,160 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + +static uint16_t seqnum = 0x0000; + +static int dd = -1; + +int csr_open_hci(char *device) +{ + struct hci_dev_info di; + struct hci_version ver; + int dev = 0; + + if (device) { + dev = hci_devid(device); + if (dev < 0) { + fprintf(stderr, "Device not available\n"); + return -1; + } + } + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + return -1; + } + + if (hci_devinfo(dev, &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + return -1; + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + return -1; + } + + if (ver.manufacturer != 10) { + fprintf(stderr, "Unsupported manufacturer\n"); + hci_close_dev(dd); + return -1; + } + + return 0; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + unsigned char cp[254], rp[254]; + struct hci_request rq; + uint8_t cmd[10]; + uint16_t size; + + size = (length < 8) ? 9 : ((length + 1) / 2) + 5; + + cmd[0] = command & 0xff; + cmd[1] = command >> 8; + cmd[2] = size & 0xff; + cmd[3] = size >> 8; + cmd[4] = seqnum & 0xff; + cmd[5] = seqnum >> 8; + cmd[6] = varid & 0xff; + cmd[7] = varid >> 8; + cmd[8] = 0x00; + cmd[9] = 0x00; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + memcpy(cp + 11, value, length); + + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return hci_send_cmd(dd, OGF_VENDOR_CMD, 0x00, (size * 2) + 1, cp); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = (size * 2) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 11, length); + + return 0; +} + +int csr_read_hci(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_hci(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_hci(void) +{ + hci_close_dev(dd); +} diff --git a/tools/csr_usb.c b/tools/csr_usb.c new file mode 100644 index 00000000..2c29251f --- /dev/null +++ b/tools/csr_usb.c @@ -0,0 +1,173 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "csr.h" + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif + +static uint16_t seqnum = 0x0000; + +static struct usb_dev_handle *udev = NULL; + +int csr_open_usb(char *device) +{ + struct usb_bus *bus; + struct usb_device *dev; + + usb_init(); + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.bDeviceClass == USB_CLASS_HUB) + continue; + + if (dev->descriptor.idVendor != 0x0a12 || + dev->descriptor.idProduct != 0x0001) + continue; + + goto found; + } + } + + fprintf(stderr, "Device not available\n"); + + return -1; + +found: + udev = usb_open(dev); + if (!udev) { + fprintf(stderr, "Can't open device: %s (%d)\n", + strerror(errno), errno); + return -1; + } + + if (usb_claim_interface(udev, 0) < 0) { + fprintf(stderr, "Can't claim interface: %s (%d)\n", + strerror(errno), errno); + usb_close(udev); + return -1; + } + + return 0; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + unsigned char cp[254], rp[254]; + uint8_t cmd[10]; + uint16_t size; + int len, offset = 0; + + size = (length < 8) ? 9 : ((length + 1) / 2) + 5; + + cmd[0] = command & 0xff; + cmd[1] = command >> 8; + cmd[2] = size & 0xff; + cmd[3] = size >> 8; + cmd[4] = seqnum & 0xff; + cmd[5] = seqnum >> 8; + cmd[6] = varid & 0xff; + cmd[7] = varid >> 8; + cmd[8] = 0x00; + cmd[9] = 0x00; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0x00; + cp[1] = 0xfc; + cp[2] = (size * 2) + 1; + cp[3] = 0xc2; + memcpy(cp + 4, cmd, sizeof(cmd)); + memcpy(cp + 14, value, length); + + usb_interrupt_read(udev, 0x81, (void *) rp, sizeof(rp), 2); + + if (usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_DEVICE, + 0, 0, 0, (void *) cp, (size * 2) + 4, 1000) < 0) + return -1; + + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return 0; + } + + do { + len = usb_interrupt_read(udev, 0x81, + (void *) (rp + offset), sizeof(rp), 10); + offset += len; + } while (len > 0); + + if (rp[0] != 0xff || rp[2] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[11] + (rp[12] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 13, length); + + return 0; +} + +int csr_read_usb(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_usb(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_usb(void) +{ + usb_release_interface(udev, 0); + usb_close(udev); +} -- cgit From 016c7033f4b73e35ebd66ada66093f3c5fe9fbff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 21:05:14 +0000 Subject: Add skeletons for BCSP and H4 transports --- tools/Makefile.am | 2 +- tools/bccmd.c | 42 +++++++++++++++++++++++++++----------- tools/csr.h | 10 ++++++++++ tools/csr_bcsp.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr_h4.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 13 deletions(-) create mode 100644 tools/csr_bcsp.c create mode 100644 tools/csr_h4.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 9d7065b2..a038582a 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -52,7 +52,7 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ endif diff --git a/tools/bccmd.c b/tools/bccmd.c index f39686eb..3bdf702a 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -66,24 +66,16 @@ static inline int transport_open(int transport, char *device) return csr_open_hci(device); case CSR_TRANSPORT_USB: return csr_open_usb(device); + case CSR_TRANSPORT_BCSP: + return csr_open_bcsp(device); + case CSR_TRANSPORT_H4: + return csr_open_h4(device); default: fprintf(stderr, "Unsupported transport\n"); return -1; } } -static inline void transport_close(int transport) -{ - switch (transport) { - case CSR_TRANSPORT_HCI: - csr_close_hci(); - break; - case CSR_TRANSPORT_USB: - csr_close_usb(); - break; - } -} - static inline int transport_read(int transport, uint16_t varid, uint8_t *value, uint16_t length) { switch (transport) { @@ -91,6 +83,10 @@ static inline int transport_read(int transport, uint16_t varid, uint8_t *value, return csr_read_hci(varid, value, length); case CSR_TRANSPORT_USB: return csr_read_usb(varid, value, length); + case CSR_TRANSPORT_BCSP: + return csr_read_bcsp(varid, value, length); + case CSR_TRANSPORT_H4: + return csr_read_h4(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -104,12 +100,34 @@ static inline int transport_write(int transport, uint16_t varid, uint8_t *value, return csr_write_hci(varid, value, length); case CSR_TRANSPORT_USB: return csr_write_usb(varid, value, length); + case CSR_TRANSPORT_BCSP: + return csr_write_bcsp(varid, value, length); + case CSR_TRANSPORT_H4: + return csr_write_h4(varid, value, length); default: errno = EOPNOTSUPP; return -1; } } +static inline void transport_close(int transport) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + csr_close_hci(); + break; + case CSR_TRANSPORT_USB: + csr_close_usb(); + break; + case CSR_TRANSPORT_BCSP: + csr_close_bcsp(); + break; + case CSR_TRANSPORT_H4: + csr_close_h4(); + break; + } +} + static struct { uint16_t pskey; int type; diff --git a/tools/csr.h b/tools/csr.h index ec066b81..01e4d803 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -512,6 +512,16 @@ int csr_read_usb(uint16_t varid, uint8_t *value, uint16_t length); int csr_write_usb(uint16_t varid, uint8_t *value, uint16_t length); void csr_close_usb(void); +int csr_open_bcsp(char *device); +int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_bcsp(void); + +int csr_open_h4(char *device); +int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_h4(void); + int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c new file mode 100644 index 00000000..8847fec5 --- /dev/null +++ b/tools/csr_bcsp.c @@ -0,0 +1,60 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +static uint16_t seqnum = 0x0000; + +int csr_open_bcsp(char *device) +{ + fprintf(stderr, "Transport not implemented\n"); + + return -1; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + errno = EIO; + + return -1; +} + +int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_bcsp(void) +{ +} diff --git a/tools/csr_h4.c b/tools/csr_h4.c new file mode 100644 index 00000000..9140d30d --- /dev/null +++ b/tools/csr_h4.c @@ -0,0 +1,60 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +static uint16_t seqnum = 0x0000; + +int csr_open_h4(char *device) +{ + fprintf(stderr, "Transport not implemented\n"); + + return -1; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + errno = EIO; + + return -1; +} + +int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_h4(void) +{ +} -- cgit From ae3ff343f09da4e2f1b63dd4dde8d283848becd0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 21:45:44 +0000 Subject: Add workaround for missing usb_interrupt_read() --- tools/csr_usb.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tools') diff --git a/tools/csr_usb.c b/tools/csr_usb.c index 2c29251f..3e2a4144 100644 --- a/tools/csr_usb.c +++ b/tools/csr_usb.c @@ -40,6 +40,13 @@ static inline struct usb_bus *usb_get_busses(void) } #endif +#ifdef NEED_USB_INTERRUPT_READ +static inline int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) +{ + return usb_bulk_read(dev, ep, bytes, size, timeout); +} +#endif + #ifndef USB_DIR_OUT #define USB_DIR_OUT 0x00 #endif -- cgit From 1933d78da59b5965adbc223b5080c31b47081259 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 23:01:38 +0000 Subject: Fix length calculation --- tools/csr_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/csr_usb.c b/tools/csr_usb.c index 3e2a4144..617e7ccf 100644 --- a/tools/csr_usb.c +++ b/tools/csr_usb.c @@ -144,7 +144,7 @@ static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t do { len = usb_interrupt_read(udev, 0x81, - (void *) (rp + offset), sizeof(rp), 10); + (void *) (rp + offset), sizeof(rp) - offset, 10); offset += len; } while (len > 0); -- cgit From a61c4d6cd0882acb8d76f9a59f7847d7027ff539 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 23:24:54 +0000 Subject: Add H4 transport for serial ports --- tools/csr_h4.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/csr_h4.c b/tools/csr_h4.c index 9140d30d..2a6c156f 100644 --- a/tools/csr_h4.c +++ b/tools/csr_h4.c @@ -27,22 +27,133 @@ #include #include +#include +#include +#include #include +#include + +#include "csr.h" static uint16_t seqnum = 0x0000; +static int fd = -1; + int csr_open_h4(char *device) { - fprintf(stderr, "Transport not implemented\n"); + struct termios ti; + + if (!device) + device = "/dev/ttyS0"; + + fd = open(device, O_RDWR | O_NOCTTY); + if (fd < 0) { + fprintf(stderr, "Can't open serial port: %s (%d)\n", + strerror(errno), errno); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (tcgetattr(fd, &ti) < 0) { + fprintf(stderr, "Can't get port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + cfmakeraw(&ti); + + ti.c_cflag |= CLOCAL; + ti.c_cflag |= CRTSCTS; + + if (tcsetattr(fd, TCSANOW, &ti) < 0) { + fprintf(stderr, "Can't change port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + cfsetospeed(&ti, B38400); + + if (tcsetattr(fd, TCSANOW, &ti) < 0) { + fprintf(stderr, "Can't change port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + tcflush(fd, TCIOFLUSH); - return -1; + return 0; } static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { - errno = EIO; + unsigned char cp[254], rp[254]; + uint8_t cmd[10]; + uint16_t size; + int len, offset = 3; + + size = (length < 8) ? 9 : ((length + 1) / 2) + 5; + + cmd[0] = command & 0xff; + cmd[1] = command >> 8; + cmd[2] = size & 0xff; + cmd[3] = size >> 8; + cmd[4] = seqnum & 0xff; + cmd[5] = seqnum >> 8; + cmd[6] = varid & 0xff; + cmd[7] = varid >> 8; + cmd[8] = 0x00; + cmd[9] = 0x00; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0x01; + cp[1] = 0x00; + cp[2] = 0xfc; + cp[3] = (size * 2) + 1; + cp[4] = 0xc2; + memcpy(cp + 5, cmd, sizeof(cmd)); + memcpy(cp + 15, value, length); + + if (write(fd, cp, (size * 2) + 5) < 0) + return -1; + + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return 0; + } + + do { + if (read(fd, rp, 1) < 1) + return -1; + } while (rp[0] != 0x04); + + if (read(fd, rp + 1, 2) < 2) + return -1; + + do { + len = read(fd, rp + offset, sizeof(rp) - offset); + offset += len; + } while (offset < rp[2] + 3); + + if (rp[0] != 0x04 || rp[1] != 0xff || rp[3] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[12] + (rp[13] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 14, length); - return -1; + return 0; } int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length) @@ -57,4 +168,5 @@ int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length) void csr_close_h4(void) { + close(fd); } -- cgit From 1a31ffaa3c1bca7a26448069bf2aa5007ae7f826 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 00:50:01 +0000 Subject: Fix PSR parsing on big endian --- tools/csr.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 10856749..b28289a5 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2685,20 +2685,25 @@ static int parse_line(char *str) { uint8_t array[256]; uint16_t value, pskey, length = 0; - char *tmp, *end; + char *off, *end; pskey = strtol(str + 1, NULL, 16); - tmp = strstr(str, "=") + 1; + off = strstr(str, "=") + 1; + if (!off) + return -EIO; while (1) { - value = strtol(tmp, &end, 16); - if (value == 0 && tmp == end) + value = strtol(off, &end, 16); + if (value == 0 && off == end) break; array[length++] = value & 0xff; array[length++] = value >> 8; - tmp = end + 1; + if (*end == '\0') + break; + + off = end + 1; } return psr_put(pskey, array, length); @@ -2728,6 +2733,11 @@ int psr_read(const char *filename) off = map; while (1) { + if (*off == '\r' || *off == '\n') { + off++; + continue; + } + end = strpbrk(off, "\r\n"); if (!end) break; -- cgit From 979392c3e5cd32a4d570f7d37f22baebd04699ba Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 20:59:28 +0000 Subject: Add skeleton for 3-Wire UART transport --- tools/Makefile.am | 2 +- tools/bccmd.c | 9 +++++++++ tools/csr.h | 5 +++++ tools/csr_3wire.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tools/csr_3wire.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index a038582a..4e7f8d1c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -52,7 +52,7 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c csr_3wire.c bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ endif diff --git a/tools/bccmd.c b/tools/bccmd.c index 3bdf702a..7c1260cf 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -70,6 +70,8 @@ static inline int transport_open(int transport, char *device) return csr_open_bcsp(device); case CSR_TRANSPORT_H4: return csr_open_h4(device); + case CSR_TRANSPORT_3WIRE: + return csr_open_3wire(device); default: fprintf(stderr, "Unsupported transport\n"); return -1; @@ -87,6 +89,8 @@ static inline int transport_read(int transport, uint16_t varid, uint8_t *value, return csr_read_bcsp(varid, value, length); case CSR_TRANSPORT_H4: return csr_read_h4(varid, value, length); + case CSR_TRANSPORT_3WIRE: + return csr_read_3wire(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -104,6 +108,8 @@ static inline int transport_write(int transport, uint16_t varid, uint8_t *value, return csr_write_bcsp(varid, value, length); case CSR_TRANSPORT_H4: return csr_write_h4(varid, value, length); + case CSR_TRANSPORT_3WIRE: + return csr_write_3wire(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -125,6 +131,9 @@ static inline void transport_close(int transport) case CSR_TRANSPORT_H4: csr_close_h4(); break; + case CSR_TRANSPORT_3WIRE: + csr_close_3wire(); + break; } } diff --git a/tools/csr.h b/tools/csr.h index 01e4d803..daa2e669 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -522,6 +522,11 @@ int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length); int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length); void csr_close_h4(void); +int csr_open_3wire(char *device); +int csr_read_3wire(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_3wire(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_3wire(void); + int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); diff --git a/tools/csr_3wire.c b/tools/csr_3wire.c new file mode 100644 index 00000000..322fb437 --- /dev/null +++ b/tools/csr_3wire.c @@ -0,0 +1,60 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +static uint16_t seqnum = 0x0000; + +int csr_open_3wire(char *device) +{ + fprintf(stderr, "Transport not implemented\n"); + + return -1; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + errno = EIO; + + return -1; +} + +int csr_read_3wire(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_3wire(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_3wire(void) +{ +} -- cgit From 858c6b70e59fc7b44243c0c7fb0455323e723b1d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 21:07:04 +0000 Subject: No need for double tcsetattr() --- tools/csr_h4.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'tools') diff --git a/tools/csr_h4.c b/tools/csr_h4.c index 2a6c156f..1e051903 100644 --- a/tools/csr_h4.c +++ b/tools/csr_h4.c @@ -67,13 +67,6 @@ int csr_open_h4(char *device) ti.c_cflag |= CLOCAL; ti.c_cflag |= CRTSCTS; - if (tcsetattr(fd, TCSANOW, &ti) < 0) { - fprintf(stderr, "Can't change port settings: %s (%d)\n", - strerror(errno), errno); - close(fd); - return -1; - } - cfsetospeed(&ti, B38400); if (tcsetattr(fd, TCSANOW, &ti) < 0) { -- cgit From d3d625a0e1027c0f328d2d1f620390ecec1fb3cf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 21:13:25 +0000 Subject: Add basic device initialization --- tools/csr_bcsp.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 8847fec5..582d6859 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -27,15 +27,73 @@ #include #include +#include +#include +#include #include +#include + +#include "csr.h" static uint16_t seqnum = 0x0000; +static int fd = -1; + int csr_open_bcsp(char *device) { - fprintf(stderr, "Transport not implemented\n"); + struct termios ti; - return -1; + if (!device) + device = "/dev/ttyS0"; + + fd = open(device, O_RDWR | O_NOCTTY); + if (fd < 0) { + fprintf(stderr, "Can't open serial port: %s (%d)\n", + strerror(errno), errno); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (tcgetattr(fd, &ti) < 0) { + fprintf(stderr, "Can't get port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + cfmakeraw(&ti); + + ti.c_cflag |= CLOCAL; + ti.c_cflag &= ~CRTSCTS; + ti.c_cflag |= PARENB; + ti.c_cflag &= ~PARODD; + ti.c_cflag &= ~CSIZE; + ti.c_cflag |= CS8; + ti.c_cflag &= ~CSTOPB; + + ti.c_cc[VMIN] = 1; + ti.c_cc[VTIME] = 0; + + cfsetospeed(&ti, B38400); + + if (tcsetattr(fd, TCSANOW, &ti) < 0) { + fprintf(stderr, "Can't change port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) < 0) { + fprintf(stderr, "Can't set non blocking mode: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + return 0; } static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) @@ -57,4 +115,5 @@ int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length) void csr_close_bcsp(void) { + close(fd); } -- cgit From 9c4ddbfafab6fe96480edeb8c5fee1b76e103300 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 22:49:28 +0000 Subject: Add support for using the uBCSP implementation --- tools/csr_bcsp.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 582d6859..f39a4182 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -39,9 +39,40 @@ static uint16_t seqnum = 0x0000; static int fd = -1; +#ifdef HAVE_UBCSP +#include "ubcsp.h" +#else +#define UBCSP_PACKET_SENT 0x01 +#define UBCSP_PACKET_RECEIVED 0x02 +#define UBCSP_PEER_RESET 0x04 +#define UBCSP_PACKET_ACK 0x08 + +struct ubcsp_packet +{ + uint8_t channel; + uint8_t reliable; + uint8_t use_crc; + uint16_t length; + uint8_t *payload; +}; + +static inline void ubcsp_initialize(void) {} +static inline void ubcsp_send_packet(struct ubcsp_packet *send_packet) {} +static inline void ubcsp_receive_packet(struct ubcsp_packet *receive_packet) {} +static inline uint8_t ubcsp_poll(uint8_t *activity) { return 20; } +#endif + +static struct ubcsp_packet send_packet; +static uint8_t send_buffer[512]; + +static struct ubcsp_packet receive_packet; +static uint8_t receive_buffer[512]; + int csr_open_bcsp(char *device) { struct termios ti; + uint8_t delay, activity = 0x00; + int timeout = 0; if (!device) device = "/dev/ttyS0"; @@ -93,14 +124,140 @@ int csr_open_bcsp(char *device) return -1; } + memset(&send_packet, 0, sizeof(send_packet)); + memset(&receive_packet, 0, sizeof(receive_packet)); + + ubcsp_initialize(); + + send_packet.length = 512; + send_packet.payload = send_buffer; + + receive_packet.length = 512; + receive_packet.payload = receive_buffer; + + ubcsp_receive_packet(&receive_packet); + + while (1) { + delay = ubcsp_poll(&activity); + + if (activity & UBCSP_PACKET_RECEIVED) + break; + + if (delay) { + usleep(delay * 100); + + if (timeout++ > 100) { + fprintf(stderr, "Initialization timed out\n"); + return -1; + } + } + } + return 0; } +void put_uart(uint8_t ch) +{ + write(fd, &ch, 1); +} + +uint8_t get_uart(uint8_t *ch) +{ + int res = read(fd, ch, 1); + return res > 0 ? res : 0; +} + static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { - errno = EIO; + unsigned char cp[254], rp[254]; + uint8_t cmd[10]; + uint16_t size; + uint8_t delay, activity = 0x00; + int timeout = 0, sent = 0; - return -1; + size = (length < 8) ? 9 : ((length + 1) / 2) + 5; + + cmd[0] = command & 0xff; + cmd[1] = command >> 8; + cmd[2] = size & 0xff; + cmd[3] = size >> 8; + cmd[4] = seqnum & 0xff; + cmd[5] = seqnum >> 8; + cmd[6] = varid & 0xff; + cmd[7] = varid >> 8; + cmd[8] = 0x00; + cmd[9] = 0x00; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0x00; + cp[1] = 0xfc; + cp[2] = (size * 2) + 1; + cp[3] = 0xc2; + memcpy(cp + 4, cmd, sizeof(cmd)); + memcpy(cp + 14, value, length); + + receive_packet.length = 512; + ubcsp_receive_packet(&receive_packet); + + send_packet.channel = 5; + send_packet.reliable = 1; + send_packet.length = (size * 2) + 4; + memcpy(send_packet.payload, cp, (size * 2) + 4); + + ubcsp_send_packet(&send_packet); + + while (1) { + delay = ubcsp_poll(&activity); + + if (activity & UBCSP_PACKET_RECEIVED) { + if (sent && receive_packet.channel == 5 && + receive_packet.payload[0] == 0xff) { + memcpy(rp, receive_packet.payload, + receive_packet.length); + break; + } + + receive_packet.length = 512; + ubcsp_receive_packet(&receive_packet); + timeout = 0; + } + + if (activity & UBCSP_PACKET_SENT) { + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return 0; + } + + sent = 1; + timeout = 0; + } + + if (delay) { + usleep(delay * 100); + + if (timeout++ > 100) { + fprintf(stderr, "Operation timed out\n"); + return -1; + } + } + } + + if (rp[0] != 0xff || rp[2] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[11] + (rp[12] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 13, length); + + return 0; } int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length) -- cgit From dd5f6c5572b954ea569a918a1612820d3c7b8318 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 Nov 2005 19:38:22 +0000 Subject: Fix strict-aliasing warning --- tools/hciconfig.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 527c9632..417147a5 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -348,8 +348,7 @@ static void cmd_aclmtu(int ctl, int hdev, char *opt) if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; - *((uint16_t *)&dr.dev_opt + 1) = mtu; - *((uint16_t *)&dr.dev_opt + 0) = mpkt; + dr.dev_opt = mpkt | (mtu << 16); if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n", @@ -369,9 +368,8 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; - *((uint16_t *)&dr.dev_opt + 1) = mtu; - *((uint16_t *)&dr.dev_opt + 0) = mpkt; - + dr.dev_opt = mpkt | (mtu << 16); + if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", hdev, strerror(errno), errno); -- cgit From c20d8468a85840b9235694f369d021118abe23c5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Nov 2005 04:47:48 +0000 Subject: Fix big endian problem with ACL and SCO MTU settings --- tools/hciconfig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 417147a5..47488546 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -348,7 +348,7 @@ static void cmd_aclmtu(int ctl, int hdev, char *opt) if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; - dr.dev_opt = mpkt | (mtu << 16); + dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16)); if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n", @@ -368,7 +368,7 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; - dr.dev_opt = mpkt | (mtu << 16); + dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16)); if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", -- cgit From 518f2131be6bbc676121e6558f190950308958e3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 29 Nov 2005 20:37:43 +0000 Subject: Add support for AVRCP specific service records --- tools/sdptool.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 159 insertions(+), 33 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 052c0b05..6074ef77 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2047,6 +2047,162 @@ done: return ret; } +static int add_avrct(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, avctp, avrct; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + sdp_data_t *psm, *version, *features; + uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&avrct, AV_REMOTE_SVCLASS_ID); + svclass_id = sdp_list_append(0, &avrct); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&avctp, AVCTP_UUID); + proto[1] = sdp_list_append(0, &avctp); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + features = sdp_data_alloc(SDP_UINT16, &feat); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); + + sdp_set_info_attr(&record, "AVRCP CT", 0, 0); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto done; + } + + printf("Remote control service registered\n"); + +done: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_avrtg(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, avctp, avrtg; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + sdp_data_t *psm, *version, *features; + uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID); + svclass_id = sdp_list_append(0, &avrtg); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&avctp, AVCTP_UUID); + proto[1] = sdp_list_append(0, &avctp); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + features = sdp_data_alloc(SDP_UINT16, &feat); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); + + sdp_set_info_attr(&record, "AVRCP TG", 0, 0); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto done; + } + + printf("Remote target service registered\n"); + +done: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static unsigned char sr1_uuid[] = { 0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0, + 0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 }; + +static int add_sr1(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass; + uuid_t root_uuid, svclass_uuid; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) sr1_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Toshiba Speech Recognition SR-1 service record registered\n"); + + return 0; +} + static unsigned char syncml_uuid[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 }; @@ -2283,38 +2439,6 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) return 0; } -static unsigned char sr1_uuid[] = { 0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0, - 0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 }; - -static int add_sr1(sdp_session_t *session, svc_info_t *si) -{ - sdp_record_t record; - sdp_list_t *root, *svclass; - uuid_t root_uuid, svclass_uuid; - - memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(&record, root); - - sdp_uuid128_create(&svclass_uuid, (void *) sr1_uuid); - svclass = sdp_list_append(NULL, &svclass_uuid); - sdp_set_service_classes(&record, svclass); - - sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL); - - if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { - printf("Service Record registration failed\n"); - return -1; - } - - printf("Toshiba Speech Recognition SR-1 service record registered\n"); - - return 0; -} - struct { char *name; uint16_t class; @@ -2344,14 +2468,16 @@ struct { { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, + { "AVRCT", AV_REMOTE_SVCLASS_ID, add_avrct }, + { "AVRTG", AV_REMOTE_TARGET_SVCLASS_ID, add_avrtg }, + { "SR1", 0, add_sr1, sr1_uuid }, { "SYNCML", 0, add_syncml, syncml_uuid }, { "ACTIVESYNC", 0, add_activesync, async_uuid }, { "HOTSYNC", 0, add_hotsync, hotsync_uuid }, { "PALMOS", 0, add_palmos, palmos_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, - { "SR1", 0, add_sr1, sr1_uuid }, { 0 } }; -- cgit From bd3e52e30a0529e096abb4e2429122dba22e589b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 03:27:23 +0000 Subject: Update the l2ping manual page --- tools/l2ping.1 | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/l2ping.1 b/tools/l2ping.1 index 0c7da44b..f415dd9c 100644 --- a/tools/l2ping.1 +++ b/tools/l2ping.1 @@ -4,7 +4,7 @@ l2ping \- Send L2CAP echo request and receive answer .SH SYNOPSIS .B l2ping [ -.I -S source addr +.I -i ] [ .I -s size ] [ @@ -23,8 +23,13 @@ L2ping sends a L2CAP echo request to the Bluetooth MAC address given in dotted hex notation. .SH OPTIONS .TP -.I -S source addr -Select address to be used as source address for the request. +.I -i " " +The command is applied to device +.I +hciX +, which must be the name of an installed Bluetooth device (X = 0, 1, 2, ...) +If not specified, the command will be sent to the first available Bluetooth +device. .TP .I -s size The @@ -36,10 +41,10 @@ Send .B count number of packets then exit. .TP -.I -c timeout +.I -c \fBtimeout\fP Wait -.B timeout -for the response. +.B \fBtimeout\fP +seconds for the response. .TP .I -f Kind of flood ping. Use with care! It reduces the delay time between packets @@ -53,4 +58,4 @@ or .SH AUTHORS Written by Maxim Krasnyansky and Marcel Holtmann .PP -man page by Nils Faerber +man page by Nils Faerber . -- cgit From 7c115e06a562978ff2df7b32d7cb1aed72000a16 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 05:11:19 +0000 Subject: Add support for reading the full build name --- tools/bccmd.c | 25 +++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 26 insertions(+) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index 7c1260cf..291ed6a3 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -337,6 +337,30 @@ static int cmd_rand(int transport, int argc, char *argv[]) return 0; } +static int cmd_buildname(int transport, int argc, char *argv[]) +{ + uint8_t array[130]; + char name[64]; + int i, err; + + OPT_HELP(0, NULL); + + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_READ_BUILD_NAME, array, 128); + if (err < 0) { + errno = -err; + return -1; + } + + for (i = 0; i < sizeof(name); i++) + name[i] = array[(i * 2) + 4]; + + printf("Build name: %s\n", name); + + return 0; +} + static int cmd_panicarg(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -901,6 +925,7 @@ static struct { { "keylen", cmd_keylen, "", "Get current crypt key length" }, { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { "rand", cmd_rand, "", "Get random number" }, + { "buildname", cmd_buildname, "", "Get the full build name" }, { "panicarg", cmd_panicarg, "", "Get panic code argument" }, { "faultarg", cmd_faultarg, "", "Get fault code argument" }, { "coldreset", cmd_coldreset, "", "Perform cold reset" }, diff --git a/tools/csr.h b/tools/csr.h index daa2e669..9cdc7225 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -41,6 +41,7 @@ #define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ #define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ #define CSR_VARID_PS_MEMORY_TYPE 0x3012 /* complex */ +#define CSR_VARID_READ_BUILD_NAME 0x301c /* complex */ #define CSR_VARID_COLD_RESET 0x4001 /* valueless */ #define CSR_VARID_WARM_RESET 0x4002 /* valueless */ #define CSR_VARID_COLD_HALT 0x4003 /* valueless */ -- cgit From dc443fe8e6f81ae76f034e6acdc8ab5adca228fc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 05:36:33 +0000 Subject: List available transports --- tools/bccmd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index 291ed6a3..78018d48 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -957,6 +957,9 @@ static void usage(void) "\t-h, --help Display help\n" "\n"); + printf("Transports:\n" + "\tHCI USB BCSP H4 3WIRE\n\n"); + printf("Commands:\n"); for (i = 0; commands[i].str; i++) printf("\t%-10s %-14s\t%s\n", commands[i].str, -- cgit From 90049a54d90557db7c7963c83ba9ff8d3b433c15 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 08:32:00 +0000 Subject: Read oui.txt in current directory first --- tools/oui.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/oui.c b/tools/oui.c index 6ebf91a5..13d6c2f5 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -46,10 +46,12 @@ char *ouitocomp(const char *oui) char *str, *map, *off, *end; int fd; - - fd = open(OUIFILE, O_RDONLY); - if (fd < 0) - return NULL; + fd = open("oui.txt", O_RDONLY); + if (fd < 0) { + fd = open(OUIFILE, O_RDONLY); + if (fd < 0) + return NULL; + } if (fstat(fd, &st) < 0) { close(fd); -- cgit From 2a6755856c498491474e64aa506b81031a1269f7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Dec 2005 15:01:51 +0000 Subject: Fix array length for device name --- tools/hciattach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 8091d655..bcdad95b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -968,7 +968,7 @@ int main(int argc, char *argv[]) int send_break = 0; pid_t pid; struct sigaction sa; - char dev[20]; + char dev[PATH_MAX]; detach = 1; printpid = 0; -- cgit From 138621bf2dbcfa89e85a35010a406d447365cf7e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Dec 2005 19:34:29 +0000 Subject: Add MicroBCSP implementation --- tools/Makefile.am | 2 +- tools/csr_bcsp.c | 24 +- tools/ubcsp.c | 1193 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/ubcsp.h | 208 ++++++++++ 4 files changed, 1403 insertions(+), 24 deletions(-) create mode 100644 tools/ubcsp.c create mode 100644 tools/ubcsp.h (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 4e7f8d1c..08f5d742 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -52,7 +52,7 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c csr_3wire.c +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c csr_3wire.c ubcsp.h ubcsp.c bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ endif diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index f39a4182..2e1cea6e 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -34,34 +34,12 @@ #include #include "csr.h" +#include "ubcsp.h" static uint16_t seqnum = 0x0000; static int fd = -1; -#ifdef HAVE_UBCSP -#include "ubcsp.h" -#else -#define UBCSP_PACKET_SENT 0x01 -#define UBCSP_PACKET_RECEIVED 0x02 -#define UBCSP_PEER_RESET 0x04 -#define UBCSP_PACKET_ACK 0x08 - -struct ubcsp_packet -{ - uint8_t channel; - uint8_t reliable; - uint8_t use_crc; - uint16_t length; - uint8_t *payload; -}; - -static inline void ubcsp_initialize(void) {} -static inline void ubcsp_send_packet(struct ubcsp_packet *send_packet) {} -static inline void ubcsp_receive_packet(struct ubcsp_packet *receive_packet) {} -static inline uint8_t ubcsp_poll(uint8_t *activity) { return 20; } -#endif - static struct ubcsp_packet send_packet; static uint8_t send_buffer[512]; diff --git a/tools/ubcsp.c b/tools/ubcsp.c new file mode 100644 index 00000000..6928da95 --- /dev/null +++ b/tools/ubcsp.c @@ -0,0 +1,1193 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2005 CSR Ltd. + * + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/** **/ +/** ubcsp,c **/ +/** **/ +/** MicroBCSP - a very low cost implementation of the BCSP protocol **/ +/** **/ +/*****************************************************************************/ + +#include "ubcsp.h" + +#if SHOW_PACKET_ERRORS || SHOW_LE_STATES +#include +#include +#endif + +static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc); +static uint16 ubcsp_crc_reverse (uint16); + +/*****************************************************************************/ +/** **/ +/** Constant Data - ROM **/ +/** **/ +/*****************************************************************************/ + +/* This is the storage for the link establishment messages */ + +static const uint8 ubcsp_le_buffer[4][4] = + { + { 0xDA, 0xDC, 0xED, 0xED }, + { 0xAC, 0xAF, 0xEF, 0xEE }, + { 0xAD, 0xEF, 0xAC, 0xED }, + { 0xDE, 0xAD, 0xD0, 0xD0 }, + }; + +/* These are the link establishment headers */ +/* The two version are for the CRC and non-CRC varients */ + +#if UBCSP_CRC +static const uint8 ubcsp_send_le_header[4] = + { + 0x40, 0x41, 0x00, 0x7E + }; +#else +static const uint8 ubcsp_send_le_header[4] = + { + 0x00, 0x41, 0x00, 0xBE + }; +#endif + +/*****************************************************************************/ +/** **/ +/** Static Data - RAM **/ +/** **/ +/*****************************************************************************/ + +/* This is the storage for all state data for ubcsp */ + +static struct ubcsp_configuration ubcsp_config; + +/* This is the ACK packet header - this will be overwritten when + we create an ack packet */ + +static uint8 ubcsp_send_ack_header[4] = + { + 0x00, 0x00, 0x00, 0x00 + }; + +/* This is the deslip lookup table */ + +static const uint8 ubcsp_deslip[2] = + { + SLIP_FRAME, SLIP_ESCAPE, + }; + +/* This is a state machine table for link establishment */ + +static uint8 next_le_packet[16] = + { + ubcsp_le_sync, // uninit + ubcsp_le_conf, // init + ubcsp_le_none, // active + ubcsp_le_none, + ubcsp_le_sync_resp, // sync_resp + ubcsp_le_sync_resp, + ubcsp_le_none, + ubcsp_le_none, + ubcsp_le_none, // conf_resp + ubcsp_le_conf_resp, + ubcsp_le_conf_resp, + ubcsp_le_none, + }; + +/* This is the storage required for building send and crc data */ + +static uint8 ubcsp_send_header[4]; +static uint8 ubcsp_send_crc[2]; + +/* This is where the receive header is stored before the payload arrives */ + +static uint8 ubcsp_receive_header[4]; + +/*****************************************************************************/ +/** **/ +/** Code - ROM or RAM **/ +/** **/ +/*****************************************************************************/ + +/*****************************************************************************/ +/** **/ +/** ubcsp_initialize **/ +/** **/ +/** This initializes the state of the ubcsp engine to a known values **/ +/** **/ +/*****************************************************************************/ + +void ubcsp_initialize (void) +{ + ubcsp_config.ack_number = 0; + ubcsp_config.sequence_number = 0; + ubcsp_config.send_ptr = 0; + ubcsp_config.send_size = 0; + ubcsp_config.receive_index = -4; + + ubcsp_config.delay = 0; + +#if SHOW_LE_STATES + printf ("Hello Link Uninitialized\n"); +#endif + + ubcsp_config.link_establishment_state = ubcsp_le_uninitialized; + ubcsp_config.link_establishment_packet = ubcsp_le_sync; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_send_packet **/ +/** **/ +/** This sends a packet structure for sending to the ubcsp engine **/ +/** This can only be called when the activity indication from ubcsp_poll **/ +/** indicates that a packet can be sent with UBCSP_PACKET_SENT **/ +/** **/ +/*****************************************************************************/ + +void ubcsp_send_packet (struct ubcsp_packet *send_packet) +{ + /* Initialize the send data to the packet we want to send */ + + ubcsp_config.send_packet = send_packet; + + /* we cannot send the packet at the moment + when we can at the moment, just set things to 0 */ + + ubcsp_config.send_size = 0; + ubcsp_config.send_ptr = 0; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_receive_packet **/ +/** **/ +/** This sends a packet structure for receiving to the ubcsp engine **/ +/** This can only be called when the activity indication from ubcsp_poll **/ +/** indicates that a packet can be sent with UBCSP_PACKET_RECEIVED **/ +/** **/ +/*****************************************************************************/ + +void ubcsp_receive_packet (struct ubcsp_packet *receive_packet) +{ + /* Initialize the receive data to the packet we want to receive */ + + ubcsp_config.receive_packet = receive_packet; + + /* setup to receive the header first */ + + ubcsp_config.receive_index = -4; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_calc_crc **/ +/** **/ +/** Takes the next 8 bit value ch, and updates the crc with this value **/ +/** **/ +/*****************************************************************************/ + + +#ifdef UBCSP_CRC + +static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc) +{ + /* Calculate the CRC using the above 16 entry lookup table */ + + static const uint16 crc_table[] = + { + 0x0000, 0x1081, 0x2102, 0x3183, + 0x4204, 0x5285, 0x6306, 0x7387, + 0x8408, 0x9489, 0xa50a, 0xb58b, + 0xc60c, 0xd68d, 0xe70e, 0xf78f + }; + + /* Do this four bits at a time - more code, less space */ + + crc = (crc >> 4) ^ crc_table[(crc ^ ch) & 0x000f]; + crc = (crc >> 4) ^ crc_table[(crc ^ (ch >> 4)) & 0x000f]; + + return crc; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_crc_reverse **/ +/** **/ +/** Reserves the bits in crc and returns the new value **/ +/** **/ +/*****************************************************************************/ + +static uint16 ubcsp_crc_reverse (uint16 crc) +{ + int32 + b, + rev; + + /* Reserse the bits to compute the actual CRC value */ + + for (b = 0, rev=0; b < 16; b++) + { + rev = rev << 1; + rev |= (crc & 1); + crc = crc >> 1; + } + + return rev; +} + +#endif + +/*****************************************************************************/ +/** **/ +/** ubcsp_put_slip_uart **/ +/** **/ +/** Outputs a single octet to the uart **/ +/** If the octet needs to be escaped, then output the escape value **/ +/** and then store the second octet to be output later **/ +/** **/ +/*****************************************************************************/ + +static void ubcsp_put_slip_uart (uint8 ch) +{ + /* output a single UART octet */ + + /* If it needs to be escaped, then output the escape octet + and set the send_slip_escape so that the next time we + output the second octet for the escape correctly. + This is done right at the top of ubcsp_poll */ + + if (ch == SLIP_FRAME) + { + put_uart (SLIP_ESCAPE); + ubcsp_config.send_slip_escape = SLIP_ESCAPE_FRAME; + } + else if (ch == SLIP_ESCAPE) + { + put_uart (SLIP_ESCAPE); + ubcsp_config.send_slip_escape = SLIP_ESCAPE_ESCAPE; + } + else + { + /* Not escaped, so just output octet */ + + put_uart (ch); + } +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_which_le_payload **/ +/** **/ +/** Check the payload of this packet, and determine which of the four **/ +/** link establishment packets this was. **/ +/** Can return 5 if it is not a valid link establishment packet **/ +/** **/ +/*****************************************************************************/ + +static uint32 ubcsp_which_le_payload (const uint8 *payload) +{ + static int32 + octet, + loop; + + /* Search through the various link establishment payloads to find + which one we have received */ + + for (loop = 0; loop < 4; loop ++) + { + for (octet = 0; octet < 4; octet ++) + { + if (payload[octet] != ubcsp_le_buffer[loop][octet]) + { + /* Bad match, just to loop again */ + goto bad_match_loop; + } + } + + /* All the octets matched, return the value */ + + return loop; + + /* Jumps out of octet loop if we got a bad match */ +bad_match_loop: + {} + } + + /* Non of the link establishment payloads matched - return invalid value */ + + return 5; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_recevied_packet **/ +/** **/ +/** This function is called when we have a SLIP END octet and a full **/ +/** packet header and possibly data in the receive packet **/ +/** **/ +/*****************************************************************************/ + +static uint8 ubcsp_recevied_packet (void) +{ + static uint8 + receive_crc, + receive_seq, + receive_ack, + activity; + +#if UBCSP_CRC + static int32 + loop; + + static uint16 + crc; +#endif + + static uint16 + length; + + /* Keep track of what activity this received packet will cause */ + + activity = 0; + + /*** Do all error checks that we can ***/ + + /* First check the header checksum */ + + if (((ubcsp_receive_header[0] + ubcsp_receive_header[1] + ubcsp_receive_header[2] + ubcsp_receive_header[3]) & 0xff) != 0xff) + { + /* Header Checksum Error */ + +#if SHOW_PACKET_ERRORS + printf ("\n######################## Header Checksum Error %02X %02X %02X %02X\n", + ubcsp_receive_header[0], + ubcsp_receive_header[1], + ubcsp_receive_header[2], + ubcsp_receive_header[3]); +#endif + + /* If we have a header checksum error, send an ack in return + this gets a packet to be resent as quickly as possible */ + + ubcsp_config.send_ack = 1; + + return activity; + } + + /* Decode the received packets header */ + + ubcsp_config.receive_packet->reliable = (ubcsp_receive_header[0] & 0x80) >> 7; + + receive_crc = (ubcsp_receive_header[0] & 0x40) >> 6; + receive_ack = (ubcsp_receive_header[0] & 0x38) >> 3; + receive_seq = (ubcsp_receive_header[0] & 0x07); + + ubcsp_config.receive_packet->channel = (ubcsp_receive_header[1] & 0x0f); + + length = + ((ubcsp_receive_header[1] & 0xf0) >> 4) | + (ubcsp_receive_header[2] << 4); + +#if SHOW_PACKET_ERRORS + if (ubcsp_config.receive_packet->reliable) + { + printf (" : %10d Recv SEQ: %d ACK %d\n", + GetTickCount () % 100000, + receive_seq, + receive_ack); + } + else if (ubcsp_config.receive_packet->channel != 1) + { + printf (" : %10d Recv ACK %d\n", + GetTickCount () % 100000, + receive_ack); + } +#endif + + /* Check for length errors */ + +#if UBCSP_CRC + if (receive_crc) + { + /* If this packet had a CRC, then the length of the payload + should be 2 less than the received size of the payload */ + + if (length + 2 != ubcsp_config.receive_index) + { + /* Slip Length Error */ + +#if SHOW_PACKET_ERRORS + printf ("\n######################## Slip Length Error (With CRC) %d,%d\n", length, ubcsp_config.receive_index - 2); +#endif + + /* If we have a payload length error, send an ack in return + this gets a packet to be resent as quickly as possible */ + + ubcsp_config.send_ack = 1; + return activity; + } + + /* We have a CRC at the end of this packet */ + + ubcsp_config.receive_index -= 2; + + /* Calculate the packet CRC */ + + crc = 0xffff; + + /* CRC the packet header */ + + for (loop = 0; loop < 4; loop ++) + { + crc = ubcsp_calc_crc (ubcsp_receive_header[loop], crc); + } + + /* CRC the packet payload - without the CRC bytes */ + + for (loop = 0; loop < ubcsp_config.receive_index; loop ++) + { + crc = ubcsp_calc_crc (ubcsp_config.receive_packet->payload[loop], crc); + } + + /* Reverse the CRC */ + + crc = ubcsp_crc_reverse (crc); + + /* Check the CRC is correct */ + + if + ( + (((crc & 0xff00) >> 8) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index]) || + ((crc & 0xff) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index + 1]) + ) + { +#if SHOW_PACKET_ERRORS + printf ("\n######################## CRC Error\n"); +#endif + + /* If we have a packet crc error, send an ack in return + this gets a packet to be resent as quickly as possible */ + + ubcsp_config.send_ack = 1; + return activity; + } + } + else + { +#endif + /* No CRC present, so just check the length of payload with that received */ + + if (length != ubcsp_config.receive_index) + { + /* Slip Length Error */ + +#if SHOW_PACKET_ERRORS + printf ("\n######################## Slip Length Error (No CRC) %d,%d\n", length, ubcsp_config.receive_index); +#endif + + /* If we have a payload length error, send an ack in return + this gets a packet to be resent as quickly as possible */ + + ubcsp_config.send_ack = 1; + return activity; + } +#if UBCSP_CRC + } +#endif + + /*** We have a fully formed packet having passed all data integrity checks ***/ + + /* Check if we have an ACK for the last packet we sent */ + + if (receive_ack != ubcsp_config.sequence_number) + { + /* Since we only have a window size of 1, if the ACK is not equal to SEQ + then the packet was sent */ + + if + ( + (ubcsp_config.send_packet) && + (ubcsp_config.send_packet->reliable) + ) + { + /* We had sent a reliable packet, so clear this packet + Then increament the sequence number for the next packet */ + + ubcsp_config.send_packet = 0; + ubcsp_config.sequence_number ++; + ubcsp_config.delay = 0; + + /* Notify the caller that we have SENT a packet */ + + activity |= UBCSP_PACKET_SENT; + } + } + + /*** Now we can concentrate of the packet we have received ***/ + + /* Check for Link Establishment packets */ + + if (ubcsp_config.receive_packet->channel == 1) + { + /* Link Establishment */ + + ubcsp_config.delay = 0; + + /* Find which link establishment packet this payload means + This could return 5, meaning none */ + + switch (ubcsp_which_le_payload (ubcsp_config.receive_packet->payload)) + { + case 0: + { + /* SYNC Recv'd */ + +#if SHOW_LE_STATES + printf ("Recv SYNC\n"); +#endif + + /* If we receive a SYNC, then we respond to it with a SYNC RESP + but only if we are not active. + If we are active, then we have a PEER RESET */ + + if (ubcsp_config.link_establishment_state < ubcsp_le_active) + { + ubcsp_config.link_establishment_resp = 1; + } + else + { + /* Peer reset !!!! */ + +#if SHOW_LE_STATES + printf ("\n\n\n\n\nPEER RESET\n\n"); +#endif + + /* Reinitialize the link */ + + ubcsp_initialize (); + + /* Tell the host what has happened */ + + return UBCSP_PEER_RESET; + } + break; + } + + case 1: + { + /* SYNC RESP Recv'd */ + +#if SHOW_LE_STATES + printf ("Recv SYNC RESP\n"); +#endif + + /* If we receive a SYNC RESP, push us into the initialized state */ + + if (ubcsp_config.link_establishment_state < ubcsp_le_initialized) + { +#if SHOW_LE_STATES + printf ("Link Initialized\n"); +#endif + ubcsp_config.link_establishment_state = ubcsp_le_initialized; + } + + break; + } + + case 2: + { + /* CONF Recv'd */ + +#if SHOW_LE_STATES + printf ("Recv CONF\n"); +#endif + + /* If we receive a CONF, and we are initialized or active + then respond with a CONF RESP */ + + if (ubcsp_config.link_establishment_state >= ubcsp_le_initialized) + { + ubcsp_config.link_establishment_resp = 2; + } + + break; + } + + case 3: + { + /* CONF RESP Recv'd */ + +#if SHOW_LE_STATES + printf ("Recv CONF RESP\n"); +#endif + + /* If we received a CONF RESP, then push us into the active state */ + + if (ubcsp_config.link_establishment_state < ubcsp_le_active) + { +#if SHOW_LE_STATES + printf ("Link Active\n"); +#endif + + ubcsp_config.link_establishment_state = ubcsp_le_active; + ubcsp_config.send_size = 0; + + return activity | UBCSP_PACKET_SENT; + } + + break; + } + } + + /* We have finished processing Link Establishment packets */ + } + else if (ubcsp_config.receive_index) + { + /* We have some payload data we need to process + but only if we are active - otherwise, we just ignore it */ + + if (ubcsp_config.link_establishment_state == ubcsp_le_active) + { + if (ubcsp_config.receive_packet->reliable) + { + /* If the packet we've just received was reliable + then send an ACK */ + + ubcsp_config.send_ack = 1; + + /* We the sequence number we received is the same as + the last ACK we sent, then we have received a packet in sequence */ + + if (receive_seq == ubcsp_config.ack_number) + { + /* Increase the ACK number - which will be sent in the next ACK + or normal packet we send */ + + ubcsp_config.ack_number ++; + + /* Set the values in the receive_packet structure, so the caller + knows how much data we have */ + + ubcsp_config.receive_packet->length = length; + ubcsp_config.receive_packet = 0; + + /* Tell the caller that we have received a packet, and that it + will be ACK'ed */ + + activity |= UBCSP_PACKET_RECEIVED | UBCSP_PACKET_ACK; + } + } + else + { + /* Set the values in the receive_packet structure, so the caller + knows how much data we have */ + + ubcsp_config.receive_packet->length = length; + ubcsp_config.receive_packet = 0; + + /* Tell the caller that we have received a packet */ + + activity |= UBCSP_PACKET_RECEIVED; + } + } + } + + /* Just return any activity that occured */ + + return activity; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_setup_packet **/ +/** **/ +/** This function is called to setup a packet to be sent **/ +/** This allows just a header, or a header and payload to be sent **/ +/** It also allows the header checksum to be precalcuated **/ +/** or calculated here **/ +/** part1 is always 4 bytes **/ +/** **/ +/*****************************************************************************/ + +static void ubcsp_setup_packet (uint8 *part1, uint8 calc, uint8 *part2, uint16 len2) +{ + /* If we need to calculate the checksum, do that now */ + + if (calc) + { + part1[3] = + ~(part1[0] + part1[1] + part1[2]); + } + + /* Setup the header send pointer and size so we can clock this out */ + + ubcsp_config.send_ptr = part1; + ubcsp_config.send_size = 4; + + /* Setup the payload send pointer and size */ + + ubcsp_config.next_send_ptr = part2; + ubcsp_config.next_send_size = len2; + +#if UBCSP_CRC + /* Initialize the crc as required */ + + ubcsp_config.send_crc = -1; + + ubcsp_config.need_send_crc = 1; +#endif +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_sent_packet **/ +/** **/ +/** Called when we have finished sending a packet **/ +/** If this packet was unreliable, then notify caller, and clear the data **/ +/** **/ +/*****************************************************************************/ + +static uint8 ubcsp_sent_packet (void) +{ + if (ubcsp_config.send_packet) + { + if (!ubcsp_config.send_packet->reliable) + { + /* We had a packet sent that was unreliable */ + + /* Forget about this packet */ + + ubcsp_config.send_packet = 0; + + /* Notify caller that they can send another one */ + + return UBCSP_PACKET_SENT; + } + } + + /* We didn't have a packet, or it was reliable + Must wait for ACK before allowing another packet to be sent */ + + return 0; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_poll **/ +/** **/ +/** This is the main function for ubcsp **/ +/** It performs a number of tasks **/ +/** **/ +/** 1) Send another octet to the UART - escaping as required **/ +/** 2) Setup the payload to be sent after the header has been sent **/ +/** 3) Send the CRC for the packet if required **/ +/** **/ +/** 4) Calculate the next Link Establishment State **/ +/** 5) Send a Link Establishment packet **/ +/** 6) Send a normal packet if available **/ +/** 7) Send an ACK packet if required **/ +/** **/ +/** 8) Receive octets from UART and deslip them as required **/ +/** 9) Place received octets into receive header or receive payload buffer **/ +/** 10) Process received packet when SLIP_END is received **/ +/** **/ +/** 11) Keep track of ability of caller to delay recalling **/ +/** **/ +/*****************************************************************************/ + +uint8 ubcsp_poll (uint8 *activity) +{ + uint8 + delay = UBCSP_POLL_TIME_IMMEDIATE; + + uint8 + value; + + /* Assume no activity to start with */ + + *activity = 0; + + /* If we don't have to delay, then send something if we can */ + + if (!ubcsp_config.delay) + { + /* Do we have something we are sending to send */ + + if (ubcsp_config.send_size) + { + /* We have something to send so send it */ + + if (ubcsp_config.send_slip_escape) + { + /* Last time we send a SLIP_ESCAPE octet + this time send the second escape code */ + + put_uart (ubcsp_config.send_slip_escape); + + ubcsp_config.send_slip_escape = 0; + } + else + { +#if UBCSP_CRC + /* get the value to send, and calculate CRC as we go */ + + value = *ubcsp_config.send_ptr ++; + + ubcsp_config.send_crc = ubcsp_calc_crc (value, ubcsp_config.send_crc); + + /* Output the octet */ + + ubcsp_put_slip_uart (value); +#else + /* Just output the octet*/ + + ubcsp_put_slip_uart (*ubcsp_config.send_ptr ++); +#endif + } + + /* If we did output a SLIP_ESCAPE, then don't process the end of a block */ + + if ((!ubcsp_config.send_slip_escape) && ((ubcsp_config.send_size = ubcsp_config.send_size - 1) == 0)) + { + /*** We are at the end of a block - either header or payload ***/ + + /* setup the next block */ + + ubcsp_config.send_ptr = ubcsp_config.next_send_ptr; + ubcsp_config.send_size = ubcsp_config.next_send_size; + ubcsp_config.next_send_ptr = 0; + ubcsp_config.next_send_size = 0; + +#if UBCSP_CRC + /* If we have no successor block + then we might need to send the CRC */ + + if (!ubcsp_config.send_ptr) + { + if (ubcsp_config.need_send_crc) + { + /* reverse the CRC from what we computed along the way */ + + ubcsp_config.need_send_crc = 0; + + ubcsp_config.send_crc = ubcsp_crc_reverse (ubcsp_config.send_crc); + + /* Save in the send_crc buffer */ + + ubcsp_send_crc[0] = (uint8) (ubcsp_config.send_crc >> 8); + ubcsp_send_crc[1] = (uint8) ubcsp_config.send_crc; + + /* Setup to send this buffer */ + + ubcsp_config.send_ptr = ubcsp_send_crc; + ubcsp_config.send_size = 2; + } + else + { + /* We don't need to send the crc + either we just have, or this packet doesn't include it */ + + /* Output the end of FRAME marker */ + + put_uart (SLIP_FRAME); + + /* Check if this is an unreliable packet */ + + *activity |= ubcsp_sent_packet (); + + /* We've sent the packet, so don't need to have be called quickly soon */ + + delay = UBCSP_POLL_TIME_DELAY; + } + } +#else + /* If we have no successor block + then we might need to send the CRC */ + + if (!ubcsp_config.send_ptr) + { + /* Output the end of FRAME marker */ + + put_uart (SLIP_FRAME); + + /* Check if this is an unreliable packet */ + + *activity |= ubcsp_sent_packet (); + + /* We've sent the packet, so don't need to have be called quickly soon */ + + delay = UBCSP_POLL_TIME_DELAY; + } +#endif + } + } + else if (ubcsp_config.link_establishment_packet == ubcsp_le_none) + { + /* We didn't have something to send + AND we have no Link Establishment packet to send */ + + if (ubcsp_config.link_establishment_resp & 2) + { + /* Send the start of FRAME packet */ + + put_uart (SLIP_FRAME); + + /* We did require a RESP packet - so setup the send */ + + ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_le_conf_resp], 4); + + /* We have now "sent" this packet */ + + ubcsp_config.link_establishment_resp = 0; + } + else if (ubcsp_config.send_packet) + { + /* There is a packet ready to be sent */ + + /* Send the start of FRAME packet */ + + put_uart (SLIP_FRAME); + + /* Encode up the packet header using ACK and SEQ numbers */ + + ubcsp_send_header[0] = + (ubcsp_config.send_packet->reliable << 7) | +#if UBCSP_CRC + 0x40 | /* Always use CRC's */ +#endif + (ubcsp_config.ack_number << 3) | + (ubcsp_config.sequence_number); + + /* Encode up the packet header's channel and length */ + ubcsp_send_header[1] = + (ubcsp_config.send_packet->channel & 0x0f) | + ((ubcsp_config.send_packet->length << 4) & 0xf0); + + ubcsp_send_header[2] = + (ubcsp_config.send_packet->length >> 4) & 0xff; + + /* Let the ubcsp_setup_packet function calculate the header checksum */ + + ubcsp_setup_packet ((uint8*) ubcsp_send_header, 1, ubcsp_config.send_packet->payload, ubcsp_config.send_packet->length); + + /* Don't need to send an ACK - we just place on in this packet */ + + ubcsp_config.send_ack = 0; + +#if SHOW_PACKET_ERRORS + printf (" : %10d Send %d Ack %d\n", + GetTickCount () % 100000, + ubcsp_config.sequence_number, + ubcsp_config.ack_number); +#endif + } + else if (ubcsp_config.send_ack) + { + /* Send the start of FRAME packet */ + + put_uart (SLIP_FRAME); + +#if SHOW_PACKET_ERRORS + printf (" : %10d Send ACK %d\n", + GetTickCount () % 100000, + ubcsp_config.ack_number); +#endif + + /* The ack packet is already computed apart from the first octet */ + + ubcsp_send_ack_header[0] = +#if UBCSP_CRC + 0x40 | +#endif + (ubcsp_config.ack_number << 3); + + /* Let the ubcsp_setup_packet function calculate the header checksum */ + + ubcsp_setup_packet (ubcsp_send_ack_header, 1, 0, 0); + + /* We've now sent the ack */ + + ubcsp_config.send_ack = 0; + } + else + { + /* We didn't have a Link Establishment response packet, + a normal packet or an ACK packet to send */ + + delay = UBCSP_POLL_TIME_DELAY; + } + } + else + { +#if SHOW_PACKET_ERRORS +// printf (" : %10d Send LE %d\n", +// GetTickCount () % 100000, +// ubcsp_config.link_establishment_packet); +#endif + + /* Send A Link Establishment Message */ + + put_uart (SLIP_FRAME); + + /* Send the Link Establishment header followed by the + Link Establishment packet */ + + ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_config.link_establishment_packet], 4); + + /* start sending immediately */ + + ubcsp_config.delay = 0; + + /* workout what the next link establishment packet should be */ + + ubcsp_config.link_establishment_packet = next_le_packet[ubcsp_config.link_establishment_state + ubcsp_config.link_establishment_resp * 4]; + + /* We have now delt with any response packet that we needed */ + + ubcsp_config.link_establishment_resp = 0; + + return 0; + } + } + + /* We now need to receive any octets from the UART */ + + while ((ubcsp_config.receive_packet) && (get_uart (&value))) + { + /* If the last octet was SLIP_ESCAPE, then special processing is required */ + + if (ubcsp_config.receive_slip_escape) + { + /* WARNING - out of range values are not detected !!! + This will probably be caught with the checksum or CRC check */ + + value = ubcsp_deslip[value - SLIP_ESCAPE_FRAME]; + + ubcsp_config.receive_slip_escape = 0; + } + else + { + /* Check for the SLIP_FRAME octet - must be start or end of packet */ + if (value == SLIP_FRAME) + { + /* If we had a full header then we have a packet */ + + if (ubcsp_config.receive_index >= 0) + { + /* process the received packet */ + + *activity |= ubcsp_recevied_packet (); + + if (*activity & UBCSP_PACKET_ACK) + { + /* We need to ACK this packet, then don't delay its sending */ + ubcsp_config.delay = 0; + } + } + + /* Setup to receive the next packet */ + + ubcsp_config.receive_index = -4; + + /* Ok, next octet */ + + goto finished_receive; + } + else if (value == SLIP_ESCAPE) + { + /* If we receive a SLIP_ESCAPE, + then remember to process the next special octet */ + + ubcsp_config.receive_slip_escape = 1; + + goto finished_receive; + } + } + + if (ubcsp_config.receive_index < 0) + { + /* We are still receiving the header */ + + ubcsp_receive_header[ubcsp_config.receive_index + 4] = value; + + ubcsp_config.receive_index ++; + } + else if (ubcsp_config.receive_index < ubcsp_config.receive_packet->length) + { + /* We are receiving the payload */ + /* We might stop comming here if we are receiving a + packet which is longer than the receive_packet->length + given by the host */ + + ubcsp_config.receive_packet->payload[ubcsp_config.receive_index] = value; + + ubcsp_config.receive_index ++; + } + +finished_receive: + { + } + } + + if (ubcsp_config.delay > 0) + { + /* We were delayed so delay some more + this could be cancelled if we received something */ + + ubcsp_config.delay --; + } + else + { + /* We had no delay, so use the delay we just decided to us */ + + ubcsp_config.delay = delay; + } + + /* Report the current delay to the user */ + + return ubcsp_config.delay; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_end_of_functions **/ +/** **/ +/*****************************************************************************/ + +/* This function is only included to allow for the size + of the code to be determined */ + +void ubcsp_end_of_functions (void) +{ +} diff --git a/tools/ubcsp.h b/tools/ubcsp.h new file mode 100644 index 00000000..6a74e9a1 --- /dev/null +++ b/tools/ubcsp.h @@ -0,0 +1,208 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2005 CSR Ltd. + * + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef UBCSP_INCLUDE_H +#define UBCSP_INCLUDE_H + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/** **/ +/** ubcsp.h **/ +/** **/ +/** MicroBCSP - a very low cost implementation of the BCSP protocol **/ +/** **/ +/*****************************************************************************/ + +/* If we wish to use CRC's, then change 0 to 1 in the next line */ +#define UBCSP_CRC 1 + +/* Define some basic types - change these for your architecture */ +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; + +/* The defines below require a printf function to be available */ + +/* Do we want to show packet errors in debug output */ +#define SHOW_PACKET_ERRORS 0 + +/* Do we want to show Link Establishment State transitions in debug output */ +#define SHOW_LE_STATES 0 + +/*****************************************************************************/ +/** **/ +/** ubcsp_packet **/ +/** **/ +/** This is description of a bcsp packet for the upper layer **/ +/** **/ +/*****************************************************************************/ + +struct ubcsp_packet +{ + uint8 channel; /* Which Channel this packet is to/from */ + uint8 reliable; /* Is this packet reliable */ + uint8 use_crc; /* Does this packet use CRC data protection */ + uint16 length; /* What is the length of the payload data */ + uint8 *payload; /* The payload data itself - size of length */ +}; + +/*****************************************************************************/ +/** **/ +/** ubcsp_configuration **/ +/** **/ +/** This is the main configuration of the ubcsp engine **/ +/** All state variables are stored in this structure **/ +/** **/ +/*****************************************************************************/ + +enum ubcsp_link_establishment_state +{ + ubcsp_le_uninitialized, + ubcsp_le_initialized, + ubcsp_le_active +}; + +enum ubcsp_link_establishment_packet +{ + ubcsp_le_sync, + ubcsp_le_sync_resp, + ubcsp_le_conf, + ubcsp_le_conf_resp, + ubcsp_le_none +}; + +struct ubcsp_configuration +{ + uint8 link_establishment_state; + uint8 link_establishment_resp; + uint8 link_establishment_packet; + + uint8 sequence_number:3; + uint8 ack_number:3; + uint8 send_ack; + struct ubcsp_packet *send_packet; + struct ubcsp_packet *receive_packet; + + uint8 receive_header_checksum; + uint8 receive_slip_escape; + int32 receive_index; + + uint8 send_header_checksum; +#ifdef UBCSP_CRC + uint8 need_send_crc; + uint16 send_crc; +#endif + uint8 send_slip_escape; + + uint8 *send_ptr; + int32 send_size; + uint8 *next_send_ptr; + int32 next_send_size; + + int8 delay; +}; + +/*****************************************************************************/ +/** **/ +/** ubcsp_poll sets activity from an OR of these flags **/ +/** **/ +/*****************************************************************************/ + +#define UBCSP_PACKET_SENT 0x01 +#define UBCSP_PACKET_RECEIVED 0x02 +#define UBCSP_PEER_RESET 0x04 +#define UBCSP_PACKET_ACK 0x08 + +/*****************************************************************************/ +/** **/ +/** This is the functional interface for ucbsp **/ +/** **/ +/*****************************************************************************/ + +void ubcsp_initialize (void); +void ubcsp_send_packet (struct ubcsp_packet *send_packet); +void ubcsp_receive_packet (struct ubcsp_packet *receive_packet); +uint8 ubcsp_poll (uint8 *activity); + +/*****************************************************************************/ +/** **/ +/** Slip Escape Values **/ +/** **/ +/*****************************************************************************/ + +#define SLIP_FRAME 0xC0 +#define SLIP_ESCAPE 0xDB +#define SLIP_ESCAPE_FRAME 0xDC +#define SLIP_ESCAPE_ESCAPE 0xDD + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/** **/ +/** These functions need to be linked into your system **/ +/** **/ +/*****************************************************************************/ + +/*****************************************************************************/ +/** **/ +/** put_uart outputs a single octet over the UART Tx line **/ +/** **/ +/*****************************************************************************/ + +extern void put_uart (uint8); + +/*****************************************************************************/ +/** **/ +/** get_uart receives a single octet over the UART Rx line **/ +/** if no octet is available, then this returns 0 **/ +/** if an octet was read, then this is returned in the argument and **/ +/** the function returns 1 **/ +/** **/ +/*****************************************************************************/ + +extern uint8 get_uart (uint8 *); + +/*****************************************************************************/ +/** **/ +/** These defines should be changed to your systems concept of 100ms **/ +/** **/ +/*****************************************************************************/ + +#define UBCSP_POLL_TIME_IMMEDIATE 0 +#define UBCSP_POLL_TIME_DELAY 25 + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +#endif -- cgit From 57580b1b9cd64d823f3843c556cabd9856b8f86f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 6 Dec 2005 20:52:03 +0000 Subject: Update manual page of bccmd tool --- tools/bccmd.8 | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.8 b/tools/bccmd.8 index 58e8814f..82727009 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -1,26 +1,45 @@ -.TH BCCMD 8 "Sep 30 2005" BlueZ "Linux System Administration" +.TH BCCMD 8 "Dec 6 2005" BlueZ "Linux System Administration" .SH NAME bccmd \- Utility for the CSR BCCMD interface .SH SYNOPSIS .B bccmd .br -.B bccmd [-i ] +.B bccmd [-t ] [-d ] [] +.br +.B bccmd [-h --help] .br - .SH DESCRIPTION -.LP .B bccmd issues BlueCore commands to .B Cambridge Silicon Radio -devices. If run without the argument, a short help page will be diaplayed. -.PP - +devices. If run without the argument, a short help page will be displayed. .SH OPTIONS .TP -.BI -i\ -Specify a particular device to operate on. If not specified, default is the first available device. +.BI -t\ +Specify the communication transport. Valid options are: +.RS +.TP +.BI HCI +Local device with Host Controller Interface (default). +.TP +.BI USB +Direct USB connection. +.TP +.BI BCSP +Blue Core Serial Protocol. +.TP +.BI H4 +H4 serial protocol. +.TP +.BI 3WIRE +3WIRE protocol (not implemented). +.SH +.TP +.BI -d\ +Specify a particular device to operate on. If not specified, default is the first available HCI device +or /dev/ttyS0 for serial transports. .SH COMMANDS .TP .BI builddef @@ -35,6 +54,9 @@ Get local Bluetooth clock .BI rand Get random number .TP +.BI buildname +Get the full build name +.TP .BI panicarg Get panic code argument .TP @@ -52,6 +74,34 @@ Disable TX on the device .TP .BI enabletx Enable TX on the device +.TP +.BI memtypes +Get memory types +.TP +.BI psget\ +Get value for PS key +.TP +.BI psset\ \ +Set value for PS key +.TP +.BI psclr\ +Clear value for PS key +.TP +.BI pslist +List all PS keys +.TP +.BI psread +Read all PS keys +.TP +.BI psload\ +Load all PS keys from PSR file +.TP +.BI pscheck\ +Check syntax of PSR file +.SH KEYS +bdaddr country devclass keymin keymax features commands version +remver hciextn mapsco baudrate hostintf anafreq anaftrim usbvid +usbpid dfupid bootmode .SH AUTHORS Written by Marcel Holtmann , man page by Adam Laurie -- cgit From 27454e3869df7f30ba170fefc17018fa07b5d194 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Dec 2005 09:04:58 +0000 Subject: Update the Silicon Wave init routine --- tools/hciattach.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index bcdad95b..d0e03cce 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -648,7 +648,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) */ static int swave(int fd, struct uart_t *u, struct termios *ti) { - struct timespec tm = {0, 500000}; + struct timespec tm = { 0, 500000 }; char cmd[10], rsp[100]; int r; @@ -688,7 +688,7 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } /* Send initialization command */ - if (write(fd, cmd, 9) != 9) { + if (write(fd, cmd, 10) != 10) { perror("Failed to write init command"); return -1; } @@ -720,15 +720,16 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) return -1; } - // we probably got the reply. Now we must send the "soft reset": + // we probably got the reply. Now we must send the "soft reset" + // which is standard HCI RESET. + cmd[0] = HCI_COMMAND_PKT; // it's a command packet - cmd[1] = 0x0B; // OCF 0x0B = param access set - cmd[2] = 0xfc; // OGF bx111111 = vendor specific - cmd[3] = 0x01; // 1 byte of data following - cmd[4] = 0x03; // HCI Reset Subcommand - - // Send initialization command - if (write(fd, cmd, 5) != 5) { + cmd[1] = 0x03; + cmd[2] = 0x0c; + cmd[3] = 0x00; + + /* Send reset command */ + if (write(fd, cmd, 4) != 4) { perror("Can't write Silicon Wave reset cmd."); return -1; } -- cgit From a330124c26567659f373575e48d63852a96a18b3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Dec 2005 11:45:01 +0000 Subject: Use /var/lib/misc/oui.txt as default OUI file --- tools/oui.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/oui.c b/tools/oui.c index 13d6c2f5..b68ae04b 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -38,7 +38,7 @@ /* http://standards.ieee.org/regauth/oui/oui.txt */ -#define OUIFILE "/usr/share/misc/oui.txt" +#define OUIFILE "/var/lib/misc/oui.txt" char *ouitocomp(const char *oui) { @@ -49,8 +49,11 @@ char *ouitocomp(const char *oui) fd = open("oui.txt", O_RDONLY); if (fd < 0) { fd = open(OUIFILE, O_RDONLY); - if (fd < 0) - return NULL; + if (fd < 0) { + fd = open("/usr/share/misc/oui.txt", O_RDONLY); + if (fd < 0) + return NULL; + } } if (fstat(fd, &st) < 0) { -- cgit From 4312264fa42014771b188da1d61c3911026390e8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Dec 2005 09:09:33 +0000 Subject: Fix display of text strings --- tools/sdptool.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 6074ef77..2fcd0c7a 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -561,7 +561,6 @@ static void print_tree_attr(sdp_record_t *rec) static void print_raw_data(sdp_data_t *data, int indent) { struct uuid_def *def; - char *str; int i, hex; if (!data) @@ -661,25 +660,18 @@ static void print_raw_data(sdp_data_t *data, int indent) case SDP_TEXT_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: - str = data->val.str; - if (data->unitSize > strlen(str) + 1) { - hex = 0; - for (i = 0; i < data->unitSize - 1; i++) - if (!isprint(str[i])) { - hex = 1; - break; - } - if (str[data->unitSize - 1] != '\0') + hex = 0; + for (i = 0; i < data->unitSize; i++) + if (!isprint(data->val.str[i])) { hex = 1; - } else - hex = 0; - if (hex) { - printf("String"); - for (i = 0; i < data->unitSize; i++) - printf(" %02x", (unsigned char) str[i]); - printf("\n"); - } else - printf("String %s\n", str); + break; + } + for (i = 0; i < data->unitSize; i++) + if (hex) + printf(" %02x", (unsigned char) data->val.str[i]); + else + printf("%c", data->val.str[i]); + printf("\n"); break; case SDP_URL_STR8: case SDP_URL_STR16: -- cgit From 6ab0c763564fb55fc50f2f8ce4712fc718321635 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Dec 2005 10:35:27 +0000 Subject: Fix display of text and data strings --- tools/sdptool.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 2fcd0c7a..b3124c58 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -666,11 +666,15 @@ static void print_raw_data(sdp_data_t *data, int indent) hex = 1; break; } - for (i = 0; i < data->unitSize; i++) - if (hex) + if (hex) { + printf("Data"); + for (i = 0; i < data->unitSize; i++) printf(" %02x", (unsigned char) data->val.str[i]); - else + } else { + printf("String "); + for (i = 0; i < data->unitSize; i++) printf("%c", data->val.str[i]); + } printf("\n"); break; case SDP_URL_STR8: -- cgit From 69e97d91bc0636a9546836d2ec0ca629fdcb1718 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 15 Dec 2005 22:58:54 +0000 Subject: Update build definitions --- tools/csr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index b28289a5..39293fa8 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -424,7 +424,7 @@ char *csr_builddeftostr(uint16_t def) case 0x000e: return "TRANSPORT_USER"; case 0x000f: - return "CHIP_BC02K"; + return "CHIP_BC02_KATO"; case 0x0010: return "TRANSPORT_NONE"; case 0x0012: @@ -446,15 +446,15 @@ char *csr_builddeftostr(uint16_t def) case 0x001a: return "COMPILER_GCC"; case 0x001b: - return "CHIP_BC02C"; + return "CHIP_BC02_CLOUSEAU"; case 0x001c: - return "CHIP_BC02T"; + return "CHIP_BC02_TOULOUSE"; case 0x001d: return "CHIP_BASE_BC3"; case 0x001e: - return "CHIP_BC3N"; + return "CHIP_BC3_NICKNACK"; case 0x001f: - return "CHIP_BC3K"; + return "CHIP_BC3_KALIMBA"; case 0x0020: return "INSTALL_HCI_MODULE"; case 0x0021: -- cgit From 96e7c3629715547f0632d4fb313923c16b64f049 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 18 Dec 2005 19:14:43 +0000 Subject: Include header file stdint.h --- tools/csr.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index 9cdc7225..d75e3995 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -21,6 +21,8 @@ * */ +#include + #define CSR_VARID_PS_CLR_ALL 0x000b /* valueless */ #define CSR_VARID_PS_FACTORY_SET 0x000c /* valueless */ #define CSR_VARID_PS_CLR_ALL_STORES 0x082d /* uint16 */ -- cgit From f2e48c44a7e4c9ee31b8ce2e302186f6047cfeab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 13:28:56 +0000 Subject: Update copyright information --- tools/avctrl.c | 2 +- tools/bccmd.c | 2 +- tools/ciptool.c | 2 +- tools/csr.c | 2 +- tools/csr.h | 2 +- tools/csr_3wire.c | 2 +- tools/csr_bcsp.c | 2 +- tools/csr_h4.c | 2 +- tools/csr_hci.c | 2 +- tools/csr_usb.c | 2 +- tools/dfu.c | 2 +- tools/dfu.h | 2 +- tools/dfutool.c | 2 +- tools/hciattach.c | 2 +- tools/hciconfig.c | 2 +- tools/hcisecfilter.c | 2 +- tools/hcitool.c | 2 +- tools/hid2hci.c | 2 +- tools/l2ping.c | 2 +- tools/oui.c | 2 +- tools/oui.h | 2 +- tools/ppporc.c | 2 +- tools/sdptool.c | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/avctrl.c b/tools/avctrl.c index 06540ef5..c01e7d31 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/bccmd.c b/tools/bccmd.c index 78018d48..62ffd0ce 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/ciptool.c b/tools/ciptool.c index e30db09a..8f967858 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr.c b/tools/csr.c index 39293fa8..eec6c0e6 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr.h b/tools/csr.h index d75e3995..f1c63117 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_3wire.c b/tools/csr_3wire.c index 322fb437..0999efc0 100644 --- a/tools/csr_3wire.c +++ b/tools/csr_3wire.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 2e1cea6e..77766114 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_h4.c b/tools/csr_h4.c index 1e051903..8a3ff7fe 100644 --- a/tools/csr_h4.c +++ b/tools/csr_h4.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_hci.c b/tools/csr_hci.c index ebeb8aa7..4f33d0ae 100644 --- a/tools/csr_hci.c +++ b/tools/csr_hci.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_usb.c b/tools/csr_usb.c index 617e7ccf..75354fd0 100644 --- a/tools/csr_usb.c +++ b/tools/csr_usb.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfu.c b/tools/dfu.c index 436b2e02..200426ff 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfu.h b/tools/dfu.h index 54992e03..9cfe70fa 100644 --- a/tools/dfu.h +++ b/tools/dfu.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfutool.c b/tools/dfutool.c index eb087011..8d5e9194 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciattach.c b/tools/hciattach.c index d0e03cce..6a806039 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 47488546..703bdbd8 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 1d557ce1..6114f57f 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hcitool.c b/tools/hcitool.c index 9ae42a12..85404afc 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 8a19a880..7e033755 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/l2ping.c b/tools/l2ping.c index 3b46675d..0fe3d11a 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/oui.c b/tools/oui.c index b68ae04b..cc695a90 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/oui.h b/tools/oui.h index 93cc7b01..c166038f 100644 --- a/tools/oui.h +++ b/tools/oui.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/ppporc.c b/tools/ppporc.c index e8275641..45e23549 100644 --- a/tools/ppporc.c +++ b/tools/ppporc.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/sdptool.c b/tools/sdptool.c index b3124c58..689f724d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * Copyright (C) 2002-2003 Jean Tourrilhes * -- cgit From 4fe03a99ce951164c711e7f2146f2bee6df44c64 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 13:31:18 +0000 Subject: Use %jx instead of %llx for uint64_t and int64_t --- tools/sdptool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 689f724d..8749e0b5 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -586,7 +586,7 @@ static void print_raw_data(sdp_data_t *data, int indent) printf("UINT32 0x%08x\n", data->val.uint32); break; case SDP_UINT64: - printf("UINT64 0x%016llx\n", data->val.uint64); + printf("UINT64 0x%016jx\n", data->val.uint64); break; case SDP_UINT128: printf("UINT128 ...\n"); @@ -601,7 +601,7 @@ static void print_raw_data(sdp_data_t *data, int indent) printf("INT32 %d\n", data->val.int32); break; case SDP_INT64: - printf("INT64 %lld\n", data->val.int64); + printf("INT64 %jd\n", data->val.int64); break; case SDP_INT128: printf("INT128 ...\n"); -- cgit From a0de58e012d1d85dcbef1c52eb082ea6c8a8e9de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 15:26:43 +0000 Subject: Add UUID for N-Gage games --- tools/sdptool.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 8749e0b5..39583530 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2435,6 +2435,9 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) return 0; } +static unsigned char ngage_uuid[] = { 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + struct { char *name; uint16_t class; @@ -2474,6 +2477,7 @@ struct { { "PALMOS", 0, add_palmos, palmos_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, + { "NGAGE", 0, NULL, ngage_uuid }, { 0 } }; -- cgit From b27690df2da69d959a78d95483217a0a5c529cfb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 21:03:23 +0000 Subject: Add UUID for Apple Macintosh Attributes --- tools/sdptool.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 39583530..ea4e4d3d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2438,6 +2438,9 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) static unsigned char ngage_uuid[] = { 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; +static unsigned char apple_uuid[] = { 0xf0, 0x72, 0x2e, 0x20, 0x0f, 0x8b, 0x4e, 0x90, + 0x8c, 0xc2, 0x1b, 0x46, 0xf5, 0xf2, 0xef, 0xe2 }; + struct { char *name; uint16_t class; @@ -2478,6 +2481,7 @@ struct { { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "NGAGE", 0, NULL, ngage_uuid }, + { "APPLE", 0, NULL, apple_uuid }, { 0 } }; -- cgit From f83f040580da69b2e95ac817d308724bc35e75da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 4 Jan 2006 00:05:22 +0000 Subject: dd definitions for Apple Agent --- tools/sdptool.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index ea4e4d3d..2b291aa5 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -314,6 +314,7 @@ static struct uuid_def uuid16_names[] = { { 0x1303, "VideoSource", NULL, 0 }, { 0x1304, "VideoSink", NULL, 0 }, { 0x1305, "VideoDistribution", NULL, 0 }, + { 0x2112, "AppleAgent", NULL, 0 }, }; static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); @@ -2483,6 +2484,8 @@ struct { { "NGAGE", 0, NULL, ngage_uuid }, { "APPLE", 0, NULL, apple_uuid }, + { "ISYNC", APPLE_AGENT_SVCLASS_ID, NULL, }, + { 0 } }; -- cgit From b769dcbea87081a6e0010db03a97f163256cd372 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 4 Jan 2006 01:38:54 +0000 Subject: Add Apple attributes and iSync records --- tools/sdptool.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 2b291aa5..ae2925cc 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2442,6 +2442,85 @@ static unsigned char ngage_uuid[] = { 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, static unsigned char apple_uuid[] = { 0xf0, 0x72, 0x2e, 0x20, 0x0f, 0x8b, 0x4e, 0x90, 0x8c, 0xc2, 0x1b, 0x46, 0xf5, 0xf2, 0xef, 0xe2 }; +static int add_apple(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root; + uuid_t root_uuid; + uint32_t attr783 = 0x00000000; + uint32_t attr785 = 0x00000002; + uint16_t attr786 = 0x1234; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_attr_add_new(&record, 0x0780, SDP_UUID128, (void *) apple_uuid); + sdp_attr_add_new(&record, 0x0781, SDP_TEXT_STR8, (void *) "Macmini"); + sdp_attr_add_new(&record, 0x0782, SDP_TEXT_STR8, (void *) "PowerMac10,1"); + sdp_attr_add_new(&record, 0x0783, SDP_UINT32, (void *) &attr783); + sdp_attr_add_new(&record, 0x0784, SDP_TEXT_STR8, (void *) "1.6.6f22"); + sdp_attr_add_new(&record, 0x0785, SDP_UINT32, (void *) &attr785); + sdp_attr_add_new(&record, 0x0786, SDP_UUID16, (void *) &attr786); + + sdp_set_info_attr(&record, "Apple Macintosh Attributes", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Apple attribute service registered\n"); + + return 0; +} + +static int add_isync(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, serial_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel? si->channel: 8; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid16_create(&serial_uuid, SERIAL_PORT_SVCLASS_ID); + svclass = sdp_list_append(NULL, &serial_uuid); + + sdp_uuid16_create(&svclass_uuid, APPLE_AGENT_SVCLASS_ID); + svclass = sdp_list_append(svclass, &svclass_uuid); + + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "AppleAgent", "Bluetooth acceptor", "Apple Computer Ltd."); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Apple iSync service registered\n"); + + return 0; +} + struct { char *name; uint16_t class; @@ -2482,9 +2561,9 @@ struct { { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "NGAGE", 0, NULL, ngage_uuid }, - { "APPLE", 0, NULL, apple_uuid }, + { "APPLE", 0, add_apple, apple_uuid }, - { "ISYNC", APPLE_AGENT_SVCLASS_ID, NULL, }, + { "ISYNC", APPLE_AGENT_SVCLASS_ID, add_isync, }, { 0 } }; -- cgit From 88e399ec1d771872d9ee895875218a3d3aa2f6ec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Jan 2006 12:59:57 +0000 Subject: Allow null-terminated strings --- tools/sdptool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index ae2925cc..b3876233 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -662,11 +662,14 @@ static void print_raw_data(sdp_data_t *data, int indent) case SDP_TEXT_STR16: case SDP_TEXT_STR32: hex = 0; - for (i = 0; i < data->unitSize; i++) + for (i = 0; i < data->unitSize; i++) { + if (i == (data->unitSize - 1) && data->val.str[i] == '\0') + break; if (!isprint(data->val.str[i])) { hex = 1; break; } + } if (hex) { printf("Data"); for (i = 0; i < data->unitSize; i++) -- cgit From e9799abfdd2520e3adbd5c3a1d27a9e466361598 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jan 2006 15:09:53 +0000 Subject: Add support for the Handsfree Audio Gateway service record --- tools/sdptool.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index b3876233..55d7f590 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1303,7 +1303,6 @@ end: return ret; } - static int add_headset(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1424,6 +1423,73 @@ end: return ret; } +static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 3; + uint16_t u16 = 0x17; + sdp_data_t *channel, *features; + uint8_t netid = 0x01; // ???? profile document + sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + //record.handle = 0xffffffff; + record.handle = 0x10001; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + features = sdp_data_alloc(SDP_UINT16, &u16); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Voice Gateway", 0, 0); + + sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Handsfree AG service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + static int add_simaccess(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -2541,6 +2607,7 @@ struct { { "HS", HEADSET_SVCLASS_ID, add_headset }, { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, + { "HFAG", HANDSFREE_AGW_SVCLASS_ID, add_handsfree_ag}, { "SAP", SAP_SVCLASS_ID, add_simaccess }, { "NAP", NAP_SVCLASS_ID, add_nap }, -- cgit From aebaa2bd80065ac380237d2f52bc675e4d1462d1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:43:04 +0000 Subject: Add support for choosing a specific service record handle --- tools/sdptool.c | 365 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 216 insertions(+), 149 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 55d7f590..02db6e2c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -747,7 +747,7 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha sdp_list_t *attrid_list; uint32_t range = 0x0000ffff; sdp_record_t *rec; - + /* Get the old SDP record */ attrid_list = sdp_list_append(NULL, &range); rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attrid_list); @@ -794,7 +794,7 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha } static struct option set_options[] = { - { "help", 0,0, 'h' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -819,6 +819,7 @@ static int cmd_setattr(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -835,8 +836,10 @@ static int cmd_setattr(int argc, char **argv) sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); if (!sess) return -1; + status = set_attrib(sess, handle, attrib, argv[2]); sdp_close(sess); + return status; } @@ -912,13 +915,13 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri printf("Service Record update failed (%d).\n", errno); return -1; } - } else { + } else printf("Failed to create pSequenceHolder\n"); - } /* Cleanup */ for (i = 0; i < argc; i++) free(allocArray[i]); + free(dtdArray); free(valueArray); @@ -926,7 +929,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri } static struct option seq_options[] = { - { "help", 0,0, 'h' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -952,6 +955,7 @@ static int cmd_setseq(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -971,8 +975,10 @@ static int cmd_setseq(int argc, char **argv) sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); if (!sess) return -1; + status = set_attribseq(sess, handle, attrib, argc, argv); sdp_close(sess); + return status; } @@ -991,7 +997,7 @@ static void print_service_desc(void *value, void *user) char str[MAX_LEN_PROTOCOL_UUID_STR]; sdp_data_t *p = (sdp_data_t *)value, *s; int i = 0, proto = 0; - + for (; p; p = p->next, i++) { switch (p->dtd) { case SDP_UUID16: @@ -1106,10 +1112,10 @@ static void print_service_attr(sdp_record_t *rec) * Support for Service (de)registration */ typedef struct { + uint32_t handle; char *name; char *provider; char *desc; - unsigned int class; unsigned int profile; unsigned int channel; @@ -1135,12 +1141,12 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) uuid_t root_uuid, sp_uuid, l2cap, rfcomm; sdp_profile_desc_t profile; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 1; + uint8_t u8 = si->channel ? si->channel : 1; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1179,13 +1185,16 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Serial Port service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1196,12 +1205,12 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 1; + uint8_t u8 = si->channel ? si->channel : 2; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&rootu, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &rootu); sdp_set_browse_groups(&record, root); @@ -1237,7 +1246,68 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Dial-Up Networking service registered\n"); + +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + + return ret; +} + +static int add_fax(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel : 3; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID); + svclass_id = sdp_list_append(0, &fax_uuid); + sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &tel_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Fax", 0, 0); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Fax service registered\n"); end: sdp_data_free(channel); sdp_list_free(proto[0], 0); @@ -1254,12 +1324,12 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 2; + uint8_t u8 = si->channel ? si->channel : 4; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1293,13 +1363,16 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("LAN Access service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1310,12 +1383,12 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 5; + uint8_t u8 = si->channel ? si->channel : 5; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1351,13 +1424,16 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Headset service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1368,13 +1444,13 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 3; + uint8_t u8 = si->channel ? si->channel : 6; uint16_t u16 = 0x31; - sdp_data_t *channel, *features; + sdp_data_t *channel, *features; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1413,13 +1489,16 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Handsfree service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1430,16 +1509,15 @@ static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 3; + uint8_t u8 = si->channel ? si->channel : 7; uint16_t u16 = 0x17; sdp_data_t *channel, *features; uint8_t netid = 0x01; // ???? profile document sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - //record.handle = 0xffffffff; - record.handle = 0x10001; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1480,13 +1558,16 @@ static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Handsfree AG service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1497,13 +1578,13 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 3; + uint8_t u8 = si->channel? si->channel : 8; uint16_t u16 = 0x31; sdp_data_t *channel, *features; int ret = 0; memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1552,64 +1633,6 @@ end: return ret; } -static int add_fax(sdp_session_t *session, svc_info_t *si) -{ - sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid; - sdp_profile_desc_t profile; - sdp_list_t *aproto, *proto[2]; - sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 3; - sdp_data_t *channel; - int ret = 0; - - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(0, &root_uuid); - sdp_set_browse_groups(&record, root); - - sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID); - svclass_id = sdp_list_append(0, &fax_uuid); - sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID); - svclass_id = sdp_list_append(svclass_id, &tel_uuid); - sdp_set_service_classes(&record, svclass_id); - - sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID); - profile.version = 0x0100; - pfseq = sdp_list_append(0, &profile); - sdp_set_profile_descs(&record, pfseq); - - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto[0] = sdp_list_append(0, &l2cap_uuid); - apseq = sdp_list_append(0, proto[0]); - - sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); - proto[1] = sdp_list_append(0, &rfcomm_uuid); - channel = sdp_data_alloc(SDP_UINT8, &u8); - proto[1] = sdp_list_append(proto[1], channel); - apseq = sdp_list_append(apseq, proto[1]); - - aproto = sdp_list_append(0, apseq); - sdp_set_access_protos(&record, aproto); - - sdp_set_info_attr(&record, "Fax", 0, 0); - - if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { - printf("Service Record registration failed\n"); - ret = -1; - goto end; - } - printf("Fax service registered\n"); -end: - sdp_data_free(channel); - sdp_list_free(proto[0], 0); - sdp_list_free(proto[1], 0); - sdp_list_free(apseq, 0); - sdp_list_free(aproto, 0); - return ret; -} - static int add_opush(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1617,7 +1640,7 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[3]; sdp_record_t record; - uint8_t chan = si->channel? si->channel: 4; + uint8_t chan = si->channel ? si->channel : 9; sdp_data_t *channel; uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; //uint8_t formats[] = { 0xff }; @@ -1627,8 +1650,8 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) sdp_data_t *sflist; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1673,7 +1696,9 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("OBEX Object Push service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); @@ -1681,6 +1706,7 @@ end: sdp_list_free(proto[2], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1691,12 +1717,12 @@ static int add_ftp(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[3]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 4; + uint8_t u8 = si->channel ? si->channel: 10; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1734,7 +1760,9 @@ static int add_ftp(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("OBEX File Transfer service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); @@ -1742,6 +1770,7 @@ end: sdp_list_free(proto[2], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1756,8 +1785,8 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) sdp_data_t *psm, *version; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1807,7 +1836,9 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("NAP service registered\n"); + end: sdp_data_free(version); sdp_data_free(psm); @@ -1815,6 +1846,7 @@ end: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1829,8 +1861,8 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) sdp_data_t *psm, *version; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1866,7 +1898,9 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("GN service registered\n"); + end: sdp_data_free(version); sdp_data_free(psm); @@ -1874,6 +1908,7 @@ end: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1888,8 +1923,8 @@ static int add_panu(sdp_session_t *session, svc_info_t *si) sdp_data_t *psm, *version; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1928,7 +1963,9 @@ static int add_panu(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("PANU service registered\n"); + end: sdp_data_free(version); sdp_data_free(psm); @@ -1936,6 +1973,7 @@ end: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1950,8 +1988,8 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1985,13 +2023,16 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("CTP service registered\n"); + end: sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); sdp_data_free(network); + return ret; } @@ -2006,8 +2047,8 @@ static int add_a2source(sdp_session_t *session, svc_info_t *si) uint16_t lp = 0x0019, ver = 0x0100; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2051,6 +2092,7 @@ done: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2065,8 +2107,8 @@ static int add_a2sink(sdp_session_t *session, svc_info_t *si) uint16_t lp = 0x0019, ver = 0x0100; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2110,6 +2152,7 @@ done: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2124,8 +2167,8 @@ static int add_avrct(sdp_session_t *session, svc_info_t *si) uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2172,6 +2215,7 @@ done: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2186,8 +2230,8 @@ static int add_avrtg(sdp_session_t *session, svc_info_t *si) uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2234,6 +2278,7 @@ done: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2247,7 +2292,7 @@ static int add_sr1(sdp_session_t *session, svc_info_t *si) uuid_t root_uuid, svclass_uuid; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2277,10 +2322,10 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; - uint8_t channel = si->channel? si->channel: 15; + uint8_t channel = si->channel ? si->channel: 15; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2322,10 +2367,10 @@ static int add_activesync(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; - uint8_t channel = si->channel? si->channel: 21; + uint8_t channel = si->channel ? si->channel: 21; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2364,10 +2409,10 @@ static int add_hotsync(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; - uint8_t channel = si->channel? si->channel: 22; + uint8_t channel = si->channel ? si->channel: 22; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2408,7 +2453,7 @@ static int add_palmos(sdp_session_t *session, svc_info_t *si) uuid_t root_uuid, svclass_uuid; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2440,7 +2485,7 @@ static int add_nokiaid(sdp_session_t *session, svc_info_t *si) sdp_data_t *version = sdp_data_alloc(SDP_UINT16, &verid); memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2471,10 +2516,10 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; - uint8_t channel = si->channel? si->channel: 14; + uint8_t channel = si->channel ? si->channel: 14; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2521,7 +2566,7 @@ static int add_apple(sdp_session_t *session, svc_info_t *si) uint16_t attr786 = 0x1234; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2552,10 +2597,10 @@ static int add_isync(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, serial_uuid, l2cap_uuid, rfcomm_uuid; - uint8_t channel = si->channel? si->channel: 8; + uint8_t channel = si->channel ? si->channel : 16; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2641,36 +2686,42 @@ struct { /* Add local service */ static int add_service(bdaddr_t *bdaddr, svc_info_t *si) { - int i; - sdp_session_t *sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); + sdp_session_t *sess; + int i, ret = -1; + + if (!si->name) + return -1; + sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); if (!sess) return -1; - if (si->name) - for (i = 0; service[i].name; i++) - if (!strcasecmp(service[i].name, si->name)) { - int ret = -1; - if (service[i].add) - ret = service[i].add(sess, si); - free(si->name); - sdp_close(sess); - return ret; - } + + for (i = 0; service[i].name; i++) + if (!strcasecmp(service[i].name, si->name)) { + if (service[i].add) + ret = service[i].add(sess, si); + goto done; + } + printf("Unknown service name: %s\n", si->name); + +done: free(si->name); sdp_close(sess); - return -1; + + return ret; } static struct option add_options[] = { - { "help", 0,0, 'h' }, - { "channel", 1,0, 'c' }, - { 0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "handle", 1, 0, 'r' }, + { "channel", 1, 0, 'c' }, + { 0, 0, 0, 0 } }; static char *add_help = "Usage:\n" - "\tadd [--channel=CHAN] service\n"; + "\tadd [--handle=RECORD_HANDLE --channel=CHANNEL] service\n"; static int cmd_add(int argc, char **argv) { @@ -2678,8 +2729,16 @@ static int cmd_add(int argc, char **argv) int opt; memset(&si, 0, sizeof(si)); + si.handle = 0xffffffff; + for_each_opt(opt, add_options, 0) { switch (opt) { + case 'r': + if (strncasecmp(optarg, "0x", 2)) + si.handle = atoi(optarg); + else + si.handle = strtol(optarg + 2, NULL, 16); + break; case 'c': si.channel = atoi(optarg); break; @@ -2688,6 +2747,7 @@ static int cmd_add(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -2724,6 +2784,7 @@ static int del_service(bdaddr_t *bdaddr, void *arg) attr = sdp_list_append(0, &range); rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr); sdp_list_free(attr, 0); + if (!rec) { printf("Service Record not found.\n"); sdp_close(sess); @@ -2738,11 +2799,12 @@ static int del_service(bdaddr_t *bdaddr, void *arg) printf("Service Record deleted.\n"); sdp_close(sess); + return 0; } static struct option del_options[] = { - { "help", 0,0, 'h' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -2761,6 +2823,7 @@ static int cmd_del(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -2917,6 +2980,7 @@ static int cmd_browse(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -2930,9 +2994,9 @@ static int cmd_browse(int argc, char **argv) } static struct option search_options[] = { - { "help", 0,0, 'h' }, - { "bdaddr", 1,0, 'b' }, - { "tree", 0,0, 't' }, + { "help", 0, 0, 'h' }, + { "bdaddr", 1, 0, 'b' }, + { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, { 0, 0, 0, 0} }; @@ -2946,7 +3010,7 @@ static char *search_help = * Search for a specific SDP service * * Note : we should support multiple services on the command line : - * sdptool search 0x0100 0x000f 0x1002 + * sdptool search 0x0100 0x000f 0x1002 * (this would search a service supporting both L2CAP and BNEP directly in * the top level browse group) */ @@ -2980,6 +3044,7 @@ static int cmd_search(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -2989,7 +3054,7 @@ static int cmd_search(int argc, char **argv) } /* Note : we need to find a way to support search combining - * multiple services - Jean II */ + * multiple services */ context.svc = strdup(argv[0]); if (!strncasecmp(context.svc, "0x", 2)) { int num; @@ -3026,7 +3091,6 @@ static int cmd_search(int argc, char **argv) /* * Show how to get a specific SDP record by its handle. * Not really useful to the user, just show how it can be done... - * Jean II */ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int quite) { @@ -3046,6 +3110,7 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int qui rec = sdp_service_attr_req(session, context->handle, SDP_ATTR_REQ_RANGE, attrid); sdp_list_free(attrid, 0); sdp_close(session); + if (!rec) { if (!quite) { printf("Service get request failed.\n"); @@ -3112,6 +3177,7 @@ static int cmd_records(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -3177,6 +3243,7 @@ static int cmd_get(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -3202,7 +3269,7 @@ static struct { { "add", cmd_add, "Add local service" }, { "del", cmd_del, "Delete local service" }, { "get", cmd_get, "Get local service" }, - { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, + { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, { "setseq", cmd_setseq, "Set/Add attribute sequence to a SDP record" }, { 0, 0, 0 } }; @@ -3277,5 +3344,5 @@ int main(int argc, char **argv) if (strncmp(command[i].cmd, argv[0], 4) == 0) return command[i].func(argc, argv); - return -1; + return 1; } -- cgit From da7aed3f3f9377f68a7aebe645ef4e8b1f6f1d92 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Jan 2006 17:45:51 +0000 Subject: Use the correct device for reading the local clock --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 85404afc..2ad26bfe 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1973,7 +1973,7 @@ static void cmd_clock(int dev_id, int argc, char **argv) else bacpy(&bdaddr, BDADDR_ANY); - if (!bacmp(&bdaddr, BDADDR_ANY)) + if (dev_id < 0 && !bacmp(&bdaddr, BDADDR_ANY)) dev_id = hci_get_route(NULL); if (dev_id < 0) { -- cgit From 5094a9971637f88dd38383faa7be81dafd997adb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 21 Jan 2006 01:45:01 +0000 Subject: Add support for Broadcom BCM2035 chips --- tools/hciattach.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 6a806039..e583e8db 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -802,6 +802,117 @@ static int st(int fd, struct uart_t *u, struct termios *ti) return 0; } + +/* + * Broadcom specific initialization + * Extracted from Jungo openrg + */ +static int bcm2035(int fd, struct uart_t *u, struct termios *ti) +{ + int n; + unsigned char cmd[30], resp[30]; + + /* Reset the BT Chip */ + memset(cmd, 0, sizeof(cmd)); + memset(resp, 0, sizeof(resp)); + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x03; + cmd[2] = 0x0c; + cmd[3] = 0x00; + /* Send command */ + if (write(fd, cmd, 4) != 4) { + fprintf(stderr, "Failed to write reset command\n"); + return -1; + } + /* Read reply */ + if ((n = read_hci_event(fd, resp, 4)) < 0) { + fprintf(stderr, "Failed to reset chip\n"); + return -1; + } + + /* Read the local version info */ + memset(cmd, 0, sizeof(cmd)); + memset(resp, 0, sizeof(resp)); + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x01; + cmd[2] = 0x10; + cmd[3] = 0x00; + /* Send command */ + if (write(fd, cmd, 4) != 4) { + fprintf(stderr, "Failed to write \"read local version\" " + "command\n"); + return -1; + } + /* Read reply */ + if ((n = read_hci_event(fd, resp, 4)) < 0) { + fprintf(stderr, "Failed to read local version\n"); + return -1; + } + + /* Read the local supported commands info */ + memset(cmd, 0, sizeof(cmd)); + memset(resp, 0, sizeof(resp)); + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x02; + cmd[2] = 0x10; + cmd[3] = 0x00; + /* Send command */ + if (write(fd, cmd, 4) != 4) { + fprintf(stderr, "Failed to write \"read local supported " + "commands\" command\n"); + return -1; + } + /* Read reply */ + if ((n = read_hci_event(fd, resp, 4)) < 0) { + fprintf(stderr, "Failed to read local supported commands\n"); + return -1; + } + + /* Set the baud rate */ + memset(cmd, 0, sizeof(cmd)); + memset(resp, 0, sizeof(resp)); + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x18; + cmd[2] = 0xfc; + cmd[3] = 0x02; + switch (u->speed) { + case 57600: + cmd[4] = 0x00; + cmd[5] = 0xe6; + break; + case 230400: + cmd[4] = 0x22; + cmd[5] = 0xfa; + break; + case 460800: + cmd[4] = 0x11; + cmd[5] = 0xfd; + break; + case 921600: + cmd[4] = 0x65; + cmd[5] = 0xff; + break; + default: + /* Default is 115200 */ + cmd[4] = 0x00; + cmd[5] = 0xf3; + break; + } + fprintf(stderr, "Baud rate parameters: DHBR=0x%2x,DLBR=0x%2x\n", + cmd[4], cmd[5]); + + /* Send command */ + if (write(fd, cmd, 6) != 6) { + fprintf(stderr, "Failed to write \"set baud rate\" command\n"); + return -1; + } + if ((n = read_hci_event(fd, resp, 6)) < 0) { + fprintf(stderr, "Failed to set baud rate\n"); + return -1; + } + return 0; +} + struct uart_t uart[] = { { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, @@ -855,6 +966,9 @@ struct uart_t uart[] = { /* Billionton PCBTC1 PCMCIA Card */ { "billionton", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + /* Broadcom BCM2035 */ + { "bcm2035", 0x0A5C, 0x2035, HCI_UART_H4, 115200, 115200, 0, bcm2035 }, + { NULL, 0 } }; -- cgit From a6a6a79950afbf7b2366718b7e209da203d173d7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 21 Jan 2006 10:56:33 +0000 Subject: Add UDI service records --- tools/sdptool.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 02db6e2c..ba624401 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2282,6 +2282,88 @@ done: return ret; } +static int add_udiue(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel ? si->channel: 18; + + memset(&record, 0, sizeof(record)); + record.handle = si->handle; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + sdp_list_free(root, NULL); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid16_create(&svclass_uuid, UDI_MT_SVCLASS_ID); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + sdp_list_free(svclass, NULL); + + sdp_set_info_attr(&record, "UDI UE", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("UDI UE service registered\n"); + + return 0; +} + +static int add_udite(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel ? si->channel: 19; + + memset(&record, 0, sizeof(record)); + record.handle = si->handle; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + sdp_list_free(root, NULL); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid16_create(&svclass_uuid, UDI_TA_SVCLASS_ID); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + sdp_list_free(svclass, NULL); + + sdp_set_info_attr(&record, "UDI TE", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("UDI TE service registered\n"); + + return 0; +} + static unsigned char sr1_uuid[] = { 0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0, 0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 }; @@ -2668,6 +2750,9 @@ struct { { "AVRCT", AV_REMOTE_SVCLASS_ID, add_avrct }, { "AVRTG", AV_REMOTE_TARGET_SVCLASS_ID, add_avrtg }, + { "UDIUE", UDI_MT_SVCLASS_ID, add_udiue }, + { "UDITE", UDI_TA_SVCLASS_ID, add_udite }, + { "SR1", 0, add_sr1, sr1_uuid }, { "SYNCML", 0, add_syncml, syncml_uuid }, { "ACTIVESYNC", 0, add_activesync, async_uuid }, -- cgit From 6c53a6b4e4282459ec072a64d09a4c13a7feded5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 21 Jan 2006 11:39:07 +0000 Subject: Add service record for the ISDN profile --- tools/sdptool.1 | 11 ++++-- tools/sdptool.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 781a91e5..6f8d634d 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -74,17 +74,20 @@ Services are identified and manipulated with a 4-byte \fBrecord_handle\fP .IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] service_name\fP" 10 Search for services.. .IP "" 10 -Known service names are DID, SP, DUN, LAN, FAX, OPUSH, -FTP, HS, HF, SAP, NAP, GN, PANU, HID, CIP, CTP, A2SRC, A2SNK -and SYNCML. +Known service names are DID, SP, DUN, LAN, FAX, OPUSH, +FTP, HS, HF, HFAG, SAP, NAP, GN, PANU, HID, CIP, +A2SRC, A2SNK, AVRCT, AVRTG, UDIUE, UDITE and SYNCML. .IP "\fBbrowse [--tree] [--raw] [bdaddr]\fP" 10 Browse all available services on the device specified by a Bluetooth address as a parameter. .IP "\fBrecords [--tree] [--raw] bdaddr\fP" 10 Retrieve all possible service records. -.IP "\fBadd [ --channel=N ]\fP" 10 +.IP "\fBadd [ --handle=N --channel=N ]\fP" 10 Add a service to the local \fBsdpd\fR. +.IP "" 10 +You can specify a handle for this record using +the \fB--handle\fP option. .IP "" 10 You can specify a channel to add the service on using the \fB--channel\fP option. diff --git a/tools/sdptool.c b/tools/sdptool.c index ba624401..0484d8af 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1118,7 +1118,9 @@ typedef struct { char *desc; unsigned int class; unsigned int profile; - unsigned int channel; + uint16_t psm; + uint8_t channel; + uint8_t network; } svc_info_t; static void add_lang_attr(sdp_record_t *r) @@ -1211,6 +1213,7 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&rootu, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &rootu); sdp_set_browse_groups(&record, root); @@ -1270,8 +1273,9 @@ static int add_fax(sdp_session_t *session, svc_info_t *si) sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); + memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1330,6 +1334,7 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1389,6 +1394,7 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1451,6 +1457,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1512,12 +1519,13 @@ static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) uint8_t u8 = si->channel ? si->channel : 7; uint16_t u16 = 0x17; sdp_data_t *channel, *features; - uint8_t netid = 0x01; // ???? profile document + uint8_t netid = si->network ? si->network : 0x01; // ???? profile document sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); int ret = 0; memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1585,6 +1593,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) memset((void *)&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1652,6 +1661,7 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1723,6 +1733,7 @@ static int add_ftp(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1787,6 +1798,7 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1863,6 +1875,7 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1925,6 +1938,7 @@ static int add_panu(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1977,6 +1991,69 @@ end: return ret; } +static int add_cip(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, cmtp, cip; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint16_t psm = si->psm ? si->psm : 0x1001; + uint8_t netid = si->network ? si->network : 0x02; // 0x02 = ISDN, 0x03 = GSM + sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); + int ret = 0; + + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&cip, CIP_SVCLASS_ID); + svclass_id = sdp_list_append(0, &cip); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, CIP_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + apseq = sdp_list_append(0, proto[0]); + proto[0] = sdp_list_append(proto[0], sdp_data_alloc(SDP_UINT16, &psm)); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&cmtp, CMTP_UUID); + proto[1] = sdp_list_append(0, &cmtp); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network); + + sdp_set_info_attr(&record, "Common ISDN Access", 0, 0); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + + printf("CIP service registered\n"); + +end: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + sdp_data_free(network); + + return ret; +} + static int add_ctp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1984,12 +2061,13 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t netid = 0x02; // 0x01-0x07 cf. p120 profile document + uint8_t netid = si->network ? si->network : 0x02; // 0x01-0x07 cf. p120 profile document sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); int ret = 0; memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2049,6 +2127,7 @@ static int add_a2source(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2109,6 +2188,7 @@ static int add_a2sink(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2169,6 +2249,7 @@ static int add_avrct(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2232,6 +2313,7 @@ static int add_avrtg(sdp_session_t *session, svc_info_t *si) memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2742,7 +2824,7 @@ struct { { "PANU", PANU_SVCLASS_ID, add_panu }, { "HID", HID_SVCLASS_ID, NULL }, - { "CIP", CIP_SVCLASS_ID, NULL }, + { "CIP", CIP_SVCLASS_ID, add_cip }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, @@ -2800,7 +2882,9 @@ done: static struct option add_options[] = { { "help", 0, 0, 'h' }, { "handle", 1, 0, 'r' }, + { "psm", 1, 0, 'p' }, { "channel", 1, 0, 'c' }, + { "network", 1, 0, 'n' }, { 0, 0, 0, 0 } }; @@ -2824,8 +2908,23 @@ static int cmd_add(int argc, char **argv) else si.handle = strtol(optarg + 2, NULL, 16); break; + case 'p': + if (strncasecmp(optarg, "0x", 2)) + si.psm = atoi(optarg); + else + si.psm = strtol(optarg + 2, NULL, 16); + break; case 'c': - si.channel = atoi(optarg); + if (strncasecmp(optarg, "0x", 2)) + si.channel = atoi(optarg); + else + si.channel = strtol(optarg + 2, NULL, 16); + break; + case 'n': + if (strncasecmp(optarg, "0x", 2)) + si.network = atoi(optarg); + else + si.network = strtol(optarg + 2, NULL, 16); break; default: printf(add_help); -- cgit From e45e2d95822026cd2fd1de52644ba5096a1d4858 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 21 Jan 2006 13:36:10 +0000 Subject: Add HCRP service identifier --- tools/sdptool.1 | 2 +- tools/sdptool.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 6f8d634d..5392a97c 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -75,7 +75,7 @@ Services are identified and manipulated with a 4-byte \fBrecord_handle\fP Search for services.. .IP "" 10 Known service names are DID, SP, DUN, LAN, FAX, OPUSH, -FTP, HS, HF, HFAG, SAP, NAP, GN, PANU, HID, CIP, +FTP, HS, HF, HFAG, SAP, NAP, GN, PANU, HCRP, HID, CIP, A2SRC, A2SNK, AVRCT, AVRTG, UDIUE, UDITE and SYNCML. .IP "\fBbrowse [--tree] [--raw] [bdaddr]\fP" 10 Browse all available services on the device diff --git a/tools/sdptool.c b/tools/sdptool.c index 0484d8af..556d0a89 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2823,6 +2823,7 @@ struct { { "GN", GN_SVCLASS_ID, add_gn }, { "PANU", PANU_SVCLASS_ID, add_panu }, + { "HCRP", HCR_SVCLASS_ID, NULL }, { "HID", HID_SVCLASS_ID, NULL }, { "CIP", CIP_SVCLASS_ID, add_cip }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, -- cgit From b2dfbf8a88f83dd6293a6535a002b572c973de9b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 24 Jan 2006 23:34:49 +0000 Subject: Add service record for direct printing --- tools/sdptool.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 556d0a89..79ca3544 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1785,6 +1785,71 @@ end: return ret; } +static int add_directprint(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[3]; + sdp_record_t record; + uint8_t chan = si->channel ? si->channel : 12; + sdp_data_t *channel; + int ret = 0; + + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&opush_uuid, DIRECT_PRINTING_SVCLASS_ID); + svclass_id = sdp_list_append(0, &opush_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, BASIC_PRINTING_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &chan); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + sdp_uuid16_create(&obex_uuid, OBEX_UUID); + proto[2] = sdp_list_append(0, &obex_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Direct Printing", 0, 0); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + + printf("Direct Printing service registered\n"); + +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(proto[2], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + + return ret; +} + static int add_nap(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -2813,6 +2878,7 @@ struct { { "FAX", FAX_SVCLASS_ID, add_fax }, { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, { "FTP", OBEX_FILETRANS_SVCLASS_ID, add_ftp }, + { "PRINT", DIRECT_PRINTING_SVCLASS_ID, add_directprint }, { "HS", HEADSET_SVCLASS_ID, add_headset }, { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, -- cgit From 05e39374143b7b052e49ef65382ed30fe276a442 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 30 Jan 2006 21:25:48 +0000 Subject: Add definition for radio test commands --- tools/csr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index f1c63117..6893574b 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -59,6 +59,7 @@ #define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ #define CSR_VARID_PS_CLR 0x4818 /* uint16 */ #define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */ +#define CSR_VARID_RADIOTEST 0x5004 /* complex */ #define CSR_VARID_PS_CLR_STORES 0x500c /* complex */ #define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */ #define CSR_VARID_CONFIG_UART 0x6802 /* uint16 */ -- cgit From 97e0baa36f2177c90f58c3d3670feed5149f354a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 30 Jan 2006 23:22:51 +0000 Subject: Add support for TXData1 radio test command --- tools/bccmd.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index 62ffd0ce..b48eb525 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -429,6 +429,31 @@ static int cmd_enabletx(int transport, int argc, char *argv[]) return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0); } +static int cmd_rttxdata1(int transport, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t freq, level; + + OPT_HELP(2, NULL); + + freq = atoi(argv[0]); + + if (!strncasecmp(argv[1], "0x", 2)) + level = strtol(argv[1], NULL, 16); + else + level = atoi(argv[1]); + + memset(array, 0, sizeof(array)); + array[0] = 0x04; + array[1] = 0x00; + array[2] = freq & 0xff; + array[3] = freq >> 8; + array[4] = level & 0xff; + array[5] = level >> 8; + + return transport_write(transport, CSR_VARID_RADIOTEST, array, 8); +} + static int cmd_memtypes(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -932,6 +957,7 @@ static struct { { "warmreset", cmd_warmreset, "", "Perform warm reset" }, { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "rttxdata1", cmd_rttxdata1, " ","TXData1 radio test" }, { "memtypes", cmd_memtypes, NULL, "Get memory types" }, { "psget", cmd_psget, "", "Get value for PS key" }, { "psset", cmd_psset, " ", "Set value for PS key" }, -- cgit From 431b6b66ff50f037ebcb7b8f85feff8255a5cd17 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Tue, 31 Jan 2006 18:15:07 +0000 Subject: add radio test (rttxdata1) --- tools/bccmd.8 | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/bccmd.8 b/tools/bccmd.8 index 82727009..91d3ba86 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -75,6 +75,9 @@ Disable TX on the device .BI enabletx Enable TX on the device .TP +.BI rttxdata1\ \ +TXData1 radio test +.TP .BI memtypes Get memory types .TP -- cgit From 49244d8ca41191d042fbed0732bb14db99fd56c8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 3 Feb 2006 18:45:50 +0000 Subject: Implement the gnip (reverse ping) support --- tools/l2ping.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/l2ping.c b/tools/l2ping.c index 0fe3d11a..0ae61c9d 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -50,6 +50,7 @@ static int ident = 200; static int delay = 1; static int count = -1; static int timeout = 10; +static int reverse = 0; /* Stats */ static int sent_pkt = 0; @@ -144,13 +145,17 @@ static void ping(char *svr) l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; /* Build command header */ - cmd->code = L2CAP_ECHO_REQ; cmd->ident = id; cmd->len = htobs(size); + if (reverse) + cmd->code = L2CAP_ECHO_RSP; + else + cmd->code = L2CAP_ECHO_REQ; + gettimeofday(&tv_send, NULL); - /* Send Echo Request */ + /* Send Echo Command */ if (send(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0) <= 0) { perror("Send failed"); exit(1); @@ -192,8 +197,9 @@ static void ping(char *svr) continue; /* Check type */ - if (cmd->code == L2CAP_ECHO_RSP) + if (!reverse && cmd->code == L2CAP_ECHO_RSP) break; + if (cmd->code == L2CAP_COMMAND_REJ) { printf("Peer doesn't support Echo packets\n"); exit(1); @@ -226,7 +232,7 @@ static void usage(void) { printf("l2ping - L2CAP ping\n"); printf("Usage:\n"); - printf("\tl2ping [-i device] [-s size] [-c count] [-t timeout] [-f] \n"); + printf("\tl2ping [-i device] [-s size] [-c count] [-t timeout] [-f] [-r] \n"); } int main(int argc, char *argv[]) @@ -236,7 +242,7 @@ int main(int argc, char *argv[]) /* Default options */ bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"i:s:c:t:f")) != EOF) { + while ((opt=getopt(argc,argv,"i:s:c:t:fr")) != EOF) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -250,6 +256,11 @@ int main(int argc, char *argv[]) delay = 0; break; + case 'r': + /* Use responses instead of requests */ + reverse = 1; + break; + case 'c': count = atoi(optarg); break; -- cgit From b7d130c68efdeea62d459e5c6c968c89412d9f46 Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Fri, 3 Feb 2006 18:48:52 +0000 Subject: gnip (reverse ping) --- tools/l2ping.1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/l2ping.1 b/tools/l2ping.1 index f415dd9c..ab92caf7 100644 --- a/tools/l2ping.1 +++ b/tools/l2ping.1 @@ -13,6 +13,8 @@ l2ping \- Send L2CAP echo request and receive answer .I -t timeout ] [ .I -f +] [ +.I -r ] < .I bd_addr > @@ -50,6 +52,9 @@ seconds for the response. Kind of flood ping. Use with care! It reduces the delay time between packets to 0. .TP +.I -r +Reverse ping (gnip?). Send echo response instead of echo request. +.TP .I bd_addr The Bluetooth MAC address to be pinged in dotted hex notation like .B 01:02:03:ab:cd:ef @@ -58,4 +63,4 @@ or .SH AUTHORS Written by Maxim Krasnyansky and Marcel Holtmann .PP -man page by Nils Faerber . +man page by Nils Faerber , Adam Laurie . -- cgit From 8b25f36fba836612200a6d1022858d6f2649db72 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 8 Feb 2006 11:09:24 +0000 Subject: Add SDP service record for HID keyboards --- tools/sdptool.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 170 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 79ca3544..afdc567a 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1632,13 +1632,16 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("SIM Access service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2055,6 +2058,168 @@ end: return ret; } +static int add_hid_keyb(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, hidkb_uuid, l2cap_uuid, hidp_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[3]; + sdp_data_t *channel, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2; + int i; + uint8_t dtd = SDP_UINT16; + uint8_t dtd2 = SDP_UINT8; + uint8_t dtd_data = SDP_TEXT_STR8; + void *dtds[2]; + void *values[2]; + void *dtds2[2]; + void *values2[2]; + int leng[2]; + uint8_t hid_spec_type = 0x22; + uint16_t hid_attr_lang[] = { 0x409, 0x100 }; + static const uint8_t ctrl = 0x11; + static const uint8_t intr = 0x13; + static const uint16_t hid_attr[] = { 0x100, 0x111, 0x40, 0x0d, 0x01, 0x01 }; + static const uint16_t hid_attr2[] = { 0x0, 0x01, 0x100, 0x1f40, 0x01, 0x01 }; + const uint8_t hid_spec[] = { + 0x05, 0x01, // usage page + 0x09, 0x06, // keyboard + 0xa1, 0x01, // key codes + 0x85, 0x01, // minimum + 0x05, 0x07, // max + 0x19, 0xe0, // logical min + 0x29, 0xe7, // logical max + 0x15, 0x00, // report size + 0x25, 0x01, // report count + 0x75, 0x01, // input data variable absolute + 0x95, 0x08, // report count + 0x81, 0x02, // report size + 0x75, 0x08, + 0x95, 0x01, + 0x81, 0x01, + 0x75, 0x01, + 0x95, 0x05, + 0x05, 0x08, + 0x19, 0x01, + 0x29, 0x05, + 0x91, 0x02, + 0x75, 0x03, + 0x95, 0x01, + 0x91, 0x01, + 0x75, 0x08, + 0x95, 0x06, + 0x15, 0x00, + 0x26, 0xff, + 0x00, 0x05, + 0x07, 0x19, + 0x00, 0x2a, + 0xff, 0x00, + 0x81, 0x00, + 0x75, 0x01, + 0x95, 0x01, + 0x15, 0x00, + 0x25, 0x01, + 0x05, 0x0c, + 0x09, 0xb8, + 0x81, 0x06, + 0x09, 0xe2, + 0x81, 0x06, + 0x09, 0xe9, + 0x81, 0x02, + 0x09, 0xea, + 0x81, 0x02, + 0x75, 0x01, + 0x95, 0x04, + 0x81, 0x01, + 0xc0 // end tag + }; + + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + add_lang_attr(&record); + + sdp_uuid16_create(&hidkb_uuid, HID_SVCLASS_ID); + svclass_id = sdp_list_append(0, &hidkb_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, HID_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, profile); + sdp_set_profile_descs(&record, pfseq); + + /* protocols */ + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[1] = sdp_list_append(0, &l2cap_uuid); + channel = sdp_data_alloc(SDP_UINT8, &ctrl); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(0, proto[1]); + + sdp_uuid16_create(&hidp_uuid, HIDP_UUID); + proto[2] = sdp_list_append(0, &hidp_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + /* additional protocols */ + proto[1] = sdp_list_append(0, &l2cap_uuid); + channel = sdp_data_alloc(SDP_UINT8, &intr); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(0, proto[1]); + + sdp_uuid16_create(&hidp_uuid, HIDP_UUID); + proto[2] = sdp_list_append(0, &hidp_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_add_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "HID Keyboard", NULL, NULL); + + for (i = 0; i < sizeof(hid_attr) / 2; i++) + sdp_attr_add_new(&record, + SDP_ATTR_HID_DEVICE_RELEASE_NUMBER + i, + SDP_UINT16, &hid_attr[i]); + + dtds[0] = &dtd2; + values[0] = &hid_spec_type; + dtds[1] = &dtd_data; + values[1] = (uint8_t *) hid_spec; + leng[0] = 0; + leng[1] = sizeof(hid_spec); + hid_spec_lst = sdp_seq_alloc_with_length(dtds, values, leng, 2); + hid_spec_lst2 = sdp_data_alloc(SDP_SEQ8, hid_spec_lst); + sdp_attr_add(&record, SDP_ATTR_HID_DESCRIPTOR_LIST, hid_spec_lst2); + + for (i = 0; i < sizeof(hid_attr_lang) / 2; i++) { + dtds2[i] = &dtd; + values2[i] = &hid_attr_lang[i]; + } + + lang_lst = sdp_seq_alloc(dtds2, values2, sizeof(hid_attr_lang) / 2); + lang_lst2 = sdp_data_alloc(SDP_SEQ8, lang_lst); + sdp_attr_add(&record, SDP_ATTR_HID_LANG_ID_BASE_LIST, lang_lst2); + + sdp_attr_add_new(&record, SDP_ATTR_HID_SDP_DISABLE, SDP_UINT16, &hid_attr2[0]); + + for (i = 0; i < sizeof(hid_attr2) / 2 - 1; i++) + sdp_attr_add_new(&record, SDP_ATTR_HID_REMOTE_WAKEUP + i, + SDP_UINT16, &hid_attr2[i + 1]); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("HID keyboard service registered\n"); + + return 0; +} static int add_cip(sdp_session_t *session, svc_info_t *si) { @@ -2429,7 +2594,7 @@ done: return ret; } -static int add_udiue(sdp_session_t *session, svc_info_t *si) +static int add_udi_ue(sdp_session_t *session, svc_info_t *si) { sdp_record_t record; sdp_list_t *root, *svclass, *proto; @@ -2470,7 +2635,7 @@ static int add_udiue(sdp_session_t *session, svc_info_t *si) return 0; } -static int add_udite(sdp_session_t *session, svc_info_t *si) +static int add_udi_te(sdp_session_t *session, svc_info_t *si) { sdp_record_t record; sdp_list_t *root, *svclass, *proto; @@ -2891,6 +3056,7 @@ struct { { "HCRP", HCR_SVCLASS_ID, NULL }, { "HID", HID_SVCLASS_ID, NULL }, + { "KEYB", HID_SVCLASS_ID, add_hid_keyb }, { "CIP", CIP_SVCLASS_ID, add_cip }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, @@ -2899,8 +3065,8 @@ struct { { "AVRCT", AV_REMOTE_SVCLASS_ID, add_avrct }, { "AVRTG", AV_REMOTE_TARGET_SVCLASS_ID, add_avrtg }, - { "UDIUE", UDI_MT_SVCLASS_ID, add_udiue }, - { "UDITE", UDI_TA_SVCLASS_ID, add_udite }, + { "UDIUE", UDI_MT_SVCLASS_ID, add_udi_ue }, + { "UDITE", UDI_TA_SVCLASS_ID, add_udi_te }, { "SR1", 0, add_sr1, sr1_uuid }, { "SYNCML", 0, add_syncml, syncml_uuid }, -- cgit From 0722d48e5cd78d94fc66e27de13a726ad81d3425 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 8 Feb 2006 11:16:47 +0000 Subject: Add service record for SEMC High Level Authentication --- tools/sdptool.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index afdc567a..fb1a0fbf 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -3029,9 +3029,57 @@ static int add_isync(sdp_session_t *session, svc_info_t *si) return 0; } +static int add_semchla(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_profile_desc_t profile; + sdp_list_t *root, *svclass, *proto, *profiles; + uuid_t root_uuid, service_uuid, l2cap_uuid, semchla_uuid; + uint16_t psm = 0xf0f9; + + memset(&record, 0, sizeof(record)); + record.handle = si->handle; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append( + sdp_list_append(NULL, &l2cap_uuid), sdp_data_alloc(SDP_UINT16, &psm))); + + sdp_uuid32_create(&semchla_uuid, 0x8e770300); + proto = sdp_list_append(proto, sdp_list_append(NULL, &semchla_uuid)); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid32_create(&service_uuid, 0x8e771301); + svclass = sdp_list_append(NULL, &service_uuid); + + sdp_set_service_classes(&record, svclass); + + sdp_uuid32_create(&profile.uuid, 0x8e771302); // Headset + //sdp_uuid32_create(&profile.uuid, 0x8e771303); // Phone + profile.version = 0x0100; + profiles = sdp_list_append(NULL, &profile); + sdp_set_profile_descs(&record, profiles); + + sdp_set_info_attr(&record, "SEMC HLA", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + /* SEMC High Level Authentication */ + printf("SEMC HLA service registered\n"); + + return 0; +} + struct { char *name; - uint16_t class; + uint32_t class; int (*add)(sdp_session_t *sess, svc_info_t *si); unsigned char *uuid; } service[] = { @@ -3068,6 +3116,8 @@ struct { { "UDIUE", UDI_MT_SVCLASS_ID, add_udi_ue }, { "UDITE", UDI_TA_SVCLASS_ID, add_udi_te }, + { "SEMCHLA", 0x8e771301, add_semchla }, + { "SR1", 0, add_sr1, sr1_uuid }, { "SYNCML", 0, add_syncml, syncml_uuid }, { "ACTIVESYNC", 0, add_activesync, async_uuid }, @@ -3435,7 +3485,7 @@ static int cmd_search(int argc, char **argv) { struct search_context context; unsigned char *uuid = NULL; - uint16_t class = 0; + uint32_t class = 0; bdaddr_t bdaddr; int has_addr = 0; int i; @@ -3494,9 +3544,14 @@ static int cmd_search(int argc, char **argv) } } - if (class) - sdp_uuid16_create(&context.group, class); - else + if (class) { + if (class & 0xffff0000) + sdp_uuid32_create(&context.group, class); + else { + uint16_t class16 = class & 0xffff; + sdp_uuid16_create(&context.group, class16); + } + } else sdp_uuid128_create(&context.group, uuid); if (has_addr) -- cgit From d0d48dda01cd66f89dc46c55e7b3741e5427da14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Feb 2006 11:49:04 +0000 Subject: Add values for single channel and hopping on commands --- tools/csr.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index 6893574b..c3277a45 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -56,9 +56,11 @@ #define CSR_VARID_PS_FACTORY_RESTORE 0x400d /* valueless */ #define CSR_VARID_PS_FACTORY_RESTORE_ALL 0x400e /* valueless */ #define CSR_VARID_PS_DEFRAG_RESET 0x400f /* valueless */ +#define CSR_VARID_HOPPING_ON 0x4011 /* valueless */ #define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ #define CSR_VARID_PS_CLR 0x4818 /* uint16 */ #define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */ +#define CSR_VARID_SINGLE_CHAN 0x482e /* uint16 */ #define CSR_VARID_RADIOTEST 0x5004 /* complex */ #define CSR_VARID_PS_CLR_STORES 0x500c /* complex */ #define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */ -- cgit From f0b5cb444eba02a9b34e11b88d6a0458516450ce Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Feb 2006 11:55:35 +0000 Subject: Add support for channel selection and reverting to normal hopping --- tools/bccmd.8 | 6 ++++++ tools/bccmd.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'tools') diff --git a/tools/bccmd.8 b/tools/bccmd.8 index 91d3ba86..e4642fec 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -75,6 +75,12 @@ Disable TX on the device .BI enabletx Enable TX on the device .TP +.BI singlechan\ +Lock radio on specific channel +.TP +.BI hoppingon +Revert to channel hopping +.TP .BI rttxdata1\ \ TXData1 radio test .TP diff --git a/tools/bccmd.c b/tools/bccmd.c index b48eb525..f86b93ea 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -429,6 +429,35 @@ static int cmd_enabletx(int transport, int argc, char *argv[]) return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0); } +static int cmd_singlechan(int transport, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t channel; + + OPT_HELP(1, NULL); + + channel = atoi(argv[0]); + + if (channel > 2401 && channel < 2481) + channel -= 2402; + + if (channel > 78) { + errno = EINVAL; + return -1; + } + + memset(array, 0, sizeof(array)); + array[0] = channel & 0xff; + array[1] = channel >> 8; + + return transport_write(transport, CSR_VARID_SINGLE_CHAN, array, 8); +} + +static int cmd_hoppingon(int transport, int argc, char *argv[]) +{ + return transport_write(transport, CSR_VARID_HOPPING_ON, NULL, 0); +} + static int cmd_rttxdata1(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -957,6 +986,8 @@ static struct { { "warmreset", cmd_warmreset, "", "Perform warm reset" }, { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "singlechan",cmd_singlechan,"", "Lock radio on specific channel" }, + { "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" }, { "rttxdata1", cmd_rttxdata1, " ","TXData1 radio test" }, { "memtypes", cmd_memtypes, NULL, "Get memory types" }, { "psget", cmd_psget, "", "Get value for PS key" }, -- cgit From e15aceaa85267a21b84a10a9a0cb22090c50ccc4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Feb 2006 12:29:21 +0000 Subject: Add value for killing VM application --- tools/csr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.h b/tools/csr.h index c3277a45..491ab4b7 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -56,6 +56,7 @@ #define CSR_VARID_PS_FACTORY_RESTORE 0x400d /* valueless */ #define CSR_VARID_PS_FACTORY_RESTORE_ALL 0x400e /* valueless */ #define CSR_VARID_PS_DEFRAG_RESET 0x400f /* valueless */ +#define CSR_VARID_KILL_VM_APPLICATION 0x4010 /* valueless */ #define CSR_VARID_HOPPING_ON 0x4011 /* valueless */ #define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ #define CSR_VARID_PS_CLR 0x4818 /* uint16 */ -- cgit From bce4ba5885e7afffce20dbd7214e633a31b95a81 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 15 Feb 2006 08:08:02 +0000 Subject: Fix for displaying the correct class of device strings --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 703bdbd8..d641d09c 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -676,7 +676,7 @@ static void cmd_class(int ctl, int hdev, char *opt) } else printf("Unspecified"); printf("\n\tDevice Class: "); - if ((cls[1] & 0x1f) > sizeof(*major_devices)) + if ((cls[1] & 0x1f) >= sizeof(major_devices) / sizeof(*major_devices)) printf("Invalid Device Class!\n"); else printf("%s, %s\n", major_devices[cls[1] & 0x1f], -- cgit From 65d1a12cfff5d53e535134dbf03eedcc02ffb589 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 15 Feb 2006 08:09:39 +0000 Subject: Improve display of UUID-128 strings --- tools/sdptool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index fb1a0fbf..efe59e02 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -989,7 +989,10 @@ static void print_service_class(void *value, void *userData) sdp_uuid2strn(uuid, UUID_str, MAX_LEN_UUID_STR); sdp_svclass_uuid2strn(uuid, ServiceClassUUID_str, MAX_LEN_SERVICECLASS_UUID_STR); - printf(" \"%s\" (0x%s)\n", ServiceClassUUID_str, UUID_str); + if (uuid->type != SDP_UUID128) + printf(" \"%s\" (0x%s)\n", ServiceClassUUID_str, UUID_str); + else + printf(" UUID 128: %s\n", UUID_str); } static void print_service_desc(void *value, void *user) -- cgit From 5dc0ed851328becdf700a81c2408d15704407048 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 15 Feb 2006 09:17:52 +0000 Subject: Fix revision string for Broadcom devices --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index d641d09c..1e1813f9 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1369,7 +1369,7 @@ static void print_rev_digianswer(int dd) static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) { - printf("\tFirmware %d.%d / %d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); + printf("\tFirmware %d.%d / %d\n", hci_rev & 0xff, lmp_subver >> 8, lmp_subver & 0xff); } static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver) -- cgit From 1670b1237dee92f83cb46ea0d9840d88dd49c57a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Feb 2006 21:14:23 +0000 Subject: Fix service classes decoding --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1e1813f9..e6868f0c 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -666,7 +666,7 @@ static void cmd_class(int ctl, int hdev, char *opt) printf("\tService Classes: "); if (cls[2]) { int first = 1; - for (s = 0; s < sizeof(*services); s++) + for (s = 0; s < (sizeof(services) / sizeof(*services)); s++) if (cls[2] & (1 << s)) { if (!first) printf(", "); -- cgit From 868eb388eacf226e1ff0fc84c7923aaa13836216 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 9 Mar 2006 20:15:58 +0000 Subject: Add workaround for missing Apple service identifier --- tools/sdptool.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index efe59e02..8bee7985 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -45,6 +45,10 @@ #include +#ifndef APPLE_AGENT_SVCLASS_ID +#define APPLE_AGENT_SVCLASS_ID 0x2112 +#endif + #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1) /* -- cgit From fb3a213c3304d9855ad534d8d44151b3b8e92a32 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 20 Mar 2006 22:24:24 +0000 Subject: Fix typo in manual page --- tools/l2ping.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/l2ping.1 b/tools/l2ping.1 index ab92caf7..bd07e198 100644 --- a/tools/l2ping.1 +++ b/tools/l2ping.1 @@ -43,7 +43,7 @@ Send .B count number of packets then exit. .TP -.I -c \fBtimeout\fP +.I -t \fBtimeout\fP Wait .B \fBtimeout\fP seconds for the response. -- cgit From fc4ca3634da071b9a75961be179cccbe88101b75 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 20 Mar 2006 22:29:03 +0000 Subject: Detect TTY detach and restore line discipline --- tools/hciattach.c | 124 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 89 insertions(+), 35 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index e583e8db..cfccb9ab 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,23 @@ struct uart_t { #define FLOW_CTL 0x0001 +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ +} + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static void sig_alarm(int sig) +{ + fprintf(stderr, "Initialization timed out.\n"); + exit(1); +} + static int uart_speed(int s) { switch (s) { @@ -110,12 +128,6 @@ static int set_speed(int fd, struct termios *ti, int speed) return tcsetattr(fd, TCSANOW, ti); } -static void sig_alarm(int sig) -{ - fprintf(stderr, "Initialization timed out.\n"); - exit(1); -} - /* * Read an HCI event from the given file descriptor. */ @@ -158,6 +170,7 @@ static int read_hci_event(int fd, unsigned char* buf, int size) return -1; count += r; } + return count; } @@ -201,6 +214,7 @@ static int ericsson(int fd, struct uart_t *u, struct termios *ti) perror("Failed to write init command"); return -1; } + nanosleep(&tm, NULL); return 0; } @@ -237,6 +251,7 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) perror("Failed to write init command"); return -1; } + nanosleep(&tm, NULL); return 0; } @@ -289,7 +304,7 @@ static int texas(int fd, struct uart_t *u, struct termios *ti) /* Print LMP subversion */ fprintf(stderr, "Texas module LMP sub-version : 0x%02x%02x\n", resp[14] & 0xFF, resp[13] & 0xFF); - + nanosleep(&tm, NULL); return 0; } @@ -297,7 +312,7 @@ static int texas(int fd, struct uart_t *u, struct termios *ti) static int read_check(int fd, void *buf, int count) { int res; - + do { res = read(fd, buf, count); if (res != -1) { @@ -305,10 +320,10 @@ static int read_check(int fd, void *buf, int count) count -= res; } } while (count && (errno == 0 || errno == EINTR)); - + if (count) return -1; - + return 0; } @@ -321,13 +336,14 @@ static void bcsp_tshy_sig_alarm(int sig) { static int retries=0; unsigned char bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}; - + if (retries < 10) { retries++; write(serial_fd, &bcsp_sync_pkt, 10); alarm(1); return; } + tcflush(serial_fd, TCIOFLUSH); fprintf(stderr, "BCSP initialization timed out\n"); exit(1); @@ -337,12 +353,14 @@ static void bcsp_tconf_sig_alarm(int sig) { static int retries=0; unsigned char bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}; + if (retries < 10){ retries++; write(serial_fd, &bcsp_conf_pkt, 10); alarm(1); return; } + tcflush(serial_fd, TCIOFLUSH); fprintf(stderr, "BCSP initialization timed out\n"); exit(1); @@ -390,20 +408,19 @@ static int bcsp(int fd, struct uart_t *u, struct termios *ti) return -1; } } while (byte != 0xC0); - + do { if ( read_check(fd, &bcsph[0], 1) == -1){ perror("Failed to read"); return -1; } - } while (bcsph[0] == 0xC0); - + if ( read_check(fd, &bcsph[1], 3) == -1){ perror("Failed to read"); return -1; } - + if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) continue; if (bcsph[1] != 0x41 || bcsph[2] != 0x00) @@ -437,8 +454,8 @@ static int bcsp(int fd, struct uart_t *u, struct termios *ti) do { if (read_check(fd, &bcsph[0], 1) == -1){ - perror("Failed to read"); - return -1; + perror("Failed to read"); + return -1; } } while (bcsph[0] == 0xC0); @@ -446,7 +463,7 @@ static int bcsp(int fd, struct uart_t *u, struct termios *ti) perror("Failed to read"); return -1; } - + if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) continue; @@ -553,7 +570,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) /* Display that to user */ fprintf(stderr, "CSR build ID 0x%02X-0x%02X\n", resp[15] & 0xFF, resp[14] & 0xFF); - + /* Try to read the current speed of the CSR chip */ clen = 5 + (5 + 4)*2; /* -- HCI header */ @@ -638,6 +655,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) perror("Failed to write init command (SET_UART_SPEED)"); return -1; } + nanosleep(&tm, NULL); return 0; } @@ -715,7 +733,7 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) // 01 flow on // 01 Hci Transport type = Uart // xx Baud rate set (see above) - } else { + } else { // ups, got error. return -1; } @@ -735,7 +753,7 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } nanosleep(&tm, NULL); - + // now the uart baud rate on the silicon wave module is set and effective. // change our own baud rate as well. Then there is a reset event comming in // on the *new* baud rate. This is *undocumented*! The packet looks like this: @@ -798,11 +816,11 @@ static int st(int fd, struct uart_t *u, struct termios *ti) perror("Failed to write init command"); return -1; } + nanosleep(&tm, NULL); return 0; } - /* * Broadcom specific initialization * Extracted from Jungo openrg @@ -819,11 +837,13 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) cmd[1] = 0x03; cmd[2] = 0x0c; cmd[3] = 0x00; + /* Send command */ if (write(fd, cmd, 4) != 4) { fprintf(stderr, "Failed to write reset command\n"); return -1; } + /* Read reply */ if ((n = read_hci_event(fd, resp, 4)) < 0) { fprintf(stderr, "Failed to reset chip\n"); @@ -837,12 +857,14 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) cmd[1] = 0x01; cmd[2] = 0x10; cmd[3] = 0x00; + /* Send command */ if (write(fd, cmd, 4) != 4) { fprintf(stderr, "Failed to write \"read local version\" " "command\n"); return -1; } + /* Read reply */ if ((n = read_hci_event(fd, resp, 4)) < 0) { fprintf(stderr, "Failed to read local version\n"); @@ -856,12 +878,14 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) cmd[1] = 0x02; cmd[2] = 0x10; cmd[3] = 0x00; + /* Send command */ if (write(fd, cmd, 4) != 4) { fprintf(stderr, "Failed to write \"read local supported " "commands\" command\n"); return -1; } + /* Read reply */ if ((n = read_hci_event(fd, resp, 4)) < 0) { fprintf(stderr, "Failed to read local supported commands\n"); @@ -906,10 +930,12 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) fprintf(stderr, "Failed to write \"set baud rate\" command\n"); return -1; } + if ((n = read_hci_event(fd, resp, 6)) < 0) { fprintf(stderr, "Failed to set baud rate\n"); return -1; } + return 0; } @@ -996,7 +1022,7 @@ struct uart_t * get_by_type(char *type) int init_uart(char *dev, struct uart_t *u, int send_break) { struct termios ti; - int fd, i; + int fd, i; fd = open(dev, O_RDWR | O_NOCTTY); if (fd < 0) { @@ -1071,23 +1097,21 @@ static void usage(void) printf("\thciattach -l\n"); } -extern int optind, opterr, optopt; -extern char *optarg; - int main(int argc, char *argv[]) { struct uart_t *u = NULL; - int detach, printpid, opt, i, n; + int detach, printpid, opt, i, n, ld; int to = 5; int init_speed = 0; int send_break = 0; pid_t pid; struct sigaction sa; + struct pollfd p; char dev[PATH_MAX]; detach = 1; printpid = 0; - + while ((opt=getopt(argc, argv, "bnpt:s:l")) != EOF) { switch(opt) { case 'b': @@ -1131,9 +1155,9 @@ int main(int argc, char *argv[]) for (n = 0; optind < argc; n++, optind++) { char *opt; - + opt = argv[optind]; - + switch(n) { case 0: dev[0] = 0; @@ -1182,13 +1206,13 @@ int main(int argc, char *argv[]) u->init_speed = init_speed; memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_NOCLDSTOP; + sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = sig_alarm; sigaction(SIGALRM, &sa, NULL); /* 5 seconds should be enough for initialization */ alarm(to); - + n = init_uart(dev, u, send_break); if (n < 0) { perror("Can't initialize device"); @@ -1197,16 +1221,46 @@ int main(int argc, char *argv[]) alarm(0); + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + if (detach) { if ((pid = fork())) { if (printpid) printf("%d\n", pid); return 0; } - for (i=0; i<20; i++) - if (i != n) close(i); + + for (i = 0; i < 20; i++) + if (i != n) + close(i); + } + + p.fd = n; + p.events = POLLERR | POLLHUP; + + while (!__io_canceled) { + p.revents = 0; + if (poll(&p, 1, 100)) + break; + } + + /* Restore TTY line discipline */ + ld = N_TTY; + if (ioctl(n, TIOCSETD, &ld) < 0) { + perror("Can't restore line discipline"); + exit(1); } - while (1) sleep(999999999); return 0; } -- cgit From f8a36952f39f2c51d4cd6f2e170817d89724c422 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 20 Mar 2006 22:32:32 +0000 Subject: Add skeleton for ST Microelectronics init routine --- tools/Makefile.am | 2 ++ tools/hciattach_st.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tools/hciattach_st.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 08f5d742..d682448c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -37,6 +37,8 @@ bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) noinst_PROGRAMS = hcisecfilter ppporc +hciattach_SOURCES = hciattach.c hciattach_st.c + hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c new file mode 100644 index 00000000..db73cfb5 --- /dev/null +++ b/tools/hciattach_st.c @@ -0,0 +1,29 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2006 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include -- cgit From d9f928803e9e3f628d93c131cd0cb8f3170333a5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 Apr 2006 22:03:51 +0000 Subject: Add another Apple product id --- tools/hid2hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 7e033755..ef227a35 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -218,6 +218,7 @@ static struct device_id device_list[] = { { HID, 0x0458, 0x003f, switch_hidproxy }, { HCI, 0x05ac, 0x1000, switch_hidproxy }, { HID, 0x05ac, 0x8203, switch_hidproxy }, + { HID, 0x05ac, 0x8204, switch_hidproxy }, /* Apple Mac mini */ { HCI, 0x046d, 0xc703, switch_logitech }, { HCI, 0x046d, 0xc704, switch_logitech }, { HCI, 0x046d, 0xc705, switch_logitech }, -- cgit From b853badf9af0a9ea4acf13559137c0b958e86e05 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 16 Apr 2006 19:23:25 +0000 Subject: Add build ids for Unified 21d firmwares --- tools/csr.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index eec6c0e6..0a73debe 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -320,6 +320,13 @@ static struct { { 2655, "Unified 21c" }, { 2656, "Unified 21c" }, { 2658, "Unified 21c" }, + { 3057, "Unified 21d" }, + { 3058, "Unified 21d" }, + { 3059, "Unified 21d" }, + { 3060, "Unified 21d" }, + { 3062, "Unified 21d" }, + { 3063, "Unified 21d" }, + { 3064, "Unified 21d" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, -- cgit From ae2bada6379b2d56825f0d8cc48dbd9a1890a1bd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 16 Apr 2006 21:09:01 +0000 Subject: Update STLC2500 init routine --- tools/hciattach.c | 10 ++++++++++ tools/hciattach_st.c | 5 +++++ 2 files changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index cfccb9ab..885f202d 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -821,6 +821,13 @@ static int st(int fd, struct uart_t *u, struct termios *ti) return 0; } +extern stlc2500_init(int fd); + +static int stlc2500(int fd, struct uart_t *u, struct termios *ti) +{ + return stlc2500_init(fd); +} + /* * Broadcom specific initialization * Extracted from Jungo openrg @@ -962,6 +969,9 @@ struct uart_t uart[] = { /* ST Microelectronics minikits based on STLC2410/STLC2415 */ { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, st }, + /* ST Microelectronics minikits based on STLC2500 */ + { "stlc2500", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, stlc2500 }, + /* Sphinx Electronics PICO Card */ { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index db73cfb5..744ae838 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -27,3 +27,8 @@ #include #include + +int stlc2500_init(int fd) +{ + return 0; +} -- cgit From 0bf26d618424720586e0013256bdc39803c90c4a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 16 Apr 2006 22:04:19 +0000 Subject: Update STLC2500 init routine --- tools/hciattach_st.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'tools') diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index 744ae838..98179d71 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -27,8 +27,78 @@ #include #include +#include +#include +#include +#include + +static int do_command(int fd, uint8_t ogf, uint16_t ocf, + uint8_t *cparam, int clen, uint8_t *rparam, int rlen) +{ + uint16_t opcode = (uint16_t) ((ocf & 0x03ff) | (ogf << 10)); + unsigned char cp[254], rp[254]; + int len, size, offset = 3; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0x01; + cp[1] = opcode & 0xff; + cp[2] = opcode >> 8; + cp[3] = 0x00; + + if (write(fd, cp, 4) < 0) + return -1; + + do { + if (read(fd, rp, 1) < 1) + return -1; + } while (rp[0] != 0x04); + + if (read(fd, rp + 1, 2) < 2) + return -1; + + do { + len = read(fd, rp + offset, sizeof(rp) - offset); + offset += len; + } while (offset < rp[2] + 3); + + if (rp[0] != 0x04) { + errno = EIO; + return -1; + } + + switch (rp[1]) { + case 0x0e: + if (rp[6] != 0x00) + return -ENXIO; + offset = 3 + 4; + size = rp[2] - 4; + break; + default: + offset = 3; + size = rp[2]; + break; + } + + if (!rparam || rlen < size) + return -ENXIO; + + memcpy(rparam, rp + offset, size); + + return size; +} int stlc2500_init(int fd) { + unsigned char buf[254]; + int len; + + len = do_command(fd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf)); + + //printf("STLC2500 R%d.%d\n", buf[2], buf[1]); + + len = do_command(fd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf)); + + printf("%s\n", buf + 3); + return 0; } -- cgit From 892ff56030437019d237cd33b1434592c48c7df3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 17 Apr 2006 01:13:57 +0000 Subject: Change device address and reset --- tools/hciattach_st.c | 54 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index 98179d71..ee3ca2a7 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -32,20 +32,32 @@ #include #include +static int debug = 0; + static int do_command(int fd, uint8_t ogf, uint16_t ocf, uint8_t *cparam, int clen, uint8_t *rparam, int rlen) { - uint16_t opcode = (uint16_t) ((ocf & 0x03ff) | (ogf << 10)); + //uint16_t opcode = (uint16_t) ((ocf & 0x03ff) | (ogf << 10)); unsigned char cp[254], rp[254]; int len, size, offset = 3; - memset(cp, 0, sizeof(cp)); cp[0] = 0x01; - cp[1] = opcode & 0xff; - cp[2] = opcode >> 8; - cp[3] = 0x00; + cp[1] = ocf & 0xff; + cp[2] = ogf << 2 | ocf >> 8; + cp[3] = clen; + + if (clen > 0) + memcpy(cp + 4, cparam, clen); + + if (debug) { + int i; + printf("[<"); + for (i = 0; i < clen + 4; i++) + printf(" %02x", cp[i]); + printf("]\n"); + } - if (write(fd, cp, 4) < 0) + if (write(fd, cp, clen + 4) < 0) return -1; do { @@ -61,18 +73,28 @@ static int do_command(int fd, uint8_t ogf, uint16_t ocf, offset += len; } while (offset < rp[2] + 3); + if (debug) { + int i; + printf("[>"); + for (i = 0; i < offset; i++) + printf(" %02x", rp[i]); + printf("]\n"); + } + if (rp[0] != 0x04) { errno = EIO; return -1; } switch (rp[1]) { - case 0x0e: + case 0x0e: /* command complete */ if (rp[6] != 0x00) return -ENXIO; offset = 3 + 4; size = rp[2] - 4; break; + case 0x0f: /* command status */ + /* fall through */ default: offset = 3; size = rp[2]; @@ -89,16 +111,30 @@ static int do_command(int fd, uint8_t ogf, uint16_t ocf, int stlc2500_init(int fd) { + unsigned char cmd[16]; unsigned char buf[254]; int len; len = do_command(fd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf)); - //printf("STLC2500 R%d.%d\n", buf[2], buf[1]); + printf("Patch: STLC2500_R%d_%02d_*.ptc\n", buf[2], buf[1]); len = do_command(fd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf)); - printf("%s\n", buf + 3); + printf("%s\n", buf); + + cmd[0] = 0xfe; + cmd[1] = 0x06; + cmd[2] = 0xba; + cmd[3] = 0xab; + cmd[4] = 0x00; + cmd[5] = 0xe1; + cmd[6] = 0x80; + cmd[7] = 0x00; + + len = do_command(fd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf)); + + len = do_command(fd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); return 0; } -- cgit From d168dc64106e440a149718436e63912b18e0064e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Apr 2006 00:49:40 +0000 Subject: Add patch and configuration download --- tools/hciattach_st.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index ee3ca2a7..0279d398 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -29,8 +29,10 @@ #include #include #include +#include #include #include +#include static int debug = 0; @@ -38,7 +40,7 @@ static int do_command(int fd, uint8_t ogf, uint16_t ocf, uint8_t *cparam, int clen, uint8_t *rparam, int rlen) { //uint16_t opcode = (uint16_t) ((ocf & 0x03ff) | (ogf << 10)); - unsigned char cp[254], rp[254]; + unsigned char cp[260], rp[260]; int len, size, offset = 3; cp[0] = 0x01; @@ -109,17 +111,104 @@ static int do_command(int fd, uint8_t ogf, uint16_t ocf, return size; } -int stlc2500_init(int fd) +static int load_file(int dd, uint16_t version, const char *suffix) +{ + DIR *dir; + struct dirent *d; + char filename[NAME_MAX], prefix[20]; + unsigned char cmd[256]; + unsigned char buf[256]; + uint8_t seqnum = 0; + int fd, size, len; + + memset(filename, 0, sizeof(filename)); + + snprintf(prefix, sizeof(prefix), "STLC2500_R%d_%02d_", + version >> 8, version & 0xff); + + dir = opendir("."); + if (!dir) + return -errno; + + while (1) { + d = readdir(dir); + if (!d) + break; + + if (strncmp(d->d_name + strlen(d->d_name) - strlen(suffix), + suffix, strlen(suffix))) + continue; + + if (strncmp(d->d_name, prefix, strlen(prefix))) + continue; + + snprintf(filename, sizeof(filename), "%s", d->d_name); + } + + closedir(dir); + + printf("Loading file %s\n", filename); + + fd = open(filename, O_RDONLY); + if (fd < 0) { + perror("Can't open firmware file"); + return -errno; + } + + while (1) { + size = read(fd, cmd + 1, 254); + if (size <= 0) + break; + + cmd[0] = seqnum; + + len = do_command(dd, 0xff, 0x002e, cmd, size + 1, buf, sizeof(buf)); + if (len < 1) + break; + + if (buf[0] != seqnum) { + fprintf(stderr, "Sequence number mismatch\n"); + break; + } + + seqnum++; + } + + close(fd); + + return 0; +} + +int stlc2500_init(int dd) { unsigned char cmd[16]; unsigned char buf[254]; + uint16_t version; int len; - len = do_command(fd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf)); + len = do_command(dd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf)); + if (len < 0) + return -1; + + version = buf[2] << 8 | buf[1]; + + if (load_file(dd, version, ".ptc") < 0) + return -1; - printf("Patch: STLC2500_R%d_%02d_*.ptc\n", buf[2], buf[1]); + len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); + if (len < 0) + return -1; - len = do_command(fd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf)); + if (load_file(dd, buf[2] << 8 | buf[1], ".ssf") < 0) + return -1; + + len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); + if (len < 0) + return -1; + + len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf)); + if (len < 0) + return -1; printf("%s\n", buf); @@ -132,9 +221,13 @@ int stlc2500_init(int fd) cmd[6] = 0x80; cmd[7] = 0x00; - len = do_command(fd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf)); + len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf)); + if (len < 0) + return -1; - len = do_command(fd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); + len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); + if (len < 0) + return -1; return 0; } -- cgit From 403066f6cd6f4df68f68178acc2db0926370e95c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Apr 2006 14:30:59 +0000 Subject: Cleanup main function declarations --- tools/hciconfig.c | 8 ++++---- tools/hcitool.c | 2 +- tools/sdptool.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index e6868f0c..3ebfc1c8 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1532,12 +1532,12 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"all", 0,0, 'a'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "all", 0, 0, 'a' }, + { 0, 0, 0, 0 } }; -int main(int argc, char **argv, char **env) +int main(int argc, char *argv[]) { int opt, ctl, i, cmd=0; diff --git a/tools/hcitool.c b/tools/hcitool.c index 2ad26bfe..594c2601 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -2081,7 +2081,7 @@ static struct option main_options[] = { { 0, 0, 0, 0 } }; -int main(int argc, char **argv) +int main(int argc, char *argv[]) { int opt, i, dev_id = -1; bdaddr_t ba; diff --git a/tools/sdptool.c b/tools/sdptool.c index 8bee7985..8beff568 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -3786,7 +3786,7 @@ static struct option main_options[] = { { 0, 0, 0, 0 } }; -int main(int argc, char **argv) +int main(int argc, char *argv[]) { int i, opt; -- cgit From 910d9fe22770d744f88eb42762ec678e4e0a16de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Apr 2006 18:21:14 +0000 Subject: Fix a small typo --- tools/hciattach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 885f202d..08b28f45 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -821,7 +821,7 @@ static int st(int fd, struct uart_t *u, struct termios *ti) return 0; } -extern stlc2500_init(int fd); +extern int stlc2500_init(int fd); static int stlc2500(int fd, struct uart_t *u, struct termios *ti) { -- cgit From af08011b31b086a947f97ed22a46efb48fc70b19 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 16 May 2006 15:50:35 +0000 Subject: Add build id for Unified 21e ROM firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 0a73debe..fea0c7c3 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -327,6 +327,7 @@ static struct { { 3062, "Unified 21d" }, { 3063, "Unified 21d" }, { 3064, "Unified 21d" }, + { 3164, "Unified 21e" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, -- cgit From fe2fcaafb891599e82853fcf2940e79cd25e8e78 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 30 May 2006 11:00:34 +0000 Subject: Add another Phonebook Access identifier --- tools/sdptool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 8beff568..d5ad511c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -306,6 +306,7 @@ static struct uuid_def uuid16_names[] = { { 0x112d, "SIM Access (SAP)", NULL, 0 }, { 0x112e, "Phonebook Access (PBAP) - PCE", NULL, 0 }, { 0x112f, "Phonebook Access (PBAP) - PSE", NULL, 0 }, + { 0x1130, "Phonebook Access (PBAP)", NULL, 0 }, /* ... */ { 0x1200, "PnPInformation", did_attrib_names, sizeof(did_attrib_names)/sizeof(struct attrib_def) }, -- cgit From 5c59f168117c1f3d48bafda1f868ae3784f28e23 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Jun 2006 18:36:20 +0000 Subject: Update manual pages --- tools/hciattach.8 | 55 +++++++++++------------ tools/hciconfig.8 | 132 +++++++++++++++++++++++++----------------------------- 2 files changed, 87 insertions(+), 100 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.8 b/tools/hciattach.8 index 0dadec99..430e8067 100644 --- a/tools/hciattach.8 +++ b/tools/hciattach.8 @@ -3,44 +3,41 @@ hciattach \- attach serial devices via UART HCI to BlueZ stack .SH SYNOPSIS .B hciattach -[ -n ] [ -p ] [ -t timeout ] < +.RB [\| \-n \|] +.RB [\| \-p \|] +.RB [\| \-t +.IR timeout \|] .I tty -> < -.I type -| -.I id -> [ +.IR type \||\| id .I speed -] [ .I flow -] .SH DESCRIPTION .LP Hciattach is used to attach a serial UART to the Bluetooth stack as HCI transport interface. .SH OPTIONS .TP -.BI -n +.B \-n Don't detach from controlling terminal. .TP -.BI -p +.B \-p Print the PID when detaching. .TP -.BI -t timeout +.BI \-t " timeout" Specify an initialization timeout. (Default is 5 seconds.) .TP -.I +.I tty This specifies the serial device to attach. A leading .B /dev can be omitted. Examples: .B /dev/ttyS1 .B ttyS2 .TP -.I +.IR type \||\| id The -.B type +.I type or -.B id +.I id of the Bluetooth device that is to be attached, i.e. vendor or other device specific identifier. Currently supported types are .RS @@ -48,45 +45,45 @@ specific identifier. Currently supported types are .B type .B description .TP -any +.B any Unspecified HCI_UART interface, no vendor specific options .TP -ericsson +.B ericsson Ericsson based modules .TP -digi +.B digi Digianswer based cards .TP -xircom +.B xircom Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter .TP -csr +.B csr CSR Casira serial adapter or BrainBoxes serial dongle (BL642) .TP -bboxes +.B bboxes BrainBoxes PCMCIA card (BL620) .TP -swave +.B swave Silicon Wave kits .TP -bcsp +.B bcsp Serial adapters using CSR chips with BCSP serial protocol .RE Supported IDs are (manufacturer id, product id) .RS .TP -0x0105, 0x080a +.B 0x0105, 0x080a Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter .TP -0x0160, 0x0002 +.B 0x0160, 0x0002 BrainBoxes PCMCIA card (BL620) .RE .TP -.I +.I speed The -.B speed +.I speed specifies the UART speed to use. Baudrates higher than 115.200bps require vendor specific initializations that are not implemented for all types of devices. In general the following speeds are supported: @@ -96,9 +93,9 @@ devices. In general the following speeds are supported: Supported vendor devices are automatically initialised to their respective best settings. .TP -.I +.I flow If the keyword -.B flow +.I flow is appended to the list of options then hardware flow control is forced on the serial link ( .B CRTSCTS diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 96990b06..da39a40c 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -2,89 +2,95 @@ .SH NAME hciconfig \- configure Bluetooth devices .SH SYNOPSIS -.B hciconfig -h +.B hciconfig +.B \-h .br -.B hciconfig [-a] +.B hciconfig +.RB [\| \-a \|] .br -.B hciconfig [-a] [command [command parameters]] +.B hciconfig +.RB [\| \-a \|] +.RI [\| command +.RI [\| "command parameters" \|]\|] .SH DESCRIPTION .LP -.B -hciconfig -is used to configure Bluetooth devices. is the name of a Bluetooth -device installed in the system. If is not given, -.B -hciconfig +.B hciconfig +is used to configure Bluetooth devices. +.I hciX +is the name of a Bluetooth device installed in the system. If +.I hciX +is not given, +.B hciconfig prints name and basic information about all the Bluetooth devices installed in -the system. If is given but no command is given, -it prints basic information on device only. Basic information is +the system. If +.I hciX +is given but no command is given, it prints basic information on device +.I hciX +only. Basic information is interface type, BD address, ACL MTU, SCO MTU, flags (up, init, running, raw, page scan enabled, inquiry scan enabled, inquiry, authentication enabled, encryption enabled). .SH OPTIONS .TP -.BI -h +.B \-h, \-\-help Gives a list of possible commands. .TP -.BI -a +.B \-a, \-\-all Other than the basic info, print features, packet type, link policy, link mode, name, class, version. .SH COMMANDS .TP -.BI up +.B up Open and initialize HCI device. .TP -.BI down +.B down Close HCI device. .TP -.BI reset +.B reset Reset HCI device. .TP -.BI rstat +.B rstat Reset statistic counters. .TP -.BI auth +.B auth Enable authentication (sets device to security mode 3). .TP -.BI noauth +.B noauth Disable authentication. .TP -.BI encrypt +.B encrypt Enable encryption (sets device to security mode 3). .TP -.BI noencrypt +.B noencrypt Disable encryption. .TP -.BI secmgr +.B secmgr Enable security manager (current kernel support is limited). .TP -.BI nosecmgr +.B nosecmgr Disable security manager. .TP -.BI piscan +.B piscan Enable page and inquiry scan. .TP -.BI noscan +.B noscan Disable page and inquiry scan. .TP -.BI iscan +.B iscan Enable inquiry scan, disable page scan. .TP -.BI pscan +.B pscan Enable page scan, disable inquiry scan. .TP -.BI ptype " [type]" +\fBptype\fP [\fItype\fP] With no -.I -type +.I type , displays the current packet types. Otherwise, all the packet types specified by -.I -type +.I type are set. -.I -type +.I type is a comma-separated list of packet types, where the possible packet types are .BR DM1 , .BR DM3 , @@ -117,8 +123,7 @@ With no .IR voice , prints voice setting. Otherwise, sets voice setting to .IR voice . -.I -voice +.I voice is a 16-bit hex number describing the voice setting. .TP .BI iac " [iac]" @@ -145,9 +150,9 @@ With no prints out the current inquiry scan type. Otherwise, sets inquiry scan type to .IR type . .TP -.BI inqparms " [win:int]" +\fBinqparams\fP [\fIwin\fP:\fIint\fP] With no -.IR win:int , +.IR win : int , prints inquiry scan window and interval. Otherwise, sets inquiry scan window to .I win @@ -155,23 +160,20 @@ slots and inquiry scan interval to .I int slots. .TP -.BI pageparms " [win:int]" +\fBpageparms\fP [\fIwin\fP:\fIint\fP] With no -.IR win:int , +.IR win : int , prints page scan window and interval. Otherwise, sets page scan window to -.I -win +.I win slots and page scan interval to -.I -int +.I int slots. .TP .BI pageto " [to]" With no .IR to , prints page timeout. Otherwise, sets page timeout -to -.I +to .I to slots. .TP @@ -181,19 +183,16 @@ With no prints out the current AFH mode. Otherwise, sets AFH mode to .IR mode . .TP -.BI aclmtu " " +\fBaclmtu\fP \fImtu\fP:\fIpkt\fP Sets ACL MTU to to -.I -mtu +.I mtu bytes and ACL buffer size to -.I -pkt +.I pkt packets. .TP -.BI scomtu " " +\fBscomtu\fP \fImtu\fP:\fIpkt\fP Sets SCO MTU to -to .I mtu bytes and SCO buffer size to .I pkt @@ -223,43 +222,34 @@ Display revision information. .TP .BI lm " [mode]" With no -.I -mode +.I mode , prints link mode. -.B -MASTER +.B MASTER or -.B -SLAVE +.B SLAVE mean, respectively, to ask to become master or to remain slave when a connection request comes in. The additional keyword -.B -ACCEPT +.B ACCEPT means that baseband connections will be accepted even if there are no listening .I AF_BLUETOOTH sockets. .I mode is -.B -NONE +.B NONE or a comma-separated list of keywords, where possible keywords are -.B -MASTER +.B MASTER and .B "ACCEPT" . -.B -NONE +.B NONE sets link policy to the default behaviour of remaining slave and not accepting baseband connections when there are no listening .I AF_BLUETOOTH sockets. If -.B -MASTER +.B MASTER is present, the device will ask to become master if a connection request comes in. If -.B -ACCEPT +.B ACCEPT is present, the device will accept baseband connections even when there are no listening .I AF_BLUETOOTH -- cgit From b96133c91a2abcc6b0a6de80176623f0ee6f600e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 4 Jun 2006 12:09:30 +0000 Subject: Build a generic helper library --- tools/Makefile.am | 6 +-- tools/oui.c | 109 ------------------------------------------------------ tools/oui.h | 25 ------------- 3 files changed, 3 insertions(+), 137 deletions(-) delete mode 100644 tools/oui.c delete mode 100644 tools/oui.h (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index d682448c..31626523 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -40,10 +40,10 @@ noinst_PROGRAMS = hcisecfilter ppporc hciattach_SOURCES = hciattach.c hciattach_st.c hciconfig_SOURCES = hciconfig.c csr.h csr.c -hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a +hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a -hcitool_SOURCES = hcitool.c oui.h oui.c -hcitool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a +hcitool_SOURCES = hcitool.c +hcitool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a l2ping_LDADD = @BLUEZ_LIBS@ diff --git a/tools/oui.c b/tools/oui.c deleted file mode 100644 index cc695a90..00000000 --- a/tools/oui.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2006 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "oui.h" - -/* http://standards.ieee.org/regauth/oui/oui.txt */ - -#define OUIFILE "/var/lib/misc/oui.txt" - -char *ouitocomp(const char *oui) -{ - struct stat st; - char *str, *map, *off, *end; - int fd; - - fd = open("oui.txt", O_RDONLY); - if (fd < 0) { - fd = open(OUIFILE, O_RDONLY); - if (fd < 0) { - fd = open("/usr/share/misc/oui.txt", O_RDONLY); - if (fd < 0) - return NULL; - } - } - - if (fstat(fd, &st) < 0) { - close(fd); - return NULL; - } - - str = malloc(128); - if (!str) { - close(fd); - return NULL; - } - - memset(str, 0, 128); - - map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (!map || map == MAP_FAILED) { - free(str); - close(fd); - return NULL; - } - - off = strstr(map, oui); - if (off) { - off += 18; - end = strpbrk(off, "\r\n"); - strncpy(str, off, end - off); - } else { - free(str); - str = NULL; - } - - munmap(map, st.st_size); - - close(fd); - - return str; -} - -int oui2comp(const char *oui, char *comp, size_t size) -{ - char *tmp; - - tmp = ouitocomp(oui); - if (!tmp) - return -1; - - snprintf(comp, size, "%s", tmp); - - free(tmp); - - return 0; -} diff --git a/tools/oui.h b/tools/oui.h deleted file mode 100644 index c166038f..00000000 --- a/tools/oui.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2006 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -char *ouitocomp(const char *oui); -int oui2comp(const char *oui, char *comp, size_t size); -- cgit From 3efb1bff5770e3609548b992d2e459968942b7de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 4 Jun 2006 13:05:36 +0000 Subject: Update more manual pages --- tools/l2ping.1 | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) (limited to 'tools') diff --git a/tools/l2ping.1 b/tools/l2ping.1 index bd07e198..8f56fb5e 100644 --- a/tools/l2ping.1 +++ b/tools/l2ping.1 @@ -3,56 +3,57 @@ l2ping \- Send L2CAP echo request and receive answer .SH SYNOPSIS .B l2ping -[ -.I -i -] [ -.I -s size -] [ -.I -c count -] [ -.I -t timeout -] [ -.I -f -] [ -.I -r -] < +.RB [\| \-i +.IR \|] +.RB [\| \-s +.IR size \|] +.RB [\| \-c +.IR count \|] +.RB [\| \-t +.IR timeout \|] +.RB [\| \-f \|] +.RB [\| \-r \|] .I bd_addr -> + +.SH DESCRIPTION +.LP +.I bd_addr + .SH DESCRIPTION .LP L2ping sends a L2CAP echo request to the Bluetooth MAC address -.B bd_addr +.I bd_addr given in dotted hex notation. .SH OPTIONS .TP -.I -i " " +.BI \-i " " The command is applied to device -.I +.BI hciX , which must be the name of an installed Bluetooth device (X = 0, 1, 2, ...) If not specified, the command will be sent to the first available Bluetooth device. .TP -.I -s size +.BI \-s " size" The -.B size +.I size of the data packets to be sent. .TP -.I -c count +.BI \-c " count" Send -.B count +.I count number of packets then exit. .TP -.I -t \fBtimeout\fP +.BI \-t " timeout" Wait -.B \fBtimeout\fP +.I timeout seconds for the response. .TP -.I -f +.B \-f Kind of flood ping. Use with care! It reduces the delay time between packets to 0. .TP -.I -r +.B \-r Reverse ping (gnip?). Send echo response instead of echo request. .TP .I bd_addr -- cgit From 99dd5f8c7549a7e7f4183bd8040c3e0e8884594f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 4 Jun 2006 15:27:17 +0000 Subject: Load firmware files from /lib/firmware --- tools/hciattach_st.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index 0279d398..46efbc2c 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -115,7 +115,7 @@ static int load_file(int dd, uint16_t version, const char *suffix) { DIR *dir; struct dirent *d; - char filename[NAME_MAX], prefix[20]; + char pathname[PATH_MAX], filename[NAME_MAX], prefix[20]; unsigned char cmd[256]; unsigned char buf[256]; uint8_t seqnum = 0; @@ -126,9 +126,14 @@ static int load_file(int dd, uint16_t version, const char *suffix) snprintf(prefix, sizeof(prefix), "STLC2500_R%d_%02d_", version >> 8, version & 0xff); - dir = opendir("."); - if (!dir) - return -errno; + strcpy(pathname, "/lib/firmware"); + dir = opendir(pathname); + if (!dir) { + strcpy(pathname, "."); + dir = opendir(pathname); + if (!dir) + return -errno; + } while (1) { d = readdir(dir); @@ -142,7 +147,8 @@ static int load_file(int dd, uint16_t version, const char *suffix) if (strncmp(d->d_name, prefix, strlen(prefix))) continue; - snprintf(filename, sizeof(filename), "%s", d->d_name); + snprintf(filename, sizeof(filename), "%s/%s", + pathname, d->d_name); } closedir(dir); -- cgit From cb778770890a9c3e69179488f5b21becc5973e59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Jun 2006 11:01:32 +0000 Subject: Adapt possible record range --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index d5ad511c..2b0a1df2 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -3637,7 +3637,7 @@ static char *records_help = static int cmd_records(int argc, char **argv) { struct search_context context; - uint32_t base[] = { 0x10000, 0x1002e, 0x110b }; + uint32_t base[] = { 0x10000, 0x1002e, 0x110b, 0x90000, 0x2008000, 0x4000000, 0x1000000 }; bdaddr_t bdaddr; int i, n, opt, err = 0, num = 32; -- cgit From 33b2522fb2f86590aaf40dc79a6156b94d5a6980 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 15 Jun 2006 05:44:22 +0000 Subject: Use uint16 for PSM in the HID keyboard record --- tools/sdptool.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 2b0a1df2..0cefafb0 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2073,7 +2073,7 @@ static int add_hid_keyb(sdp_session_t *session, svc_info_t *si) uuid_t root_uuid, hidkb_uuid, l2cap_uuid, hidp_uuid; sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[3]; - sdp_data_t *channel, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2; + sdp_data_t *psm, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2; int i; uint8_t dtd = SDP_UINT16; uint8_t dtd2 = SDP_UINT8; @@ -2085,8 +2085,8 @@ static int add_hid_keyb(sdp_session_t *session, svc_info_t *si) int leng[2]; uint8_t hid_spec_type = 0x22; uint16_t hid_attr_lang[] = { 0x409, 0x100 }; - static const uint8_t ctrl = 0x11; - static const uint8_t intr = 0x13; + static const uint16_t ctrl = 0x11; + static const uint16_t intr = 0x13; static const uint16_t hid_attr[] = { 0x100, 0x111, 0x40, 0x0d, 0x01, 0x01 }; static const uint16_t hid_attr2[] = { 0x0, 0x01, 0x100, 0x1f40, 0x01, 0x01 }; const uint8_t hid_spec[] = { @@ -2163,8 +2163,8 @@ static int add_hid_keyb(sdp_session_t *session, svc_info_t *si) /* protocols */ sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); proto[1] = sdp_list_append(0, &l2cap_uuid); - channel = sdp_data_alloc(SDP_UINT8, &ctrl); - proto[1] = sdp_list_append(proto[1], channel); + psm = sdp_data_alloc(SDP_UINT16, &ctrl); + proto[1] = sdp_list_append(proto[1], psm); apseq = sdp_list_append(0, proto[1]); sdp_uuid16_create(&hidp_uuid, HIDP_UUID); @@ -2176,8 +2176,8 @@ static int add_hid_keyb(sdp_session_t *session, svc_info_t *si) /* additional protocols */ proto[1] = sdp_list_append(0, &l2cap_uuid); - channel = sdp_data_alloc(SDP_UINT8, &intr); - proto[1] = sdp_list_append(proto[1], channel); + psm = sdp_data_alloc(SDP_UINT16, &intr); + proto[1] = sdp_list_append(proto[1], psm); apseq = sdp_list_append(0, proto[1]); sdp_uuid16_create(&hidp_uuid, HIDP_UUID); -- cgit From 29a6d660b09d5f277d354b3fbd4f168cd325bf74 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 Jun 2006 09:08:13 +0000 Subject: Add another build id for the "marcel" specific firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index fea0c7c3..5430ecec 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -331,6 +331,7 @@ static struct { { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, + { 3326, "Marcel 4 (2006-06-16)" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 9fab0f8bb8c38b57d9a3bfe6abb2d93134326462 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 17 Jun 2006 10:35:00 +0000 Subject: Only read remote extended features if local adapter supports it --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 594c2601..f38fd1d0 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -833,7 +833,7 @@ static void cmd_info(int dev_id, int argc, char **argv) bt_free(tmp); } - if (features[7] & LMP_EXT_FEAT) { + if ((di.features[7] & LMP_EXT_FEAT) && (features[7] & LMP_EXT_FEAT)) { if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) if (max_page > 0) printf("\tExtended features: %d pages\n", max_page); -- cgit From b296f5081912b00dd837109c44625e26734fbf3a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 17 Jun 2006 11:12:55 +0000 Subject: Add build ids for new sniffer firmwares --- tools/csr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 5430ecec..531bced6 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -396,6 +396,12 @@ static struct { { 2388, "Sniff 46 (2005-08-17)" }, { 2389, "Sniff 46 (2005-08-17)" }, { 2390, "Sniff 46 (2005-08-17)" }, + { 2869, "Sniff 47 (2006-02-15)" }, + { 2870, "Sniff 47 (2006-02-15)" }, + { 2871, "Sniff 47 (2006-02-15)" }, + { 3214, "Sniff 48 (2006-05-16)" }, + { 3215, "Sniff 48 (2006-05-16)" }, + { 3216, "Sniff 48 (2006-05-16)" }, { 0, } }; -- cgit From 8f1b0911978d19b9e20f152db3fc427fc3b4ee07 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Jun 2006 09:45:55 +0000 Subject: Accept list of bytes as input for key values --- tools/bccmd.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.c b/tools/bccmd.c index f86b93ea..2e426e79 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -199,9 +199,9 @@ static char *memorytostr(uint16_t type) } } -#define OPT_RANGE(range) \ - if (argc < (range)) { errno = EINVAL; return -1; } \ - if (argc > (range)) { errno = E2BIG; return -1; } +#define OPT_RANGE(min, max) \ + if (argc < (min)) { errno = EINVAL; return -1; } \ + if (argc > (max)) { errno = E2BIG; return -1; } static struct option help_options[] = { { "help", 0, 0, 'h' }, @@ -227,7 +227,7 @@ static int opt_help(int argc, char *argv[], int *help) #define OPT_HELP(range, help) \ opt_help(argc, argv, (help)); \ argc -= optind; argv += optind; optind = 0; \ - OPT_RANGE((range)) + OPT_RANGE((range), (range)) static int cmd_builddef(int transport, int argc, char *argv[]) { @@ -564,10 +564,10 @@ static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int * return optind; } -#define OPT_PSKEY(range, stores, reset, help) \ +#define OPT_PSKEY(min, max, stores, reset, help) \ opt_pskey(argc, argv, (stores), (reset), (help)); \ argc -= optind; argv += optind; optind = 0; \ - OPT_RANGE((range)) + OPT_RANGE((min), (max)) static int cmd_psget(int transport, int argc, char *argv[]) { @@ -578,7 +578,7 @@ static int cmd_psget(int transport, int argc, char *argv[]) memset(array, 0, sizeof(array)); - OPT_PSKEY(1, &stores, &reset, NULL); + OPT_PSKEY(1, 1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); @@ -653,7 +653,7 @@ static int cmd_psset(int transport, int argc, char *argv[]) memset(array, 0, sizeof(array)); - OPT_PSKEY(2, &stores, &reset, NULL); + OPT_PSKEY(2, 81, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); @@ -756,7 +756,7 @@ static int cmd_psclr(int transport, int argc, char *argv[]) uint16_t pskey, stores = CSR_STORES_PSRAM; int i, err, reset = 0; - OPT_PSKEY(1, &stores, &reset, NULL); + OPT_PSKEY(1, 1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); @@ -793,7 +793,7 @@ static int cmd_pslist(int transport, int argc, char *argv[]) uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; int err, reset = 0; - OPT_PSKEY(0, &stores, &reset, NULL); + OPT_PSKEY(0, 0, &stores, &reset, NULL); while (1) { memset(array, 0, sizeof(array)); @@ -839,7 +839,7 @@ static int cmd_psread(int transport, int argc, char *argv[]) char *str, val[7]; int i, err, reset = 0; - OPT_PSKEY(0, &stores, &reset, NULL); + OPT_PSKEY(0, 0, &stores, &reset, NULL); while (1) { memset(array, 0, sizeof(array)); @@ -908,7 +908,7 @@ static int cmd_psload(int transport, int argc, char *argv[]) char *str, val[7]; int err, reset = 0; - OPT_PSKEY(1, &stores, &reset, NULL); + OPT_PSKEY(1, 1, &stores, &reset, NULL); psr_read(argv[0]); -- cgit From 36e5deeafe85d7d4be7db89083870ed073c25653 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 Jun 2006 12:20:54 +0000 Subject: Add additional PS related options --- tools/bccmd.8 | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.8 b/tools/bccmd.8 index e4642fec..95d67461 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -1,4 +1,4 @@ -.TH BCCMD 8 "Dec 6 2005" BlueZ "Linux System Administration" +.TH BCCMD 8 "Jun 20 2006" BlueZ "Linux System Administration" .SH NAME bccmd \- Utility for the CSR BCCMD interface .SH SYNOPSIS @@ -87,26 +87,33 @@ TXData1 radio test .BI memtypes Get memory types .TP -.BI psget\ -Get value for PS key +.BI psget\ [-r]\ [-s\ ]\ +Get value for PS key. +-r sends a warm reset afterwards .TP -.BI psset\ \ -Set value for PS key +.BI psset\ [-r]\ [-s\ ]\ \ +Set value for PS key. +-r sends a warm reset afterwards .TP -.BI psclr\ -Clear value for PS key +.BI psclr\ [-r]\ [-s\ ]\ +Clear value for PS key. +-r sends a warm reset afterwards .TP -.BI pslist -List all PS keys +.BI pslist\ [-r]\ [-s\ ] +List all PS keys. +-r sends a warm reset afterwards .TP -.BI psread -Read all PS keys +.BI psread\ [-r]\ [-s\ ] +Read all PS keys. +-r sends a warm reset afterwards .TP -.BI psload\ -Load all PS keys from PSR file +.BI psload\ [-r]\ [-s\ ]\ +Load all PS keys from PSR file. +-r sends a warm reset afterwards .TP -.BI pscheck\ -Check syntax of PSR file +.BI pscheck\ [-r]\ [-s\ ]\ +Check syntax of PSR file. +-r sends a warm reset afterwards .SH KEYS bdaddr country devclass keymin keymax features commands version remver hciextn mapsco baudrate hostintf anafreq anaftrim usbvid -- cgit From 943b02e163e169795a010c36a3b3343cc5092a96 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jun 2006 07:33:36 +0000 Subject: Include sys/param.h for PATH_MAX when cross-compiling --- tools/hciattach.c | 1 + tools/hciattach_st.c | 1 + tools/hciconfig.c | 1 + 3 files changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 08b28f45..909a6465 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index 46efbc2c..014ddb2d 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -33,6 +33,7 @@ #include #include #include +#include static int debug = 0; diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3ebfc1c8..04f9a8be 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include -- cgit From ff9745b2228bfb780f5d5d553a8de61a7271062d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Jul 2006 13:03:54 +0000 Subject: Make use of create_name() --- tools/hciconfig.c | 2 +- tools/hcitool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 04f9a8be..53ffec89 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -734,7 +734,7 @@ static int get_link_key(const bdaddr_t *local, const bdaddr_t *peer, uint8_t *ke int i; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "linkkeys"); ba2str(peer, addr); str = textfile_get(filename, addr); diff --git a/tools/hcitool.c b/tools/hcitool.c index f38fd1d0..ef33440f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -281,7 +281,7 @@ static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer) char filename[PATH_MAX + 1], addr[18]; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "names"); ba2str(peer, addr); return textfile_get(filename, addr); -- cgit From b102348e988e4abc5d579ce13c067ce2c885aaf7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Jul 2006 13:32:44 +0000 Subject: Fix declared with attribute warn_unused_result errors --- tools/csr_bcsp.c | 3 ++- tools/dfutool.c | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 77766114..29a60bf9 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -136,7 +136,8 @@ int csr_open_bcsp(char *device) void put_uart(uint8_t ch) { - write(fd, &ch, 1); + if (write(fd, &ch, 1) < 0) + fprintf(stderr, "UART write error\n"); } uint8_t get_uart(uint8_t *ch) diff --git a/tools/dfutool.c b/tools/dfutool.c index 8d5e9194..6bf65639 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -166,7 +166,8 @@ static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffi printf("\rSelect device (abort with 0): "); fflush(stdout); memset(str, 0, sizeof(str)); - fgets(str, sizeof(str) - 1, stdin); + if (!fgets(str, sizeof(str) - 1, stdin)) + continue; sel = atoi(str); } while (!isdigit(str[0]) || sel < 0 || sel > num ); @@ -666,8 +667,12 @@ static void cmd_archive(char *device, int argc, char **argv) for (i = 0; i < len; i++) crc = crc32_byte(crc, buf[i]); - if (len > 0) - write(fd, buf, len); + if (len > 0) { + if (write(fd, buf, len) < 0) { + printf("\rCan't write next block: %s (%d)\n", strerror(errno), errno); + goto done; + } + } n++; if (len != 1023) @@ -687,7 +692,8 @@ static void cmd_archive(char *device, int argc, char **argv) suffix.dwCRC = cpu_to_le32(crc); - write(fd, &suffix, DFU_SUFFIX_SIZE); + if (write(fd, &suffix, DFU_SUFFIX_SIZE) < 0) + printf("Can't write suffix block: %s (%d)\n", strerror(errno), errno); done: close(fd); -- cgit From 7449f2395ee3df35bb76c04ab211042e05af1c89 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jul 2006 02:08:02 +0000 Subject: Don't ignore return value of write() --- tools/hciattach.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 909a6465..ca7f91c7 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -337,10 +337,11 @@ static void bcsp_tshy_sig_alarm(int sig) { static int retries=0; unsigned char bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}; + int len; if (retries < 10) { retries++; - write(serial_fd, &bcsp_sync_pkt, 10); + len = write(serial_fd, &bcsp_sync_pkt, 10); alarm(1); return; } @@ -354,10 +355,11 @@ static void bcsp_tconf_sig_alarm(int sig) { static int retries=0; unsigned char bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}; + int len; if (retries < 10){ retries++; - write(serial_fd, &bcsp_conf_pkt, 10); + len = write(serial_fd, &bcsp_conf_pkt, 10); alarm(1); return; } @@ -377,6 +379,7 @@ static int bcsp(int fd, struct uart_t *u, struct termios *ti) bcspconf[4] = {0xad,0xef,0xac,0xed}, bcspconfresp[4] = {0xde,0xad,0xd0,0xd0}; struct sigaction sa; + int len; if (set_speed(fd, ti, u->speed) < 0) { perror("Can't set default baud rate"); @@ -433,7 +436,7 @@ static int bcsp(int fd, struct uart_t *u, struct termios *ti) } if (!memcmp(bcspp, bcspsync, 4)) { - write(fd, &bcsp_sync_resp_pkt,10); + len = write(fd, &bcsp_sync_resp_pkt,10); } else if (!memcmp(bcspp, bcspsyncresp, 4)) break; } @@ -477,9 +480,9 @@ static int bcsp(int fd, struct uart_t *u, struct termios *ti) } if (!memcmp(bcspp, bcspsync, 4)) - write(fd, &bcsp_sync_resp_pkt, 10); + len = write(fd, &bcsp_sync_resp_pkt, 10); else if (!memcmp(bcspp, bcspconf, 4)) - write(fd, &bcsp_conf_resp_pkt, 10); + len = write(fd, &bcsp_conf_resp_pkt, 10); else if (!memcmp(bcspp, bcspconfresp, 4)) break; } -- cgit From 47e47d4cfe1ef4f2f5faef19c11618d929cd3f9a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Aug 2006 14:27:30 +0000 Subject: Add another Apple product id --- tools/hid2hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index ef227a35..c35195b4 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -219,6 +219,7 @@ static struct device_id device_list[] = { { HCI, 0x05ac, 0x1000, switch_hidproxy }, { HID, 0x05ac, 0x8203, switch_hidproxy }, { HID, 0x05ac, 0x8204, switch_hidproxy }, /* Apple Mac mini */ + { HID, 0x05ac, 0x8207, switch_hidproxy }, /* Apple Power Mac G5 */ { HCI, 0x046d, 0xc703, switch_logitech }, { HCI, 0x046d, 0xc704, switch_logitech }, { HCI, 0x046d, 0xc705, switch_logitech }, -- cgit From 854c86afe6c6fd19245e2bdda0e8c671c45ce00c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Aug 2006 20:51:28 +0000 Subject: Update HCI switching for Logitech MX 5000 --- tools/hid2hci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index c35195b4..594ea044 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -223,7 +223,8 @@ static struct device_id device_list[] = { { HCI, 0x046d, 0xc703, switch_logitech }, { HCI, 0x046d, 0xc704, switch_logitech }, { HCI, 0x046d, 0xc705, switch_logitech }, - { HCI, 0x046d, 0x0b02, switch_logitech }, /* Logitech diNovo Media Desktop Laser */ + { HCI, 0x046d, 0xc70a, switch_logitech }, /* Logitech diNovo mouse */ + { HCI, 0x046d, 0xc70e, switch_logitech }, /* logitech diNovo keyboard */ { -1 } }; -- cgit From 35e9349ffc53950c4b78fba9537a50cdb6e5fd7a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Aug 2006 10:20:59 +0000 Subject: Change default poll() timeout --- tools/ciptool.c | 2 +- tools/hciattach.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index 8f967858..97dcb62d 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -380,7 +380,7 @@ static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) while (!__io_canceled) { p.revents = 0; - if (poll(&p, 1, 100)) + if (poll(&p, 1, 500)) break; } diff --git a/tools/hciattach.c b/tools/hciattach.c index ca7f91c7..a38d2481 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -1265,7 +1265,7 @@ int main(int argc, char *argv[]) while (!__io_canceled) { p.revents = 0; - if (poll(&p, 1, 100)) + if (poll(&p, 1, 500)) break; } -- cgit From a1bc48d15a5d6e78efe744eb7b27b6421cb7222f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 16 Aug 2006 10:54:06 +0000 Subject: Convert to using ppoll() and pselect() --- tools/ciptool.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index 97dcb62d..3f4b113f 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -25,6 +25,7 @@ #include #endif +#define _GNU_SOURCE #include #include #include @@ -44,6 +45,10 @@ #include #include +#ifdef NEED_PPOLL +#include "ppoll.h" +#endif + static volatile sig_atomic_t __io_canceled = 0; static void sig_hup(int sig) @@ -331,6 +336,7 @@ static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) struct cmtp_conndel_req req; struct sigaction sa; struct pollfd p; + sigset_t sigs; bdaddr_t src, dst; unsigned short psm; int dev_id, sk; @@ -375,12 +381,14 @@ static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); + sigfillset(&sigs); + p.fd = sk; p.events = POLLERR | POLLHUP; while (!__io_canceled) { p.revents = 0; - if (poll(&p, 1, 500)) + if (ppoll(&p, 1, NULL, &sigs) > 0) break; } -- cgit From 73b9315e56f5f635eaf82a08271e8f462b731972 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 16 Aug 2006 11:44:52 +0000 Subject: Don't forget to unblock signals for ppoll() --- tools/ciptool.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index 3f4b113f..99add635 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -382,6 +382,11 @@ static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) sigaction(SIGHUP, &sa, NULL); sigfillset(&sigs); + sigdelset(&sigs, SIGCHLD); + sigdelset(&sigs, SIGPIPE); + sigdelset(&sigs, SIGTERM); + sigdelset(&sigs, SIGINT); + sigdelset(&sigs, SIGHUP); p.fd = sk; p.events = POLLERR | POLLHUP; -- cgit From a229e05f0a28860e766034f04ca5086f0e355045 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Sep 2006 10:53:18 +0000 Subject: Add support for periodic inquiry mode --- tools/hcitool.1 | 10 +++- tools/hcitool.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 140 insertions(+), 18 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index 01ef03a8..dd32ba21 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -42,7 +42,7 @@ Inquire remote devices. For each discovered device, Bluetooth device address, clock offset and class are printed. .TP .BI scan -Inquire remote devices. For each discovered device, device name is printed. +Inquire remote devices. For each discovered device, device name are printed. .TP .BI name " " Print device name of remote device with Bluetooth address @@ -53,13 +53,19 @@ Print device name, version and supported features of remote device with Bluetooth address .IR bdaddr . .TP +.BI spinq +Start periodic inquiry process. No inquiry results are printed. +.TP +.BI epinq +Exit periodic inquiry process. +.TP .BI cmd " [parameters]" Submit an arbitrary HCI command to local device. .IR ogf , .IR ocf and .IR parameters -are hexadecimal bytes +are hexadecimal bytes. .TP .BI con Display active baseband connections diff --git a/tools/hcitool.c b/tools/hcitool.c index ef33440f..4ae4226d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -301,6 +301,7 @@ static char *dev_help = static void cmd_dev(int dev_id, int argc, char **argv) { int opt; + for_each_opt(opt, dev_options, NULL) { switch (opt) { default: @@ -310,6 +311,7 @@ static void cmd_dev(int dev_id, int argc, char **argv) } printf("Devices:\n"); + hci_for_each_dev(HCI_UP, dev_info, 0); } @@ -379,6 +381,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) } printf("Inquiring ...\n"); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); if (num_rsp < 0) { perror("Inquiry failed."); @@ -658,8 +661,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("\n"); } - close(dd); bt_free(info); + + hci_close_dev(dd); } /* Remote name */ @@ -713,7 +717,7 @@ static void cmd_name(int dev_id, int argc, char **argv) if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("%s\n", name); - close(dd); + hci_close_dev(dd); } /* Info about remote device */ @@ -844,7 +848,104 @@ static void cmd_info(int dev_id, int argc, char **argv) hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); } - close(dd); + hci_close_dev(dd); +} + +/* Start periodic inquiry */ + +static struct option spinq_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *spinq_help = + "Usage:\n" + "\tspinq\n"; + +static void cmd_spinq(int dev_id, int argc, char **argv) +{ + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + struct hci_request rq; + periodic_inquiry_cp cp; + int opt, dd; + + for_each_opt(opt, spinq_options, NULL) { + switch (opt) { + default: + printf(spinq_help); + return; + } + } + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + memset(&cp, 0, sizeof(cp)); + memcpy(cp.lap, lap, 3); + cp.max_period = 16; + cp.min_period = 10; + cp.length = 8; + cp.num_rsp = 0; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_PERIODIC_INQUIRY; + rq.cparam = &cp; + rq.clen = PERIODIC_INQUIRY_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("Periodic inquiry failed"); + exit(EXIT_FAILURE); + } + + hci_close_dev(dd); +} + +/* Exit periodic inquiry */ + +static struct option epinq_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *epinq_help = + "Usage:\n" + "\tspinq\n"; + +static void cmd_epinq(int dev_id, int argc, char **argv) +{ + int opt, dd; + + for_each_opt(opt, epinq_options, NULL) { + switch (opt) { + default: + printf(epinq_help); + return; + } + } + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + if (hci_send_cmd(dd, OGF_LINK_CTL, + OCF_EXIT_PERIODIC_INQUIRY, 0, NULL) < 0) { + perror("Exit periodic inquiry failed"); + exit(EXIT_FAILURE); + } + + hci_close_dev(dd); } /* Send arbitrary HCI commands */ @@ -961,6 +1062,7 @@ static void cmd_con(int dev_id, int argc, char **argv) } printf("Connections:\n"); + hci_for_each_dev(HCI_UP, conn_list, dev_id); } @@ -1033,6 +1135,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) if (hci_create_connection(dd, &bdaddr, htobs(ptype), htobs(0x0000), role, &handle, 25000) < 0) perror("Can't create connection"); + hci_close_dev(dd); } @@ -1101,8 +1204,9 @@ static void cmd_dc(int dev_id, int argc, char **argv) HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) perror("Disconnect failed"); - close(dd); free(cr); + + hci_close_dev(dd); } /* Role switch */ @@ -1169,7 +1273,7 @@ static void cmd_sr(int dev_id, int argc, char **argv) exit(1); } - close(dd); + hci_close_dev(dd); } /* Read RSSI */ @@ -1241,8 +1345,9 @@ static void cmd_rssi(int dev_id, int argc, char **argv) printf("RSSI return value: %d\n", rssi); - close(dd); free(cr); + + hci_close_dev(dd); } /* Get link quality */ @@ -1314,8 +1419,9 @@ static void cmd_lq(int dev_id, int argc, char **argv) printf("Link quality: %d\n", lq); - close(dd); free(cr); + + hci_close_dev(dd); } /* Get transmit power level */ @@ -1390,8 +1496,9 @@ static void cmd_tpl(int dev_id, int argc, char **argv) printf("%s transmit power level: %d\n", (type == 0) ? "Current" : "Maximum", level); - close(dd); free(cr); + + hci_close_dev(dd); } /* Get AFH channel map */ @@ -1473,8 +1580,9 @@ static void cmd_afh(int dev_id, int argc, char **argv) } else printf("AFH disabled\n"); - close(dd); free(cr); + + hci_close_dev(dd); } /* Set connection packet type */ @@ -1560,8 +1668,9 @@ static void cmd_cpt(int dev_id, int argc, char **argv) exit(1); } - close(dd); free(cr); + + hci_close_dev(dd); } /* Get/Set link supervision timeout */ @@ -1648,8 +1757,9 @@ static void cmd_lst(int dev_id, int argc, char **argv) } } - close(dd); free(cr); + + hci_close_dev(dd); } /* Request authentication */ @@ -1718,8 +1828,9 @@ static void cmd_auth(int dev_id, int argc, char **argv) exit(1); } - close(dd); free(cr); + + hci_close_dev(dd); } /* Activate encryption */ @@ -1791,8 +1902,9 @@ static void cmd_enc(int dev_id, int argc, char **argv) exit(1); } - close(dd); free(cr); + + hci_close_dev(dd); } /* Change connection link key */ @@ -1861,8 +1973,9 @@ static void cmd_key(int dev_id, int argc, char **argv) exit(1); } - close(dd); free(cr); + + hci_close_dev(dd); } /* Read clock offset */ @@ -1934,8 +2047,9 @@ static void cmd_clkoff(int dev_id, int argc, char **argv) printf("Clock offset: 0x%4.4x\n", btohs(offset)); - close(dd); free(cr); + + hci_close_dev(dd); } /* Read clock */ @@ -2024,7 +2138,7 @@ static void cmd_clock(int dev_id, int argc, char **argv) printf("Clock: 0x%4.4x\n", btohl(clock)); printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); - close(dd); + hci_close_dev(dd); } static struct { @@ -2037,6 +2151,8 @@ static struct { { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, + { "spinq", cmd_spinq, "Start periodic inquiry" }, + { "epinq", cmd_epinq, "Exit periodic inquiry" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, -- cgit From 8ee8041f8ad6aeb75ff9d9dba3d27d6663da247a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Sep 2006 08:47:57 +0000 Subject: Fix endian issue with periodic inquiry --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 4ae4226d..88c320b6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -888,8 +888,8 @@ static void cmd_spinq(int dev_id, int argc, char **argv) memset(&cp, 0, sizeof(cp)); memcpy(cp.lap, lap, 3); - cp.max_period = 16; - cp.min_period = 10; + cp.max_period = htobs(16); + cp.min_period = htobs(10); cp.length = 8; cp.num_rsp = 0; -- cgit From b08d30eb4d07eec80cd7f852a6037864219313d0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Sep 2006 11:42:14 +0000 Subject: Fix major class count calculation error --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 88c320b6..dfa3e48e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -619,7 +619,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (extcls) { memcpy(cls, (info+i)->dev_class, 3); printf("Device class:\t"); - if ((cls[1] & 0x1f) > sizeof(*major_classes)) + if ((cls[1] & 0x1f) > sizeof(major_classes) / sizeof(char *)) printf("Invalid"); else printf("%s, %s", major_classes[cls[1] & 0x1f], -- cgit From cf1c6fe16bd66651951724a7ee6ba7c80b83717a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Sep 2006 17:50:36 +0000 Subject: Add build ids for Unified 21f firmwares --- tools/csr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 531bced6..072f5fca 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -328,6 +328,11 @@ static struct { { 3063, "Unified 21d" }, { 3064, "Unified 21d" }, { 3164, "Unified 21e" }, + { 3413, "Unified 21f" }, + { 3414, "Unified 21f" }, + { 3415, "Unified 21f" }, + { 3424, "Unified 21f" }, + { 3454, "Unified 21f" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, -- cgit From d544342b190eabf0703218169c1248f3905b09b1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Oct 2006 13:07:47 +0000 Subject: Add another Ricoh specific range --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 0cefafb0..477f05a1 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -3637,7 +3637,7 @@ static char *records_help = static int cmd_records(int argc, char **argv) { struct search_context context; - uint32_t base[] = { 0x10000, 0x1002e, 0x110b, 0x90000, 0x2008000, 0x4000000, 0x1000000 }; + uint32_t base[] = { 0x10000, 0x1002e, 0x110b, 0x90000, 0x2008000, 0x4000000, 0x100000, 0x1000000 }; bdaddr_t bdaddr; int i, n, opt, err = 0, num = 32; -- cgit From 704e6982209342a90051aeb9e280cf887e2f5f77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 24 Oct 2006 16:24:13 +0000 Subject: Add another build id for the "marcel" specific firmware --- tools/csr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 072f5fca..4d64fde7 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -335,8 +335,9 @@ static struct { { 3454, "Unified 21f" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, - { 2622, "Marcel 3 (2005-10-27)" }, - { 3326, "Marcel 4 (2006-06-16)" }, + { 2622, "Marcel 3 (2005-10-27)" }, + { 3326, "Marcel 4 (2006-06-16)" }, + { 3612, "Marcel 5 (2006-10-24)" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From f16a4ebd9b71a929aef6cea1052941702ff39c36 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Nov 2006 18:46:56 +0000 Subject: Add build ids for new sniffer firmwares --- tools/csr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 4d64fde7..46d3ae10 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -408,6 +408,9 @@ static struct { { 3214, "Sniff 48 (2006-05-16)" }, { 3215, "Sniff 48 (2006-05-16)" }, { 3216, "Sniff 48 (2006-05-16)" }, + { 3356, "Sniff 49 (2006-07-17)" }, + { 3529, "Sniff 50 (2006-09-21)" }, + { 3546, "Sniff 51 (2006-09-29)" }, { 0, } }; -- cgit From 32327680a5df58a4ba7fcfa9edc31e6f3e1e33a5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 21 Nov 2006 15:44:56 +0000 Subject: Don't change scan enable on devup --- tools/hciconfig.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 53ffec89..3e7a5fbc 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -253,11 +253,6 @@ static void cmd_up(int ctl, int hdev, char *opt) hdev, strerror(errno), errno); exit(1); } - if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) - return; - if (hci_test_bit(HCI_RAW, &di.flags)) - return; - cmd_scan(ctl, hdev, "piscan"); } static void cmd_down(int ctl, int hdev, char *opt) -- cgit From 77d92a75f16e380ed204fb2e42eb292a16355ec9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Nov 2006 04:59:17 +0000 Subject: Add support for XML view of service records --- tools/Makefile.am | 2 +- tools/sdptool.c | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 31626523..3b21f72b 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -47,7 +47,7 @@ hcitool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a l2ping_LDADD = @BLUEZ_LIBS@ -sdptool_LDADD = @BLUEZ_LIBS@ +sdptool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a ciptool_LDADD = @BLUEZ_LIBS@ diff --git a/tools/sdptool.c b/tools/sdptool.c index 477f05a1..4c3bf5cc 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -45,6 +45,8 @@ #include +#include "sdp-xml.h" + #ifndef APPLE_AGENT_SVCLASS_ID #define APPLE_AGENT_SVCLASS_ID 0x2112 #endif @@ -67,6 +69,7 @@ static int estr2ba(char *str, bdaddr_t *ba) #define DEFAULT_VIEW 0 /* Display only known attribute */ #define TREE_VIEW 1 /* Display full attribute tree */ #define RAW_VIEW 2 /* Display raw tree */ +#define XML_VIEW 3 /* Display xml tree */ /* Pass args to the inquiry/search handler */ struct search_context { @@ -3329,6 +3332,11 @@ static void inquiry(handler_t handler, void *arg) handler(&ii[i].bdaddr, arg); } +static void doprintf(void *data, const char *str) +{ + printf(str); +} + /* * Search for a specific SDP service */ @@ -3383,6 +3391,10 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) print_tree_attr(rec); printf("\n"); break; + case XML_VIEW: + /* Display raw XML tree */ + convert_sdp_record_to_xml(rec, 0, doprintf); + break; default: /* Display raw tree */ print_raw_attr(rec); @@ -3409,6 +3421,7 @@ static struct option browse_options[] = { { "help", 0, 0, 'h' }, { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, + { "xml", 0, 0, 'x' }, { "uuid", 1, 0, 'u' }, { "l2cap", 0, 0, 'l' }, { 0, 0, 0, 0 } @@ -3416,7 +3429,7 @@ static struct option browse_options[] = { static char *browse_help = "Usage:\n" - "\tbrowse [--tree] [--raw] [--uuid uuid] [--l2cap] [bdaddr]\n"; + "\tbrowse [--tree] [--raw] [--xml] [--uuid uuid] [--l2cap] [bdaddr]\n"; /* * Browse the full SDP database (i.e. list all services starting from the @@ -3440,6 +3453,9 @@ static int cmd_browse(int argc, char **argv) case 'r': context.view = RAW_VIEW; break; + case 'x': + context.view = XML_VIEW; + break; case 'u': if (sscanf(optarg, "%i", &num) != 1 || num < 0 || num > 0xffff) { printf("Invalid uuid %s\n", optarg); @@ -3473,12 +3489,13 @@ static struct option search_options[] = { { "bdaddr", 1, 0, 'b' }, { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, + { "xml", 0, 0, 'x' }, { 0, 0, 0, 0} }; static char *search_help = "Usage:\n" - "\tsearch [--bdaddr bdaddr] [--tree] [--raw] SERVICE\n" + "\tsearch [--bdaddr bdaddr] [--tree] [--raw] [--xml] SERVICE\n" "SERVICE is a name (string) or UUID (0x1002)\n"; /* @@ -3514,6 +3531,9 @@ static int cmd_search(int argc, char **argv) case 'r': context.view = RAW_VIEW; break; + case 'x': + context.view = XML_VIEW; + break; default: printf(search_help); return -1; @@ -3610,6 +3630,10 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int qui print_tree_attr(rec); printf("\n"); break; + case XML_VIEW: + /* Display raw XML tree */ + convert_sdp_record_to_xml(rec, 0, doprintf); + break; default: /* Display raw tree */ print_raw_attr(rec); @@ -3624,12 +3648,13 @@ static struct option records_options[] = { { "help", 0, 0, 'h' }, { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, + { "xml", 0, 0, 'x' }, { 0, 0, 0, 0 } }; static char *records_help = "Usage:\n" - "\trecords [--tree] [--raw] bdaddr\n"; + "\trecords [--tree] [--raw] [--xml] bdaddr\n"; /* * Request possible SDP service records @@ -3652,6 +3677,9 @@ static int cmd_records(int argc, char **argv) case 'r': context.view = RAW_VIEW; break; + case 'x': + context.view = XML_VIEW; + break; default: printf(records_help); return -1; @@ -3686,12 +3714,13 @@ static struct option get_options[] = { { "bdaddr", 1, 0, 'b' }, { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, + { "xml", 0, 0, 'x' }, { 0, 0, 0, 0 } }; static char *get_help = "Usage:\n" - "\tget [--tree] [--raw] [--bdaddr bdaddr] record_handle\n"; + "\tget [--tree] [--raw] [--xml] [--bdaddr bdaddr] record_handle\n"; /* * Get a specific SDP record on the local SDP server @@ -3718,6 +3747,9 @@ static int cmd_get(int argc, char **argv) case 'r': context.view = RAW_VIEW; break; + case 'x': + context.view = XML_VIEW; + break; default: printf(get_help); return -1; -- cgit From 07ad6734b5859f00f4cb4fbb0bda806953339a69 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Nov 2006 05:01:13 +0000 Subject: Don't forget to mention the --xml option in the manual page --- tools/sdptool.1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 5392a97c..686ec95a 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -71,16 +71,16 @@ for \fBbdaddr\fP, then the local \fBsdpd\fR is searched. Services are identified and manipulated with a 4-byte \fBrecord_handle\fP (NOT the service name). To find a service's \fBrecord_handle\fP, look for the "Service RecHandle" line in the \fBsearch\fP or \fBbrowse\fP results -.IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] service_name\fP" 10 +.IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] [--xml] service_name\fP" 10 Search for services.. .IP "" 10 Known service names are DID, SP, DUN, LAN, FAX, OPUSH, FTP, HS, HF, HFAG, SAP, NAP, GN, PANU, HCRP, HID, CIP, A2SRC, A2SNK, AVRCT, AVRTG, UDIUE, UDITE and SYNCML. -.IP "\fBbrowse [--tree] [--raw] [bdaddr]\fP" 10 +.IP "\fBbrowse [--tree] [--raw] [--xml] [bdaddr]\fP" 10 Browse all available services on the device specified by a Bluetooth address as a parameter. -.IP "\fBrecords [--tree] [--raw] bdaddr\fP" 10 +.IP "\fBrecords [--tree] [--raw] [--xml] bdaddr\fP" 10 Retrieve all possible service records. .IP "\fBadd [ --handle=N --channel=N ]\fP" 10 Add a service to the local @@ -94,7 +94,7 @@ using the \fB--channel\fP option. .IP "\fBdel record_handle\fP" 10 Remove a service from the local \fBsdpd\fR. -.IP "\fBget [--tree] [--raw] [--bdaddr bdaddr] record_handle\fP" 10 +.IP "\fBget [--tree] [--raw] [--xml] [--bdaddr bdaddr] record_handle\fP" 10 Retrieve a service from the local \fBsdpd\fR. .IP "\fBsetattr record_handle attrib_id attrib_value\fP" 10 -- cgit From 59a4bc3afb004d7aeef69461987307738a9fe4af Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 26 Nov 2006 09:17:15 +0000 Subject: Use multibyte friendly checks instead of isprint() --- tools/hciconfig.c | 12 ++++++++---- tools/hcitool.c | 16 ++++++++++------ 2 files changed, 18 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3e7a5fbc..18601d77 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -473,9 +473,11 @@ static void cmd_name(int ctl, int hdev, char *opt) exit(1); } - for (i = 0; i < 248 && name[i]; i++) - if (!isprint(name[i])) + for (i = 0; i < 248 && name[i]; i++) { + if ((unsigned char) name[i] < 32 || name[i] == 127) name[i] = '.'; + } + name[248] = '\0'; print_dev_hdr(&di); @@ -1002,9 +1004,11 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) str = malloc(len); if (str) { snprintf(str, len, "%s", ptr); - for (i = 0; i < len - 1; i++) - if (!isprint(str[i])) + for (i = 0; i < len - 1; i++) { + if ((unsigned char) str[i] < 32 || str[i] == 127) str[i] = '.'; + } + printf("\t%s local name: \'%s\'\n", type == 0x08 ? "Shortened" : "Complete", str); free(str); diff --git a/tools/hcitool.c b/tools/hcitool.c index dfa3e48e..9449e7c6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -546,9 +546,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - for (n = 0; n < 248 && name[n]; n++) - if (!isprint(name[n])) - name[n] = '.'; + for (n = 0; n < 248 && name[n]; n++) { + if ((unsigned char) name[i] < 32 || name[i] == 127) + name[i] = '.'; + } + name[248] = '\0'; printf("\t%s\t%s\n", addr, name); @@ -605,9 +607,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (!nc) strcpy(name, "n/a"); } else { - for (n = 0; n < 248 && name[n]; n++) - if (!isprint(name[n])) - name[n] = '.'; + for (n = 0; n < 248 && name[n]; n++) { + if ((unsigned char) name[i] < 32 || name[i] == 127) + name[i] = '.'; + } + name[248] = '\0'; nc = 0; } -- cgit From 225ca66857cfd4186a2651b60886e5ffe04fd3c2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Dec 2006 14:09:45 +0000 Subject: Add device ids for Logitech diNovo Laser keyboard and mouse --- tools/hid2hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 594ea044..0ca3fdce 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -224,6 +224,8 @@ static struct device_id device_list[] = { { HCI, 0x046d, 0xc704, switch_logitech }, { HCI, 0x046d, 0xc705, switch_logitech }, { HCI, 0x046d, 0xc70a, switch_logitech }, /* Logitech diNovo mouse */ + { HCI, 0x046d, 0xc70b, switch_logitech }, /* Logitech diNovo Laser keyboard */ + { HCI, 0x046d, 0xc70c, switch_logitech }, /* Logitech diNovo Laser mouse */ { HCI, 0x046d, 0xc70e, switch_logitech }, /* logitech diNovo keyboard */ { -1 } }; -- cgit From f1e35f0b9edc15eebfd9b2b0b01ffa4bf0f85cdb Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 20 Dec 2006 10:40:46 +0000 Subject: More accurate class of device decoding for hcitool and hciconfig --- tools/hciconfig.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++----- tools/hcitool.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 139 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 18601d77..0dc6d08a 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -594,16 +594,53 @@ static char *get_minor_device_name(int major, int minor) return "Gaming/Toy"; } break; - case 5: /* peripheral */ - switch(minor) { + case 5: /* peripheral */ { + static char cls_str[48]; + + cls_str[0] = '\0'; + + switch(minor & 48) { case 16: - return "Keyboard"; + strncpy(cls_str, "Keyboard", sizeof(cls_str)); + break; case 32: - return "Pointing device"; + strncpy(cls_str, "Pointing device", sizeof(cls_str)); + break; case 48: - return "Combo keyboard/pointing device"; + strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str)); + break; } - break; + if((minor & 15) && (strlen(cls_str) > 0)) + strcat(cls_str, "/"); + + switch(minor & 15) { + case 0: + break; + case 1: + strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str)); + break; + case 2: + strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str)); + break; + case 3: + strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str)); + break; + case 4: + strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str)); + break; + case 5: + strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str)); + break; + case 6: + strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str)); + break; + default: + strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str)); + break; + } + if(strlen(cls_str) > 0) + return cls_str; + } case 6: /* imaging */ if (minor & 4) return "Display"; @@ -614,6 +651,34 @@ static char *get_minor_device_name(int major, int minor) if (minor & 32) return "Printer"; break; + case 7: /* wearable */ + switch(minor) { + case 1: + return "Wrist Watch"; + case 2: + return "Pager"; + case 3: + return "Jacket"; + case 4: + return "Helmet"; + case 5: + return "Glasses"; + } + break; + case 8: /* toy */ + switch(minor) { + case 1: + return "Robot"; + case 2: + return "Vehicle"; + case 3: + return "Doll / Action Figure"; + case 4: + return "Controller"; + case 5: + return "Game"; + } + break; case 63: /* uncategorised */ return ""; } diff --git a/tools/hcitool.c b/tools/hcitool.c index 9449e7c6..50abce17 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -245,16 +245,51 @@ static char *get_minor_device_name(int major, int minor) return "Gaming/Toy"; } break; - case 5: /* peripheral */ - switch(minor) { + case 5: /* peripheral */ { + static char cls_str[48]; cls_str[0] = 0; + + switch(minor & 48) { case 16: - return "Keyboard"; + strncpy(cls_str, "Keyboard", sizeof(cls_str)); + break; case 32: - return "Pointing device"; + strncpy(cls_str, "Pointing device", sizeof(cls_str)); + break; case 48: - return "Combo keyboard/pointing device"; + strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str)); + break; } + if((minor & 15) && (strlen(cls_str) > 0)) + strcat(cls_str, "/"); + + switch(minor & 15) { + case 0: + break; + case 1: + strncat(cls_str, "Joystick", sizeof(cls_str) - strlen(cls_str)); + break; + case 2: + strncat(cls_str, "Gamepad", sizeof(cls_str) - strlen(cls_str)); + break; + case 3: + strncat(cls_str, "Remote control", sizeof(cls_str) - strlen(cls_str)); + break; + case 4: + strncat(cls_str, "Sensing device", sizeof(cls_str) - strlen(cls_str)); + break; + case 5: + strncat(cls_str, "Digitizer tablet", sizeof(cls_str) - strlen(cls_str)); break; + case 6: + strncat(cls_str, "Card reader", sizeof(cls_str) - strlen(cls_str)); + break; + default: + strncat(cls_str, "(reserved)", sizeof(cls_str) - strlen(cls_str)); + break; + } + if(strlen(cls_str) > 0) + return cls_str; + } case 6: /* imaging */ if (minor & 4) return "Display"; @@ -265,6 +300,34 @@ static char *get_minor_device_name(int major, int minor) if (minor & 32) return "Printer"; break; + case 7: /* wearable */ + switch(minor) { + case 1: + return "Wrist Watch"; + case 2: + return "Pager"; + case 3: + return "Jacket"; + case 4: + return "Helmet"; + case 5: + return "Glasses"; + } + break; + case 8: /* toy */ + switch(minor) { + case 1: + return "Robot"; + case 2: + return "Vehicle"; + case 3: + return "Doll / Action Figure"; + case 4: + return "Controller"; + case 5: + return "Game"; + } + break; case 63: /* uncategorised */ return ""; } -- cgit From 607695ed109340f4b7a5628420e0a8e8aee34f4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 17:48:12 +0000 Subject: Update copyright information --- tools/avctrl.c | 2 +- tools/bccmd.c | 2 +- tools/ciptool.c | 2 +- tools/csr.c | 2 +- tools/csr.h | 2 +- tools/csr_3wire.c | 2 +- tools/csr_bcsp.c | 2 +- tools/csr_h4.c | 2 +- tools/csr_hci.c | 2 +- tools/csr_usb.c | 2 +- tools/dfu.c | 2 +- tools/dfu.h | 2 +- tools/dfutool.c | 2 +- tools/hciattach.c | 2 +- tools/hciattach_st.c | 2 +- tools/hciconfig.c | 2 +- tools/hcisecfilter.c | 2 +- tools/hcitool.c | 2 +- tools/hid2hci.c | 2 +- tools/l2ping.c | 2 +- tools/ppporc.c | 2 +- tools/sdptool.c | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/avctrl.c b/tools/avctrl.c index c01e7d31..a7565c36 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/bccmd.c b/tools/bccmd.c index 2e426e79..4ce06675 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/ciptool.c b/tools/ciptool.c index 99add635..e5661012 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr.c b/tools/csr.c index 46d3ae10..8661bcef 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2006 Marcel Holtmann + * Copyright (C) 2003-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr.h b/tools/csr.h index 491ab4b7..5d0b989a 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2006 Marcel Holtmann + * Copyright (C) 2003-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_3wire.c b/tools/csr_3wire.c index 0999efc0..afcc5f50 100644 --- a/tools/csr_3wire.c +++ b/tools/csr_3wire.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 29a60bf9..26887414 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_h4.c b/tools/csr_h4.c index 8a3ff7fe..d31de396 100644 --- a/tools/csr_h4.c +++ b/tools/csr_h4.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_hci.c b/tools/csr_hci.c index 4f33d0ae..c9e02341 100644 --- a/tools/csr_hci.c +++ b/tools/csr_hci.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_usb.c b/tools/csr_usb.c index 75354fd0..a7966957 100644 --- a/tools/csr_usb.c +++ b/tools/csr_usb.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfu.c b/tools/dfu.c index 200426ff..6863751b 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2006 Marcel Holtmann + * Copyright (C) 2003-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfu.h b/tools/dfu.h index 9cfe70fa..d2ba2fbf 100644 --- a/tools/dfu.h +++ b/tools/dfu.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2006 Marcel Holtmann + * Copyright (C) 2003-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfutool.c b/tools/dfutool.c index 6bf65639..3d38f8ef 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2006 Marcel Holtmann + * Copyright (C) 2003-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciattach.c b/tools/hciattach.c index a38d2481..ab8a0f25 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index 014ddb2d..736597cb 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2005-2006 Marcel Holtmann + * Copyright (C) 2005-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 0dc6d08a..99ed7716 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 6114f57f..6a4f897b 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hcitool.c b/tools/hcitool.c index 50abce17..75fbc8e2 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 0ca3fdce..1e22b64d 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2006 Marcel Holtmann + * Copyright (C) 2003-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/l2ping.c b/tools/l2ping.c index 0ae61c9d..6b1ae477 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/ppporc.c b/tools/ppporc.c index 45e23549..cf9a10b4 100644 --- a/tools/ppporc.c +++ b/tools/ppporc.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/sdptool.c b/tools/sdptool.c index 4c3bf5cc..2fb7504f 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * Copyright (C) 2002-2003 Jean Tourrilhes * -- cgit From d08e29ecf191dc890e95e02999f66fd876069ad5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 14 Jan 2007 22:29:20 +0000 Subject: The Philips chips also support the Ericsson revision command --- tools/hciconfig.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 99ed7716..430cd0c3 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1466,6 +1466,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_dev_hdr(&di); switch (ver.manufacturer) { case 0: + case 37: case 48: print_rev_ericsson(dd); break; -- cgit From c3da6a497333f7e21007a3f23312e74464a408bf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 17 Jan 2007 12:31:42 +0000 Subject: Add support for Philips BGB2xx modules --- tools/Makefile.am | 1 + tools/hciattach.c | 25 +++++++++++++++++++++++-- tools/hciattach_st.c | 38 +++++++++++++++++++++++++++++++------- 3 files changed, 55 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 3b21f72b..21b2c3a2 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -38,6 +38,7 @@ bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) noinst_PROGRAMS = hcisecfilter ppporc hciattach_SOURCES = hciattach.c hciattach_st.c +hciattach_LDADD = @BLUEZ_LIBS@ hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a diff --git a/tools/hciattach.c b/tools/hciattach.c index ab8a0f25..45ce4d7b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -825,11 +825,26 @@ static int st(int fd, struct uart_t *u, struct termios *ti) return 0; } -extern int stlc2500_init(int fd); +extern int stlc2500_init(int fd, bdaddr_t *bdaddr); static int stlc2500(int fd, struct uart_t *u, struct termios *ti) { - return stlc2500_init(fd); + bdaddr_t bdaddr; + + str2ba("00:80:E1:00:AB:BA", &bdaddr); + + return stlc2500_init(fd, &bdaddr); +} + +extern int bgb2xx_init(int fd, bdaddr_t *bdaddr); + +static int bgb2xx(int fd, struct uart_t *u, struct termios *ti) +{ + bdaddr_t bdaddr; + + str2ba("BD:B2:10:00:AB:BA", &bdaddr); + + return bgb2xx_init(fd, &bdaddr); } /* @@ -976,6 +991,12 @@ struct uart_t uart[] = { /* ST Microelectronics minikits based on STLC2500 */ { "stlc2500", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, stlc2500 }, + /* Philips generic Ericsson IP core based */ + { "philips", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + + /* Philips BGB2xx Module */ + { "bgb2xx", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, bgb2xx }, + /* Sphinx Electronics PICO Card */ { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index 736597cb..47df4fe1 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -35,6 +35,8 @@ #include #include +#include + static int debug = 0; static int do_command(int fd, uint8_t ogf, uint16_t ocf, @@ -186,7 +188,7 @@ static int load_file(int dd, uint16_t version, const char *suffix) return 0; } -int stlc2500_init(int dd) +int stlc2500_init(int dd, bdaddr_t *bdaddr) { unsigned char cmd[16]; unsigned char buf[254]; @@ -221,12 +223,34 @@ int stlc2500_init(int dd) cmd[0] = 0xfe; cmd[1] = 0x06; - cmd[2] = 0xba; - cmd[3] = 0xab; - cmd[4] = 0x00; - cmd[5] = 0xe1; - cmd[6] = 0x80; - cmd[7] = 0x00; + bacpy((bdaddr_t *) (cmd + 2), bdaddr); + + len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf)); + if (len < 0) + return -1; + + len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); + if (len < 0) + return -1; + + return 0; +} + +int bgb2xx_init(int dd, bdaddr_t *bdaddr) +{ + unsigned char cmd[16]; + unsigned char buf[254]; + int len; + + len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf)); + if (len < 0) + return -1; + + printf("%s\n", buf); + + cmd[0] = 0xfe; + cmd[1] = 0x06; + bacpy((bdaddr_t *) (cmd + 2), bdaddr); len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf)); if (len < 0) -- cgit From a60dd957416d08b5f752d24b7277e885d4951fc5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Jan 2007 01:20:52 +0000 Subject: Add UUID for Nokia FTP --- tools/sdptool.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 2fb7504f..6418eafb 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2955,6 +2955,9 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) return 0; } +static unsigned char nftp_uuid[] = { 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + static unsigned char ngage_uuid[] = { 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; @@ -3136,6 +3139,7 @@ struct { { "PALMOS", 0, add_palmos, palmos_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, + { "NFTP", 0, NULL, nftp_uuid }, { "NGAGE", 0, NULL, ngage_uuid }, { "APPLE", 0, add_apple, apple_uuid }, -- cgit From 1bc5e02b94a1524de2ccb7e2f0704a895ad77de6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 23 Jan 2007 07:29:27 +0000 Subject: Make it possible to disable USB support --- tools/Makefile.am | 8 ++++++-- tools/bccmd.c | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 21b2c3a2..0ebb351b 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -55,8 +55,12 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c csr_3wire.c ubcsp.h ubcsp.c -bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_bcsp.c csr_h4.c csr_3wire.c ubcsp.h ubcsp.c +bccmd_LDADD = @BLUEZ_LIBS@ +if USB +bccmd_SOURCES += csr_usb.c +bccmd_LDADD += @USB_LIBS@ +endif endif if AVCTRL diff --git a/tools/bccmd.c b/tools/bccmd.c index 4ce06675..7f5deb5b 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -64,8 +64,10 @@ static inline int transport_open(int transport, char *device) switch (transport) { case CSR_TRANSPORT_HCI: return csr_open_hci(device); +#ifdef HAVE_LIBUSB case CSR_TRANSPORT_USB: return csr_open_usb(device); +#endif case CSR_TRANSPORT_BCSP: return csr_open_bcsp(device); case CSR_TRANSPORT_H4: @@ -83,8 +85,10 @@ static inline int transport_read(int transport, uint16_t varid, uint8_t *value, switch (transport) { case CSR_TRANSPORT_HCI: return csr_read_hci(varid, value, length); +#ifdef HAVE_LIBUSB case CSR_TRANSPORT_USB: return csr_read_usb(varid, value, length); +#endif case CSR_TRANSPORT_BCSP: return csr_read_bcsp(varid, value, length); case CSR_TRANSPORT_H4: @@ -102,8 +106,10 @@ static inline int transport_write(int transport, uint16_t varid, uint8_t *value, switch (transport) { case CSR_TRANSPORT_HCI: return csr_write_hci(varid, value, length); +#ifdef HAVE_LIBUSB case CSR_TRANSPORT_USB: return csr_write_usb(varid, value, length); +#endif case CSR_TRANSPORT_BCSP: return csr_write_bcsp(varid, value, length); case CSR_TRANSPORT_H4: @@ -122,9 +128,11 @@ static inline void transport_close(int transport) case CSR_TRANSPORT_HCI: csr_close_hci(); break; +#ifdef HAVE_LIBUSB case CSR_TRANSPORT_USB: csr_close_usb(); break; +#endif case CSR_TRANSPORT_BCSP: csr_close_bcsp(); break; -- cgit From 5b1649afe025b7b3f0e620fbd4c7a21b71545fe5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 11 Feb 2007 00:17:41 +0000 Subject: Add Wii-Mote HID service record --- tools/sdptool.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 6418eafb..8864dc99 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2069,6 +2069,7 @@ end: return ret; } + static int add_hid_keyb(sdp_session_t *session, svc_info_t *si) { sdp_record_t record; @@ -2232,6 +2233,177 @@ static int add_hid_keyb(sdp_session_t *session, svc_info_t *si) return 0; } +static int add_hid_wiimote(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, hid_uuid, l2cap_uuid, hidp_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[3]; + sdp_data_t *psm, *lang_lst, *lang_lst2, *hid_spec_lst, *hid_spec_lst2; + int i; + uint8_t dtd = SDP_UINT16; + uint8_t dtd2 = SDP_UINT8; + uint8_t dtd_data = SDP_TEXT_STR8; + void *dtds[2]; + void *values[2]; + void *dtds2[2]; + void *values2[2]; + int leng[2]; + uint8_t hid_spec_type = 0x22; + uint16_t hid_attr_lang[] = { 0x409, 0x100 }; + uint16_t ctrl = 0x11, intr = 0x13; + uint16_t hid_release = 0x0100, parser_version = 0x0111; + uint8_t subclass = 0x04, country = 0x33; + uint8_t virtual_cable = 0, reconnect = 1, sdp_disable = 0; + uint8_t battery = 1, remote_wakeup = 1; + uint16_t profile_version = 0x0100, superv_timeout = 0x0c80; + uint8_t norm_connect = 0, boot_device = 0; + const uint8_t hid_spec[] = { + 0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x10, + 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, + 0x01, 0x06, 0x00, 0xff, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x11, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x12, 0x95, 0x02, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x13, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x14, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x15, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x16, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x17, 0x95, 0x06, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x18, 0x95, 0x15, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x19, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x1a, 0x95, 0x01, 0x09, 0x01, 0x91, 0x00, + 0x85, 0x20, 0x95, 0x06, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x21, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x22, 0x95, 0x04, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x30, 0x95, 0x02, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x31, 0x95, 0x05, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x32, 0x95, 0x0a, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x33, 0x95, 0x11, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x34, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x35, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x36, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x37, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x3d, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x3e, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0x85, 0x3f, 0x95, 0x15, 0x09, 0x01, 0x81, 0x00, + 0xc0, 0x00 + }; + + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&hid_uuid, HID_SVCLASS_ID); + svclass_id = sdp_list_append(NULL, &hid_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, HID_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[1] = sdp_list_append(0, &l2cap_uuid); + psm = sdp_data_alloc(SDP_UINT16, &ctrl); + proto[1] = sdp_list_append(proto[1], psm); + apseq = sdp_list_append(0, proto[1]); + + sdp_uuid16_create(&hidp_uuid, HIDP_UUID); + proto[2] = sdp_list_append(0, &hidp_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + proto[1] = sdp_list_append(0, &l2cap_uuid); + psm = sdp_data_alloc(SDP_UINT16, &intr); + proto[1] = sdp_list_append(proto[1], psm); + apseq = sdp_list_append(0, proto[1]); + + sdp_uuid16_create(&hidp_uuid, HIDP_UUID); + proto[2] = sdp_list_append(0, &hidp_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_add_access_protos(&record, aproto); + + add_lang_attr(&record); + + sdp_set_info_attr(&record, "Nintendo RVL-CNT-01", + "Nintendo", "Nintendo RVL-CNT-01"); + + sdp_attr_add_new(&record, SDP_ATTR_HID_DEVICE_RELEASE_NUMBER, + SDP_UINT16, &hid_release); + + sdp_attr_add_new(&record, SDP_ATTR_HID_PARSER_VERSION, + SDP_UINT16, &parser_version); + + sdp_attr_add_new(&record, SDP_ATTR_HID_DEVICE_SUBCLASS, + SDP_UINT8, &subclass); + + sdp_attr_add_new(&record, SDP_ATTR_HID_COUNTRY_CODE, + SDP_UINT8, &country); + + sdp_attr_add_new(&record, SDP_ATTR_HID_VIRTUAL_CABLE, + SDP_BOOL, &virtual_cable); + + sdp_attr_add_new(&record, SDP_ATTR_HID_RECONNECT_INITIATE, + SDP_BOOL, &reconnect); + + dtds[0] = &dtd2; + values[0] = &hid_spec_type; + dtds[1] = &dtd_data; + values[1] = (uint8_t *) hid_spec; + leng[0] = 0; + leng[1] = sizeof(hid_spec); + hid_spec_lst = sdp_seq_alloc_with_length(dtds, values, leng, 2); + hid_spec_lst2 = sdp_data_alloc(SDP_SEQ8, hid_spec_lst); + sdp_attr_add(&record, SDP_ATTR_HID_DESCRIPTOR_LIST, hid_spec_lst2); + + for (i = 0; i < sizeof(hid_attr_lang) / 2; i++) { + dtds2[i] = &dtd; + values2[i] = &hid_attr_lang[i]; + } + + lang_lst = sdp_seq_alloc(dtds2, values2, sizeof(hid_attr_lang) / 2); + lang_lst2 = sdp_data_alloc(SDP_SEQ8, lang_lst); + sdp_attr_add(&record, SDP_ATTR_HID_LANG_ID_BASE_LIST, lang_lst2); + + sdp_attr_add_new(&record, SDP_ATTR_HID_SDP_DISABLE, + SDP_BOOL, &sdp_disable); + + sdp_attr_add_new(&record, SDP_ATTR_HID_BATTERY_POWER, + SDP_BOOL, &battery); + + sdp_attr_add_new(&record, SDP_ATTR_HID_REMOTE_WAKEUP, + SDP_BOOL, &remote_wakeup); + + sdp_attr_add_new(&record, SDP_ATTR_HID_PROFILE_VERSION, + SDP_UINT16, &profile_version); + + sdp_attr_add_new(&record, SDP_ATTR_HID_SUPERVISION_TIMEOUT, + SDP_UINT16, &superv_timeout); + + sdp_attr_add_new(&record, SDP_ATTR_HID_NORMALLY_CONNECTABLE, + SDP_BOOL, &norm_connect); + + sdp_attr_add_new(&record, SDP_ATTR_HID_BOOT_DEVICE, + SDP_BOOL, &boot_device); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Wii-Mote service registered\n"); + + return 0; +} + static int add_cip(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -3119,6 +3291,7 @@ struct { { "HCRP", HCR_SVCLASS_ID, NULL }, { "HID", HID_SVCLASS_ID, NULL }, { "KEYB", HID_SVCLASS_ID, add_hid_keyb }, + { "WIIMOTE", HID_SVCLASS_ID, add_hid_wiimote }, { "CIP", CIP_SVCLASS_ID, add_cip }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, -- cgit From c7d02264b409fb1fe1af55a45417cf39a2362f66 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Feb 2007 09:25:40 +0000 Subject: Typo --- tools/hid2hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 1e22b64d..f4409c20 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -226,7 +226,7 @@ static struct device_id device_list[] = { { HCI, 0x046d, 0xc70a, switch_logitech }, /* Logitech diNovo mouse */ { HCI, 0x046d, 0xc70b, switch_logitech }, /* Logitech diNovo Laser keyboard */ { HCI, 0x046d, 0xc70c, switch_logitech }, /* Logitech diNovo Laser mouse */ - { HCI, 0x046d, 0xc70e, switch_logitech }, /* logitech diNovo keyboard */ + { HCI, 0x046d, 0xc70e, switch_logitech }, /* Logitech diNovo keyboard */ { -1 } }; -- cgit From dcf9a09a033ce0e5420a7ef719e8e88e3eeaeb5c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Apr 2007 23:25:14 +0000 Subject: Handle EINTR errors --- tools/hciattach.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 45ce4d7b..a01c149f 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -1135,7 +1135,7 @@ static void usage(void) int main(int argc, char *argv[]) { struct uart_t *u = NULL; - int detach, printpid, opt, i, n, ld; + int detach, printpid, opt, i, n, ld, err; int to = 5; int init_speed = 0; int send_break = 0; @@ -1286,7 +1286,10 @@ int main(int argc, char *argv[]) while (!__io_canceled) { p.revents = 0; - if (poll(&p, 1, 500)) + err = poll(&p, 1, 500); + if (err < 0 && errno == EINTR) + continue; + if (err) break; } -- cgit From ebd5a00a5a30970a5546a599f37f44a6a0470916 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Apr 2007 14:08:19 +0000 Subject: Add build ids for Unified 22c firmwares --- tools/csr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 8661bcef..12fc6419 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -333,6 +333,9 @@ static struct { { 3415, "Unified 21f" }, { 3424, "Unified 21f" }, { 3454, "Unified 21f" }, + { 4363, "Unified 22c" }, + { 4373, "Unified 22c" }, + { 4374, "Unified 22c" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, -- cgit From 7003cb14e073b191bd82842cf50c25ba03ca9f0e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Apr 2007 14:16:35 +0000 Subject: Add build ids for Unified 22b firmwares --- tools/csr.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 12fc6419..318542be 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -333,6 +333,21 @@ static struct { { 3415, "Unified 21f" }, { 3424, "Unified 21f" }, { 3454, "Unified 21f" }, + { 4276, "Unified 22b" }, + { 4277, "Unified 22b" }, + { 4279, "Unified 22b" }, + { 4281, "Unified 22b" }, + { 4282, "Unified 22b" }, + { 4283, "Unified 22b" }, + { 4284, "Unified 22b" }, + { 4285, "Unified 22b" }, + { 4289, "Unified 22b" }, + { 4290, "Unified 22b" }, + { 4291, "Unified 22b" }, + { 4292, "Unified 22b" }, + { 4293, "Unified 22b" }, + { 4294, "Unified 22b" }, + { 4295, "Unified 22b" }, { 4363, "Unified 22c" }, { 4373, "Unified 22c" }, { 4374, "Unified 22c" }, -- cgit From b0fac4eacec5fd1cb73880f2e705d08bacf667a4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Apr 2007 14:19:24 +0000 Subject: Add build ids for Unified 21f firmwares --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 318542be..93ad5de9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -333,6 +333,8 @@ static struct { { 3415, "Unified 21f" }, { 3424, "Unified 21f" }, { 3454, "Unified 21f" }, + { 3684, "Unified 21f" }, + { 3764, "Unified 21f" }, { 4276, "Unified 22b" }, { 4277, "Unified 22b" }, { 4279, "Unified 22b" }, -- cgit From 6709e54559ae9f94749c5401579b03716400eb02 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 25 Apr 2007 23:09:02 +0000 Subject: Add support for STLC2500 address and baud rate settings --- tools/hciattach.8 | 11 +++++ tools/hciattach.c | 132 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 116 insertions(+), 27 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.8 b/tools/hciattach.8 index 430e8067..f9d295eb 100644 --- a/tools/hciattach.8 +++ b/tools/hciattach.8 @@ -11,6 +11,7 @@ hciattach \- attach serial devices via UART HCI to BlueZ stack .IR type \||\| id .I speed .I flow +.I bdaddr .SH DESCRIPTION .LP Hciattach is used to attach a serial UART to the Bluetooth stack as HCI @@ -105,6 +106,16 @@ set by default. To force no flow control use .B noflow instead. +.TP +.I bdaddr +The +.I bdaddr +specifies the Bluetooth Address to use. Some devices (like the STLC2500) +do not store the Bluetooth address in hardware memory. Instead it must +be uploaded during the initialization process. If this argument +is specified, then the address will be used to initialize the device. +Otherwise, a default address will be used. + .SH AUTHORS Written by Maxim Krasnyansky .PP diff --git a/tools/hciattach.c b/tools/hciattach.c index a01c149f..776035e0 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -67,6 +67,7 @@ struct uart_t { int init_speed; int speed; int flags; + char *bdaddr; int (*init) (int fd, struct uart_t *u, struct termios *ti); }; @@ -830,9 +831,82 @@ extern int stlc2500_init(int fd, bdaddr_t *bdaddr); static int stlc2500(int fd, struct uart_t *u, struct termios *ti) { bdaddr_t bdaddr; + char cmd[5]; + unsigned char resp[10]; + int n; + + /* STLC2500 Set Baud Rate stuff */ + /* We should set the baud rate first, so the firmware download */ + /* goes much faster */ + + /* STLC2500 Seems to support the Ericsson set baud rate stuff */ + /* It should also support the ST Set Baud Rate command */ + /* (as in st() function above, but those commands never succeed */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x09; + cmd[2] = 0xfc; + cmd[3] = 0x01; + + switch (u->speed) { + case 57600: + cmd[4] = 0x03; + break; + case 115200: + cmd[4] = 0x02; + break; + case 230400: + cmd[4] = 0x01; + break; + case 460800: + cmd[4] = 0x00; + break; + case 921600: + cmd[4] = 0x20; + break; + default: + cmd[4] = 0x02; + u->speed = 115200; + break; + } + +#ifdef STLC2500_DEBUG + fprintf(stderr, "Sending Baud Rate %02x\n", cmd[4]); +#endif + /* Send initialization command */ + if (write(fd, cmd, 5) != 5) { + perror("Failed to write init command"); + return -1; + } - str2ba("00:80:E1:00:AB:BA", &bdaddr); + /* Need to wait here to give a chance for the device to set baud */ + /* But no more than 0.5 seconds */ + usleep(200000); +#ifdef STLC2500_DEBUG + fprintf(stderr, "Setting speed\n"); +#endif + if (set_speed(fd, ti, u->speed) < 0) { + perror("Can't set baud rate"); + return -1; + } + +#ifdef STLC2500_DEBUG + fprintf(stderr, "Speed set...\n"); +#endif + + /* Read reply */ + if ((n = read_hci_event(fd, resp, 10)) < 0) { + fprintf(stderr, "Failed to set baud rate on chip\n"); + return -1; + } + +#ifdef STLC2500_DEBUG + for (i = 0; i < n; i++) { + fprintf(stderr, "resp[%d] = %02x\n", i, resp[i]); + } +#endif + + str2ba(u->bdaddr, &bdaddr); return stlc2500_init(fd, &bdaddr); } @@ -842,7 +916,7 @@ static int bgb2xx(int fd, struct uart_t *u, struct termios *ti) { bdaddr_t bdaddr; - str2ba("BD:B2:10:00:AB:BA", &bdaddr); + str2ba(u->bdaddr, &bdaddr); return bgb2xx_init(fd, &bdaddr); } @@ -966,69 +1040,69 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) } struct uart_t uart[] = { - { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, - { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, - { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, digi }, - { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, texas }, + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, NULL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, NULL, digi }, + { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, texas }, - { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ - { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, NULL }, /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ - { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, csr }, /* BrainBoxes PCMCIA card (BL620) */ - { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 115200, 460800, FLOW_CTL, csr }, + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 115200, 460800, FLOW_CTL, NULL, csr }, /* Silicon Wave kits */ - { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, swave }, /* ST Microelectronics minikits based on STLC2410/STLC2415 */ - { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, st }, + { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, NULL, st }, /* ST Microelectronics minikits based on STLC2500 */ - { "stlc2500", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, stlc2500 }, + { "stlc2500", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, "00:80:E1:00:AB:BA", stlc2500 }, /* Philips generic Ericsson IP core based */ - { "philips", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "philips", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, NULL }, /* Philips BGB2xx Module */ - { "bgb2xx", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, bgb2xx }, + { "bgb2xx", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, "BD:B2:10:00:AB:BA", bgb2xx }, /* Sphinx Electronics PICO Card */ - { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, NULL }, /* Inventel BlueBird Module */ - { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, NULL }, /* COM One Platinium Bluetooth PC Card */ - { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, /* TDK Bluetooth PC Card and IBM Bluetooth PC Card II */ - { "tdk", 0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "tdk", 0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, /* Socket Bluetooth CF Card (Rev G) */ - { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, + { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, NULL, bcsp }, /* 3Com Bluetooth Card (Version 3.0) */ - { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, csr }, /* AmbiCom BT2000C Bluetooth PC/CF Card */ - { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, + { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, NULL, csr }, /* Zoom Bluetooth PCMCIA Card */ - { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, /* Sitecom CN-504 PCMCIA Card */ - { "sitecom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "sitecom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, /* Billionton PCBTC1 PCMCIA Card */ - { "billionton", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "billionton", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, /* Broadcom BCM2035 */ - { "bcm2035", 0x0A5C, 0x2035, HCI_UART_H4, 115200, 115200, 0, bcm2035 }, + { "bcm2035", 0x0A5C, 0x2035, HCI_UART_H4, 115200, 115200, 0, NULL, bcm2035 }, { NULL, 0 } }; @@ -1128,7 +1202,7 @@ static void usage(void) { printf("hciattach - HCI UART driver initialization utility\n"); printf("Usage:\n"); - printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow|noflow]\n"); + printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow|noflow] [bdaddr]\n"); printf("\thciattach -l\n"); } @@ -1227,6 +1301,10 @@ int main(int argc, char *argv[]) else u->flags &= ~FLOW_CTL; break; + + case 4: + u->bdaddr = argv[optind]; + break; } } -- cgit From bb02c974cc53e2a8ef9e01293070b339f00a33c4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 May 2007 09:34:21 +0000 Subject: Add HCIUARTGETDEVICE ioctl constant --- tools/hciattach.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 776035e0..c07d996b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -51,8 +51,9 @@ #define N_HCI 15 #endif -#define HCIUARTSETPROTO _IOW('U', 200, int) -#define HCIUARTGETPROTO _IOR('U', 201, int) +#define HCIUARTSETPROTO _IOW('U', 200, int) +#define HCIUARTGETPROTO _IOR('U', 201, int) +#define HCIUARTGETDEVICE _IOR('U', 202, int) #define HCI_UART_H4 0 #define HCI_UART_BCSP 1 -- cgit From 68dc1b1a461792897e7be1cafb97b1f80e6aa304 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 May 2007 10:47:49 +0000 Subject: Make it possible to disable installation of manual pages --- tools/Makefile.am | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 0ebb351b..880036ea 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -80,9 +80,12 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common +if MANPAGES man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ $(bccmd_manfiles) $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) +endif -EXTRA_DIST = $(man_MANS) bccmd.8 avctrl.8 hid2hci.8 dfutool.1 example.psr +EXTRA_DIST = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ + bccmd.8 avctrl.8 hid2hci.8 dfutool.1 example.psr MAINTAINERCLEANFILES = Makefile.in -- cgit From fcb09f4016ced43843625b197d851c90088dd418 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 6 Jun 2007 20:36:28 +0000 Subject: sdptool: fixed memory leak for setattr and setseq --- tools/sdptool.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 8864dc99..1bf3526c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -755,10 +755,12 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha sdp_list_t *attrid_list; uint32_t range = 0x0000ffff; sdp_record_t *rec; + int ret; /* Get the old SDP record */ attrid_list = sdp_list_append(NULL, &range); rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attrid_list); + sdp_list_free(attrid_list, NULL); if (!rec) { printf("Service get request failed.\n"); @@ -794,11 +796,11 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha } /* Update on the server */ - if (sdp_device_record_update(sess, &interface, rec)) { + ret = sdp_device_record_update(sess, &interface, rec); + if (ret < 0) printf("Service Record update failed (%d).\n", errno); - return -1; - } - return 0; + sdp_record_free(rec); + return ret; } static struct option set_options[] = { @@ -867,11 +869,12 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri uint8_t uuid16 = SDP_UUID16; uint8_t uint32 = SDP_UINT32; uint8_t str8 = SDP_TEXT_STR8; - int i; + int i, ret = 0; /* Get the old SDP record */ attrid_list = sdp_list_append(NULL, &range); rec = sdp_service_attr_req(session, handle, SDP_ATTR_REQ_RANGE, attrid_list); + sdp_list_free(attrid_list, NULL); if (!rec) { printf("Service get request failed.\n"); @@ -919,10 +922,9 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri sdp_attr_replace(rec, attrib, pSequenceHolder); /* Update on the server */ - if (sdp_device_record_update(session, &interface, rec)) { + ret = sdp_device_record_update(session, &interface, rec); + if (ret < 0) printf("Service Record update failed (%d).\n", errno); - return -1; - } } else printf("Failed to create pSequenceHolder\n"); @@ -932,8 +934,11 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri free(dtdArray); free(valueArray); + free(allocArray); - return 0; + sdp_record_free(rec); + + return ret; } static struct option seq_options[] = { -- cgit From abae7c2638fb280393750d2a7789b0fc8188c644 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Jun 2007 04:14:04 +0000 Subject: Add another build id for the "marcel" specific firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 93ad5de9..b82eed81 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -358,6 +358,7 @@ static struct { { 2622, "Marcel 3 (2005-10-27)" }, { 3326, "Marcel 4 (2006-06-16)" }, { 3612, "Marcel 5 (2006-10-24)" }, + { 4509, "Marcel 6 (2007-06-11)" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 5542ce34cfb07a75eebd5659fb66d1fe2394faa6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Jun 2007 11:31:41 +0000 Subject: Fix decoding of extended pages number --- tools/hcitool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 75fbc8e2..49cc6fe6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -905,9 +905,11 @@ static void cmd_info(int dev_id, int argc, char **argv) } if ((di.features[7] & LMP_EXT_FEAT) && (features[7] & LMP_EXT_FEAT)) { - if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) + if (hci_read_remote_ext_features(dd, handle, 0, + &max_page, features, 20000) == 0) if (max_page > 0) - printf("\tExtended features: %d pages\n", max_page); + printf("\tExtended features: %d page%s\n", + max_page, max_page > 1 ? "s" : ""); } if (cc) { -- cgit From dc910eeb1f381a883ad9e1617a7f72efd04a2d46 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Jun 2007 23:07:13 +0000 Subject: Improve the BCM2035 init routine --- tools/hciattach.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index c07d996b..ece80ce1 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -951,6 +951,29 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) return -1; } + if (u->bdaddr != NULL) { + /* Set BD_ADDR */ + memset(cmd, 0, sizeof(cmd)); + memset(resp, 0, sizeof(resp)); + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x01; + cmd[2] = 0xfc; + cmd[3] = 0x06; + str2ba(u->bdaddr, (bdaddr_t *) (cmd + 4)); + + /* Send command */ + if (write(fd, cmd, 10) != 10) { + fprintf(stderr, "Failed to write BD_ADDR command\n"); + return -1; + } + + /* Read reply */ + if ((n = read_hci_event(fd, resp, 10)) < 0) { + fprintf(stderr, "Failed to set BD_ADDR\n"); + return -1; + } + } + /* Read the local version info */ memset(cmd, 0, sizeof(cmd)); memset(resp, 0, sizeof(resp)); @@ -983,7 +1006,7 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) /* Send command */ if (write(fd, cmd, 4) != 4) { fprintf(stderr, "Failed to write \"read local supported " - "commands\" command\n"); + "commands\" command\n"); return -1; } @@ -1010,11 +1033,11 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti) cmd[5] = 0xfa; break; case 460800: - cmd[4] = 0x11; + cmd[4] = 0x22; cmd[5] = 0xfd; break; case 921600: - cmd[4] = 0x65; + cmd[4] = 0x55; cmd[5] = 0xff; break; default: @@ -1103,7 +1126,7 @@ struct uart_t uart[] = { { "billionton", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, /* Broadcom BCM2035 */ - { "bcm2035", 0x0A5C, 0x2035, HCI_UART_H4, 115200, 115200, 0, NULL, bcm2035 }, + { "bcm2035", 0x0A5C, 0x2035, HCI_UART_H4, 115200, 460800, FLOW_CTL, NULL, bcm2035 }, { NULL, 0 } }; -- cgit From 83a5ae0fca73331da1c1cfba6d525bac30326992 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 13 Jul 2007 03:05:30 +0000 Subject: Add command for reading the chip revision --- tools/bccmd.8 | 3 +++ tools/bccmd.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) (limited to 'tools') diff --git a/tools/bccmd.8 b/tools/bccmd.8 index 95d67461..c3c93f76 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -54,6 +54,9 @@ Get local Bluetooth clock .BI rand Get random number .TP +.BI chiprev +Get chip revision +.TP .BI buildname Get the full build name .TP diff --git a/tools/bccmd.c b/tools/bccmd.c index 7f5deb5b..8d65a454 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -345,6 +345,66 @@ static int cmd_rand(int transport, int argc, char *argv[]) return 0; } +static int cmd_chiprev(int transport, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t rev; + char *str; + int err; + + OPT_HELP(0, NULL); + + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_CHIPREV, array, 8); + if (err < 0) { + errno = -err; + return -1; + } + + rev = array[0] | (array[1] << 8); + + switch (rev) { + case 0x64: + str = "BC1 ES"; + break; + case 0x65: + str = "BC1"; + break; + case 0x89: + str = "BC2-External A"; + break; + case 0x8a: + str = "BC2-External B"; + break; + case 0x28: + str = "BC2-ROM"; + break; + case 0x43: + str = "BC3-Multimedia"; + break; + case 0x15: + str = "BC3-ROM"; + break; + case 0xe2: + str = "BC3-Flash"; + break; + case 0x26: + str = "BC4-External"; + break; + case 0x30: + str = "BC4-ROM"; + break; + default: + str = "NA"; + break; + } + + printf("Chip revision: 0x%04x (%s)\n", rev, str); + + return 0; +} + static int cmd_buildname(int transport, int argc, char *argv[]) { uint8_t array[130]; @@ -987,6 +1047,7 @@ static struct { { "keylen", cmd_keylen, "", "Get current crypt key length" }, { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { "rand", cmd_rand, "", "Get random number" }, + { "chiprev", cmd_chiprev, "", "Get chip revision" }, { "buildname", cmd_buildname, "", "Get the full build name" }, { "panicarg", cmd_panicarg, "", "Get panic code argument" }, { "faultarg", cmd_faultarg, "", "Get fault code argument" }, -- cgit From 95b9fe0e10effdae8f1721cb42c7f67862913ecb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 14 Jul 2007 13:24:26 +0000 Subject: Add generic radio test support --- tools/bccmd.8 | 3 +++ tools/bccmd.c | 76 ++++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 24 deletions(-) (limited to 'tools') diff --git a/tools/bccmd.8 b/tools/bccmd.8 index c3c93f76..28cbe880 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -87,6 +87,9 @@ Revert to channel hopping .BI rttxdata1\ \ TXData1 radio test .TP +.BI radiotest\ \ \ +Run radio tests, tests 4, 6 and 7 are transmit tests +.TP .BI memtypes Get memory types .TP diff --git a/tools/bccmd.c b/tools/bccmd.c index 8d65a454..efce49d8 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -551,6 +551,33 @@ static int cmd_rttxdata1(int transport, int argc, char *argv[]) return transport_write(transport, CSR_VARID_RADIOTEST, array, 8); } +static int cmd_radiotest(int transport, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t freq, level, test; + + OPT_HELP(3, NULL); + + freq = atoi(argv[0]); + + if (!strncasecmp(argv[1], "0x", 2)) + level = strtol(argv[1], NULL, 16); + else + level = atoi(argv[1]); + + test = atoi(argv[2]); + + memset(array, 0, sizeof(array)); + array[0] = test & 0xff; + array[1] = test >> 8; + array[2] = freq & 0xff; + array[3] = freq >> 8; + array[4] = level & 0xff; + array[5] = level >> 8; + + return transport_write(transport, CSR_VARID_RADIOTEST, array, 8); +} + static int cmd_memtypes(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -1043,29 +1070,30 @@ static struct { char *arg; char *doc; } commands[] = { - { "builddef", cmd_builddef, "", "Get build definitions" }, - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "rand", cmd_rand, "", "Get random number" }, - { "chiprev", cmd_chiprev, "", "Get chip revision" }, - { "buildname", cmd_buildname, "", "Get the full build name" }, - { "panicarg", cmd_panicarg, "", "Get panic code argument" }, - { "faultarg", cmd_faultarg, "", "Get fault code argument" }, - { "coldreset", cmd_coldreset, "", "Perform cold reset" }, - { "warmreset", cmd_warmreset, "", "Perform warm reset" }, - { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, - { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, - { "singlechan",cmd_singlechan,"", "Lock radio on specific channel" }, - { "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" }, - { "rttxdata1", cmd_rttxdata1, " ","TXData1 radio test" }, - { "memtypes", cmd_memtypes, NULL, "Get memory types" }, - { "psget", cmd_psget, "", "Get value for PS key" }, - { "psset", cmd_psset, " ", "Set value for PS key" }, - { "psclr", cmd_psclr, "", "Clear value for PS key" }, - { "pslist", cmd_pslist, NULL, "List all PS keys" }, - { "psread", cmd_psread, NULL, "Read all PS keys" }, - { "psload", cmd_psload, "", "Load all PS keys from PSR file" }, - { "pscheck", cmd_pscheck, "", "Check PSR file" }, + { "builddef", cmd_builddef, "", "Get build definitions" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "chiprev", cmd_chiprev, "", "Get chip revision" }, + { "buildname", cmd_buildname, "", "Get the full build name" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "coldreset", cmd_coldreset, "", "Perform cold reset" }, + { "warmreset", cmd_warmreset, "", "Perform warm reset" }, + { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, + { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "singlechan",cmd_singlechan,"", "Lock radio on specific channel" }, + { "hoppingon", cmd_hoppingon, "", "Revert to channel hopping" }, + { "rttxdata1", cmd_rttxdata1, " ", "TXData1 radio test" }, + { "radiotest", cmd_radiotest, " ", "Run radio tests" }, + { "memtypes", cmd_memtypes, NULL, "Get memory types" }, + { "psget", cmd_psget, "", "Get value for PS key" }, + { "psset", cmd_psset, " ", "Set value for PS key" }, + { "psclr", cmd_psclr, "", "Clear value for PS key" }, + { "pslist", cmd_pslist, NULL, "List all PS keys" }, + { "psread", cmd_psread, NULL, "Read all PS keys" }, + { "psload", cmd_psload, "", "Load all PS keys from PSR file" }, + { "pscheck", cmd_pscheck, "", "Check PSR file" }, { NULL } }; @@ -1088,7 +1116,7 @@ static void usage(void) printf("Commands:\n"); for (i = 0; commands[i].str; i++) - printf("\t%-10s %-14s\t%s\n", commands[i].str, + printf("\t%-10s %-20s\t%s\n", commands[i].str, commands[i].arg ? commands[i].arg : " ", commands[i].doc); printf("\n"); -- cgit From 072e787344d83af866fc6fb4f7ee88fd5d62cac2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 19 Jul 2007 16:16:28 +0000 Subject: Add another build id for sniffer firmware --- tools/csr.c | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index b82eed81..cd141a64 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -321,7 +321,7 @@ static struct { { 2656, "Unified 21c" }, { 2658, "Unified 21c" }, { 3057, "Unified 21d" }, - { 3058, "Unified 21d" }, + { 3058, "Unified 21d" }, { 3059, "Unified 21d" }, { 3060, "Unified 21d" }, { 3062, "Unified 21d" }, @@ -369,7 +369,7 @@ static struct { { 306, "Sniff 8 (2002-04-12)" }, { 343, "Sniff 9 (2002-05-02)" }, { 346, "Sniff 10 (2002-05-03)" }, - { 355, "Sniff 11 (2002-05-16)" }, + { 355, "Sniff 11 (2002-05-16)" }, { 256, "Sniff 11 (2002-05-16)" }, { 390, "Sniff 12 (2002-06-26)" }, { 450, "Sniff 13 (2002-08-16)" }, @@ -405,33 +405,34 @@ static struct { { 1759, "Sniff 40 (2004-11-03)" }, { 1760, "Sniff 40 (2004-11-03)" }, { 1761, "Sniff 40 (2004-11-03)" }, - { 2009, "Sniff 41 (2005-04-06)" }, - { 2010, "Sniff 41 (2005-04-06)" }, - { 2011, "Sniff 41 (2005-04-06)" }, - { 2016, "Sniff 42 (2005-04-11)" }, - { 2017, "Sniff 42 (2005-04-11)" }, - { 2018, "Sniff 42 (2005-04-11)" }, - { 2023, "Sniff 43 (2005-04-14)" }, - { 2024, "Sniff 43 (2005-04-14)" }, - { 2025, "Sniff 43 (2005-04-14)" }, - { 2032, "Sniff 44 (2005-04-18)" }, - { 2033, "Sniff 44 (2005-04-18)" }, - { 2034, "Sniff 44 (2005-04-18)" }, - { 2288, "Sniff 45 (2005-07-08)" }, - { 2289, "Sniff 45 (2005-07-08)" }, - { 2290, "Sniff 45 (2005-07-08)" }, - { 2388, "Sniff 46 (2005-08-17)" }, - { 2389, "Sniff 46 (2005-08-17)" }, - { 2390, "Sniff 46 (2005-08-17)" }, - { 2869, "Sniff 47 (2006-02-15)" }, - { 2870, "Sniff 47 (2006-02-15)" }, - { 2871, "Sniff 47 (2006-02-15)" }, - { 3214, "Sniff 48 (2006-05-16)" }, - { 3215, "Sniff 48 (2006-05-16)" }, - { 3216, "Sniff 48 (2006-05-16)" }, + { 2009, "Sniff 41 (2005-04-06)" }, + { 2010, "Sniff 41 (2005-04-06)" }, + { 2011, "Sniff 41 (2005-04-06)" }, + { 2016, "Sniff 42 (2005-04-11)" }, + { 2017, "Sniff 42 (2005-04-11)" }, + { 2018, "Sniff 42 (2005-04-11)" }, + { 2023, "Sniff 43 (2005-04-14)" }, + { 2024, "Sniff 43 (2005-04-14)" }, + { 2025, "Sniff 43 (2005-04-14)" }, + { 2032, "Sniff 44 (2005-04-18)" }, + { 2033, "Sniff 44 (2005-04-18)" }, + { 2034, "Sniff 44 (2005-04-18)" }, + { 2288, "Sniff 45 (2005-07-08)" }, + { 2289, "Sniff 45 (2005-07-08)" }, + { 2290, "Sniff 45 (2005-07-08)" }, + { 2388, "Sniff 46 (2005-08-17)" }, + { 2389, "Sniff 46 (2005-08-17)" }, + { 2390, "Sniff 46 (2005-08-17)" }, + { 2869, "Sniff 47 (2006-02-15)" }, + { 2870, "Sniff 47 (2006-02-15)" }, + { 2871, "Sniff 47 (2006-02-15)" }, + { 3214, "Sniff 48 (2006-05-16)" }, + { 3215, "Sniff 48 (2006-05-16)" }, + { 3216, "Sniff 48 (2006-05-16)" }, { 3356, "Sniff 49 (2006-07-17)" }, { 3529, "Sniff 50 (2006-09-21)" }, { 3546, "Sniff 51 (2006-09-29)" }, + { 3683, "Sniff 52 (2006-11-03)" }, { 0, } }; -- cgit From 35cc0e38796c35a24bcd7949e5b478def0672207 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jul 2007 23:20:29 +0000 Subject: Add identifier for Nokia SyncML records --- tools/sdptool.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 1bf3526c..f3bd6432 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -3135,6 +3135,9 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) static unsigned char nftp_uuid[] = { 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; +static unsigned char nsyncml_uuid[] = { 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + static unsigned char ngage_uuid[] = { 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; @@ -3318,6 +3321,7 @@ struct { { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "NFTP", 0, NULL, nftp_uuid }, + { "NSYNCML", 0, NULL, nsyncml_uuid }, { "NGAGE", 0, NULL, ngage_uuid }, { "APPLE", 0, add_apple, apple_uuid }, -- cgit From a46dd97e351ed0f312601cf8f0297fcbc358318e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jul 2007 23:28:19 +0000 Subject: Add SymcML server definition --- tools/sdptool.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index f3bd6432..562c75a6 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2896,7 +2896,10 @@ static int add_sr1(sdp_session_t *session, svc_info_t *si) return 0; } -static unsigned char syncml_uuid[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, +static unsigned char syncmls_uuid[] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 }; + +static unsigned char syncmlc_uuid[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 }; static int add_syncml(sdp_session_t *session, svc_info_t *si) @@ -2913,7 +2916,7 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(&record, root); - sdp_uuid128_create(&svclass_uuid, (void *) syncml_uuid); + sdp_uuid128_create(&svclass_uuid, (void *) syncmlc_uuid); svclass = sdp_list_append(NULL, &svclass_uuid); sdp_set_service_classes(&record, svclass); @@ -3314,7 +3317,8 @@ struct { { "SEMCHLA", 0x8e771301, add_semchla }, { "SR1", 0, add_sr1, sr1_uuid }, - { "SYNCML", 0, add_syncml, syncml_uuid }, + { "SYNCML", 0, add_syncml, syncmlc_uuid }, + { "SYNCMLSERV", 0, NULL, syncmls_uuid }, { "ACTIVESYNC", 0, add_activesync, async_uuid }, { "HOTSYNC", 0, add_hotsync, hotsync_uuid }, { "PALMOS", 0, add_palmos, palmos_uuid }, -- cgit From b42e7c67689f7c93e2eb7a54dd677a5c5e23df59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 1 Aug 2007 08:07:42 +0000 Subject: Add commands for Simple Pairing --- tools/hciconfig.8 | 9 ++++++++ tools/hciconfig.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/hcisecfilter.c | 13 +++++++---- 3 files changed, 82 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index da39a40c..fc8d69bf 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -183,6 +183,12 @@ With no prints out the current AFH mode. Otherwise, sets AFH mode to .IR mode . .TP +.BI sspmode " [mode]" +With no +.IR mode , +prints out the current Simple Pairing mode. Otherwise, sets Simple Pairing mode to +.IR mode . +.TP \fBaclmtu\fP \fImtu\fP:\fIpkt\fP Sets ACL MTU to to @@ -208,6 +214,9 @@ This command deletes the stored link key for .I bdaddr from the device. .TP +.BI oobdata +Display local OOB data. +.TP .BI commands Display supported commands. .TP diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 430cd0c3..998b6145 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -885,6 +885,36 @@ static void cmd_delkey(int ctl, int hdev, char *opt) hci_close_dev(dd); } +static void cmd_oob_data(int ctl, int hdev, char *opt) +{ + uint8_t hash[16], randomizer[16]; + int i, dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_oob_data(dd, hash, randomizer, 1000) < 0) { + fprintf(stderr, "Can't read local OOB data on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf("\tOOB Hash: "); + for (i = 0; i < 16; i++) + printf(" %02x", hash[i]); + printf("\n\tRandomizer:"); + for (i = 0; i < 16; i++) + printf(" %02x", randomizer[i]); + printf("\n"); + + hci_close_dev(dd); +} + static void cmd_commands(int ctl, int hdev, char *opt) { uint8_t cmds[64]; @@ -1365,6 +1395,39 @@ static void cmd_afh_mode(int ctl, int hdev, char *opt) } } +static void cmd_ssp_mode(int ctl, int hdev, char *opt) +{ + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (opt) { + uint8_t mode = atoi(opt); + + if (hci_write_simple_pairing_mode(dd, mode, 2000) < 0) { + fprintf(stderr, "Can't set Simple Pairing mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint8_t mode; + + if (hci_read_simple_pairing_mode(dd, &mode, 1000) < 0) { + fprintf(stderr, "Can't read Simple Pairing mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf("\tSimple Pairing mode: %s\n", mode == 1 ? "Enabled" : "Disabled"); + } +} + static void print_rev_ericsson(int dd) { struct hci_request rq; @@ -1571,10 +1634,12 @@ static struct { { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, { "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" }, + { "sspmode", cmd_ssp_mode, "[mode]", "Get/Set Simple Pairing Mode" }, { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, { "putkey", cmd_putkey, "", "Store link key on the device" }, { "delkey", cmd_delkey, "", "Delete link key from the device" }, + { "oobdata", cmd_oob_data, 0, "Display local OOB data" }, { "commands", cmd_commands, 0, "Display supported commands" }, { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 6a4f897b..5bab6389 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -81,7 +81,7 @@ int main(void) hci_set_bit(OCF_READ_CLOCK_OFFSET, ocf_mask); hci_set_bit(OCF_READ_LMP_HANDLE, ocf_mask); - printf("OGF_LINK_CTL: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", + printf("OGF_LINK_CTL: { 0x%08x, 0x%08x, 0x%08x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_LINK_POLICY */ @@ -90,7 +90,7 @@ int main(void) hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); hci_set_bit(OCF_READ_DEFAULT_LINK_POLICY, ocf_mask); - printf("OGF_LINK_POLICY: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", + printf("OGF_LINK_POLICY: { 0x%08x, 0x%08x, 0x%08x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_HOST_CTL */ @@ -120,8 +120,11 @@ int main(void) hci_set_bit(OCF_READ_PAGE_SCAN_TYPE, ocf_mask); hci_set_bit(OCF_READ_AFH_MODE, ocf_mask); hci_set_bit(OCF_READ_EXT_INQUIRY_RESPONSE, ocf_mask); + hci_set_bit(OCF_READ_SIMPLE_PAIRING_MODE, ocf_mask); + hci_set_bit(OCF_READ_INQUIRY_TRANSMIT_POWER_LEVEL, ocf_mask); + hci_set_bit(OCF_READ_DEFAULT_ERROR_DATA_REPORTING, ocf_mask); - printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", + printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%08x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_INFO_PARAM */ @@ -134,7 +137,7 @@ int main(void) hci_set_bit(OCF_READ_COUNTRY_CODE, ocf_mask); hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); - printf("OGF_INFO_PARAM: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", + printf("OGF_INFO_PARAM: { 0x%08x, 0x%08x, 0x%08x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_STATUS_PARAM */ @@ -145,7 +148,7 @@ int main(void) hci_set_bit(OCF_READ_AFH_MAP, ocf_mask); hci_set_bit(OCF_READ_CLOCK, ocf_mask); - printf("OGF_STATUS_PARAM: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", + printf("OGF_STATUS_PARAM: { 0x%08x, 0x%08x, 0x%08x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); return 0; -- cgit From c3f0924a5b4792616a2caf3acce6a4193a986d88 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 5 Aug 2007 14:25:03 +0000 Subject: Add build ids for Unified 22d firmwares --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index cd141a64..51b1081e 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -353,6 +353,8 @@ static struct { { 4363, "Unified 22c" }, { 4373, "Unified 22c" }, { 4374, "Unified 22c" }, + { 4532, "Unified 22d" }, + { 4533, "Unified 22d" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, -- cgit From 8c05580df1f807e7e24f44904d6730282633ea2b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 8 Aug 2007 16:21:13 +0000 Subject: Don't change EIR data when setting name --- tools/hciconfig.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 998b6145..bf98a74d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -433,36 +433,11 @@ static void cmd_name(int ctl, int hdev, char *opt) } if (opt) { - uint8_t fec = 0, data[240]; - int len, eir = 0; - - if (di.features[6] & LMP_EXT_INQ) { - if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) == 0) - eir = 1; - } - - memset(data, 0, sizeof(data)); - len = strlen(opt); - if (len > 48) { - len = 48; - data[1] = 0x08; - } else - data[1] = 0x09; - data[0] = len + 1; - memcpy(data + 2, opt, len); - if (hci_write_local_name(dd, opt, 2000) < 0) { fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } - - if (eir) { - if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { - fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n", - hdev, strerror(errno), errno); - } - } } else { char name[249]; int i; -- cgit From 59badd8391ce0bcd940abed5a750e0192eef9ed8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 26 Aug 2007 21:59:50 +0000 Subject: Fix command bit calculation --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index bf98a74d..51fd24af 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -917,7 +917,7 @@ static void cmd_commands(int ctl, int hdev, char *opt) printf("%s Octet %-2d = 0x%02x (Bit", i ? "\t\t ": "\tCommands:", i, cmds[i]); for (n = 0; n < 8; n++) - if (hci_test_bit(n, &cmds[i])) + if (cmds[i] & (1 << n)) printf(" %d", n); printf(")\n"); } -- cgit From 8c491ff7a6b47984f238ad76fbad7f842ef45eab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 31 Aug 2007 19:29:44 +0000 Subject: Decode more EIR elements --- tools/hciconfig.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 51fd24af..19e1334f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1069,6 +1069,22 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) len = *ptr++; type = *ptr++; switch (type) { + case 0x01: + printf("\tFlags:"); + for (i = 0; i < len - 1; i++) + printf(" 0x%2.2x", *((uint8_t *) (ptr + i))); + printf("\n"); + break; + case 0x02: + case 0x03: + printf("\t%s service classes:", + type == 0x02 ? "Shortened" : "Complete"); + for (i = 0; i < (len - 1) / 2; i++) { + uint16_t val = btohs(bt_get_unaligned((uint16_t *) (ptr + (i * 2)))); + printf(" 0x%4.4x", val); + } + printf("\n"); + break; case 0x08: case 0x09: str = malloc(len); @@ -1078,12 +1094,14 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) if ((unsigned char) str[i] < 32 || str[i] == 127) str[i] = '.'; } - printf("\t%s local name: \'%s\'\n", type == 0x08 ? "Shortened" : "Complete", str); free(str); } break; + case 0x0a: + printf("\tTX power level: %d\n", *((uint8_t *) ptr)); + break; default: printf("\tUnknown type 0x%02x with %d bytes data\n", type, len - 1); -- cgit From c05d3bbdd321efc2d92ad99488ad8c54af43d61b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 Sep 2007 19:38:57 +0000 Subject: Add utility for Babel devices --- tools/Makefile.am | 20 +++++- tools/dfubabel.1 | 38 ++++++++++ tools/dfubabel.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 tools/dfubabel.1 create mode 100644 tools/dfubabel.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 880036ea..2e5ecd68 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -31,9 +31,17 @@ dfutool_programs = dfutool_manfiles = endif +if DFUBABEL +dfubabel_programs = dfubabel +dfubabel_manfiles = dfubabel.1 +else +dfubabel_programs = +dfubabel_manfiles = +endif + sbin_PROGRAMS = hciattach hciconfig $(bccmd_programs) $(avctrl_programs) $(hid2hci_programs) -bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) +bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) $(dfubabel_programs) noinst_PROGRAMS = hcisecfilter ppporc @@ -76,16 +84,22 @@ dfutool_SOURCES = dfutool.c dfu.h dfu.c dfutool_LDADD = @USB_LIBS@ endif +if DFUBABEL +dfubabel_SOURCES = dfubabel.c +dfubabel_LDADD = @USB_LIBS@ +endif + AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common if MANPAGES man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - $(bccmd_manfiles) $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) + $(bccmd_manfiles) $(avctrl_manfiles) $(hid2hci_manfiles) \ + $(dfutool_manfiles) $(dfubabel_manfiles) endif EXTRA_DIST = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - bccmd.8 avctrl.8 hid2hci.8 dfutool.1 example.psr + bccmd.8 avctrl.8 hid2hci.8 dfutool.1 dfubabel.1 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/dfubabel.1 b/tools/dfubabel.1 new file mode 100644 index 00000000..5e0f805f --- /dev/null +++ b/tools/dfubabel.1 @@ -0,0 +1,38 @@ +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH DFUBABEL 8 "JUNE 6, 2005" "" "" + +.SH NAME +dfubabel \- Babel DFU mode switching utility +.SH SYNOPSIS +.BR "dfubabel +[ +.I options +] +.SH DESCRIPTION +.B dfubabel +is used to switch Babel devices into DFU mode. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible options. +.TP +.BI -q +Don't display any messages. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/dfubabel.c b/tools/dfubabel.c new file mode 100644 index 00000000..ffcded90 --- /dev/null +++ b/tools/dfubabel.c @@ -0,0 +1,211 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +struct device_info; + +struct device_id { + uint16_t vendor; + uint16_t product; + int (*func)(struct device_info *dev, int argc, char *argv[]); +}; + +struct device_info { + struct usb_device *dev; + struct device_id *id; +}; + +static int switch_babel(struct device_info *devinfo, int argc, char *argv[]) +{ + char buf[3]; + struct usb_dev_handle *udev; + int err; + + memset(buf, 0, sizeof(buf)); + + buf[0] = 0x00; + buf[1] = 0x06; + buf[2] = 0x00; + + udev = usb_open(devinfo->dev); + if (!udev) + return -errno; + + if (usb_claim_interface(udev, 0) < 0) { + err = -errno; + usb_close(udev); + return err; + } + + err = usb_bulk_write(udev, 0x02, buf, sizeof(buf), 10000); + + if (err == 0) { + err = -1; + errno = EALREADY; + } else { + if (errno == ETIMEDOUT) + err = 0; + } + + usb_release_interface(udev, 0); + usb_close(udev); + + return err; +} + +static struct device_id device_list[] = { + { 0x0a12, 0x0042, switch_babel }, + { -1 } +}; + +static struct device_id *match_device(uint16_t vendor, uint16_t product) +{ + int i; + + for (i = 0; device_list[i].func; i++) { + if (vendor == device_list[i].vendor && + product == device_list[i].product) + return &device_list[i]; + } + + return NULL; +} + +static int find_devices(struct device_info *devinfo, size_t size) +{ + struct usb_bus *bus; + struct usb_device *dev; + struct device_id *id; + int count = 0; + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) { + id = match_device(dev->descriptor.idVendor, + dev->descriptor.idProduct); + if (!id) + continue; + + if (count < size) { + devinfo[count].dev = dev; + devinfo[count].id = id; + count++; + } + } + + return count; +} + +static void usage(void) +{ + printf("dfubabel - Babel DFU mode switching utility\n\n"); + + printf("Usage:\n" + "\tdfubabel [options]\n" + "\n"); + + printf("Options:\n" + "\t-h, --help Display help\n" + "\t-q, --quiet Don't display any messages\n" + "\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "quiet", 0, 0, 'q' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct device_info dev[16]; + int i, opt, num, quiet = 0; + + while ((opt = getopt_long(argc, argv, "+qh", main_options, NULL)) != -1) { + switch (opt) { + case 'q': + quiet = 1; + break; + case 'h': + usage(); + exit(0); + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + usb_init(); + + num = find_devices(dev, sizeof(dev) / sizeof(dev[0])); + if (num <= 0) { + if (!quiet) + fprintf(stderr, "No Babel devices found\n"); + exit(1); + } + + for (i = 0; i < num; i++) { + struct device_id *id = dev[i].id; + int err; + + if (!quiet) + printf("Switching device %04x:%04x ", + id->vendor, id->product); + fflush(stdout); + + err = id->func(&dev[i], argc, argv); + if (err < 0) { + if (!quiet) + printf("failed (%s)\n", strerror(-err)); + } else { + if (!quiet) + printf("was successful\n"); + } + } + + return 0; +} -- cgit From d5c3190e0a1e608eeaf6c13ac12071ce288d78a1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Sep 2007 01:11:32 +0000 Subject: Add support for Logitech diNovo Edge dongle --- tools/hid2hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index f4409c20..2f1e3a95 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -227,6 +227,8 @@ static struct device_id device_list[] = { { HCI, 0x046d, 0xc70b, switch_logitech }, /* Logitech diNovo Laser keyboard */ { HCI, 0x046d, 0xc70c, switch_logitech }, /* Logitech diNovo Laser mouse */ { HCI, 0x046d, 0xc70e, switch_logitech }, /* Logitech diNovo keyboard */ + { HCI, 0x046d, 0xc713, switch_logitech }, /* Logitech diNovo Edge */ + { HCI, 0x046d, 0xc714, switch_logitech }, /* Logitech diNovo Edge */ { -1 } }; -- cgit From 7d7658ad2fcd296440916cd26cd8182a8dc0a7c3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 10 Sep 2007 18:47:30 +0000 Subject: Show connection link type correctly --- tools/hcitool.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index 49cc6fe6..c9d3dbd6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -63,6 +63,20 @@ static int dev_info(int s, int dev_id, long arg) return 0; } +static char *type2str(uint8_t type) +{ + switch (type) { + case SCO_LINK: + return "SCO"; + case ACL_LINK: + return "ACL"; + case ESCO_LINK: + return "eSCO"; + default: + return "Unknown"; + } +} + static int conn_list(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; @@ -90,8 +104,7 @@ static int conn_list(int s, int dev_id, long arg) char addr[18]; ba2str(&ci->bdaddr, addr); printf("\t%s %s %s handle %d state %d lm %s\n", - ci->out ? "<" : ">", - ci->type == ACL_LINK ? "ACL" : "SCO", + ci->out ? "<" : ">", type2str(ci->type), addr, ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } -- cgit From 6efce5841c487a4fbbc0aa324cbcdd1d58f40077 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Sep 2007 11:25:34 +0000 Subject: Add refresh option to re-request device names --- tools/hcitool.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.c b/tools/hcitool.c index c9d3dbd6..ec043d6e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -484,6 +484,7 @@ static struct option scan_options[] = { { "numrsp", 1, 0, 'n' }, { "iac", 1, 0, 'i' }, { "flush", 0, 0, 'f' }, + { "refresh", 0, 0, 'r' }, { "class", 0, 0, 'C' }, { "info", 0, 0, 'I' }, { "oui", 0, 0, 'O' }, @@ -494,7 +495,7 @@ static struct option scan_options[] = { static char *scan_help = "Usage:\n" - "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui]\n"; + "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui] [--refresh]\n"; static void cmd_scan(int dev_id, int argc, char **argv) { @@ -507,7 +508,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; - int extcls = 0, extinf = 0, extoui = 0; + int refresh = 0, extcls = 0, extinf = 0, extoui = 0; int i, n, l, opt, dd, cc, nc; length = 8; /* ~10 seconds */ @@ -543,6 +544,10 @@ static void cmd_scan(int dev_id, int argc, char **argv) flags |= IREQ_CACHE_FLUSH; break; + case 'r': + refresh = 1; + break; + case 'C': extcls = 1; break; @@ -598,12 +603,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("\n"); for (i = 0; i < num_rsp; i++) { - memset(name, 0, sizeof(name)); - tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr); - if (tmp) { - strncpy(name, tmp, 249); - free(tmp); - nc = 1; + if (!refresh) { + memset(name, 0, sizeof(name)); + tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr); + if (tmp) { + strncpy(name, tmp, 249); + free(tmp); + nc = 1; + } else + nc = 0; } else nc = 0; -- cgit From 361ed93686add66120850c8640735a048001b7e1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Oct 2007 11:25:06 +0000 Subject: Add support for inquiry transmit power level --- tools/hciconfig.8 | 7 +++++++ tools/hciconfig.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'tools') diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index fc8d69bf..f03b1c16 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -132,6 +132,13 @@ With no prints the current IAC setting. Otherwise, sets the IAC to .IR iac . .TP +.BI inqtpl " [level]" +With no +.IR level , +prints out the current inquiry transmit power level. Otherwise, sets +inquiry transmit power level to +.IR level . +.TP .BI inqmode " [mode]" With no .IR mode , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 19e1334f..ab20a4c0 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -966,6 +966,41 @@ static void cmd_version(int ctl, int hdev, char *opt) hci_close_dev(dd); } +static void cmd_inq_tpl(int ctl, int hdev, char *opt) +{ + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (opt) { + int8_t level = atoi(opt); + + if (hci_write_inquiry_transmit_power_level(dd, level, 2000) < 0) { + fprintf(stderr, "Can't set inquiry transmit power level on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + int8_t level; + + if (hci_read_inquiry_transmit_power_level(dd, &level, 1000) < 0) { + fprintf(stderr, "Can't read inquiry transmit power level on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf("\tInquiry transmit power level: %d\n", level); + } + + hci_close_dev(dd); +} + static void cmd_inq_mode(int ctl, int hdev, char *opt) { int dd; @@ -1620,6 +1655,7 @@ static struct { { "class", cmd_class, "[class]", "Get/Set class of device" }, { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, + { "inqtpl", cmd_inq_tpl, "[level]", "Get/Set inquiry transmit power level" }, { "inqmode", cmd_inq_mode, "[mode]", "Get/Set inquiry mode" }, { "inqdata", cmd_inq_data, "[data]", "Get/Set inquiry data" }, { "inqtype", cmd_inq_type, "[type]", "Get/Set inquiry scan type" }, -- cgit From bb8dcb8334611f47697796b4abb1972cb6b8cfec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Oct 2007 16:48:10 +0000 Subject: Support higher baud rates for Ericcson based chips --- tools/hciattach.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index ece80ce1..2f9b7715 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -120,6 +120,16 @@ static int uart_speed(int s) return B1152000; case 1500000: return B1500000; + case 2000000: + return B2000000; + case 2500000: + return B2500000; + case 3000000: + return B3000000; + case 3500000: + return B3500000; + case 4000000: + return B4000000; default: return B57600; } @@ -206,9 +216,19 @@ static int ericsson(int fd, struct uart_t *u, struct termios *ti) case 921600: cmd[4] = 0x20; break; + case 2000000: + cmd[4] = 0x25; + break; + case 3000000: + cmd[4] = 0x27; + break; + case 4000000: + cmd[4] = 0x2B; + break; default: cmd[4] = 0x03; u->speed = 57600; + fprintf(stderr, "Invalid speed requested, using %d bps instead\n", u->speed); break; } -- cgit From 2d49c5ba27bd59638a3fb6e357beae609d4eb27a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Oct 2007 16:49:23 +0000 Subject: Share code for Ericsson and ST chips --- tools/hciattach.c | 52 +++++----------------------------------------------- 1 file changed, 5 insertions(+), 47 deletions(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 2f9b7715..781ccd06 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -852,56 +852,14 @@ extern int stlc2500_init(int fd, bdaddr_t *bdaddr); static int stlc2500(int fd, struct uart_t *u, struct termios *ti) { bdaddr_t bdaddr; - char cmd[5]; unsigned char resp[10]; int n; + int rvalue; - /* STLC2500 Set Baud Rate stuff */ - /* We should set the baud rate first, so the firmware download */ - /* goes much faster */ - - /* STLC2500 Seems to support the Ericsson set baud rate stuff */ - /* It should also support the ST Set Baud Rate command */ - /* (as in st() function above, but those commands never succeed */ - cmd[0] = HCI_COMMAND_PKT; - cmd[1] = 0x09; - cmd[2] = 0xfc; - cmd[3] = 0x01; - - switch (u->speed) { - case 57600: - cmd[4] = 0x03; - break; - case 115200: - cmd[4] = 0x02; - break; - case 230400: - cmd[4] = 0x01; - break; - case 460800: - cmd[4] = 0x00; - break; - case 921600: - cmd[4] = 0x20; - break; - default: - cmd[4] = 0x02; - u->speed = 115200; - break; - } - -#ifdef STLC2500_DEBUG - fprintf(stderr, "Sending Baud Rate %02x\n", cmd[4]); -#endif - /* Send initialization command */ - if (write(fd, cmd, 5) != 5) { - perror("Failed to write init command"); - return -1; - } - - /* Need to wait here to give a chance for the device to set baud */ - /* But no more than 0.5 seconds */ - usleep(200000); + /* STLC2500 has an ericsson core */ + rvalue = ericsson(fd, u, ti); + if (rvalue != 0) + return rvalue; #ifdef STLC2500_DEBUG fprintf(stderr, "Setting speed\n"); -- cgit From ebc48fedda3e9220862c53e2d9afe8b50f14c1a3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Oct 2007 16:51:17 +0000 Subject: Change init sequence and add comments --- tools/hciattach_st.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index 47df4fe1..f2be66f5 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -195,40 +195,36 @@ int stlc2500_init(int dd, bdaddr_t *bdaddr) uint16_t version; int len; - len = do_command(dd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf)); + /* Hci_Cmd_Ericsson_Read_Revision_Information */ + len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf)); if (len < 0) return -1; - version = buf[2] << 8 | buf[1]; - - if (load_file(dd, version, ".ptc") < 0) - return -1; + printf("%s\n", buf); - len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); + /* HCI_Read_Local_Version_Information */ + len = do_command(dd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf)); if (len < 0) return -1; - if (load_file(dd, buf[2] << 8 | buf[1], ".ssf") < 0) - return -1; + version = buf[2] << 8 | buf[1]; - len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); - if (len < 0) + if (load_file(dd, version, ".ptc") < 0) return -1; - len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf)); - if (len < 0) + if (load_file(dd, buf[2] << 8 | buf[1], ".ssf") < 0) return -1; - printf("%s\n", buf); - cmd[0] = 0xfe; cmd[1] = 0x06; bacpy((bdaddr_t *) (cmd + 2), bdaddr); + /* Hci_Cmd_ST_Store_In_NVDS */ len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf)); if (len < 0) return -1; + /* HCI_Reset : applies parameters*/ len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf)); if (len < 0) return -1; -- cgit From bc3ec576543eac39562035172a17e7d5ad734f04 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Oct 2007 16:52:48 +0000 Subject: Make firmware and paramter loading optional --- tools/hciattach_st.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index f2be66f5..13c68278 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -122,7 +122,7 @@ static int load_file(int dd, uint16_t version, const char *suffix) unsigned char cmd[256]; unsigned char buf[256]; uint8_t seqnum = 0; - int fd, size, len; + int fd, size, len, found_fw_file; memset(filename, 0, sizeof(filename)); @@ -138,6 +138,7 @@ static int load_file(int dd, uint16_t version, const char *suffix) return -errno; } + found_fw_file = 0; while (1) { d = readdir(dir); if (!d) @@ -152,10 +153,14 @@ static int load_file(int dd, uint16_t version, const char *suffix) snprintf(filename, sizeof(filename), "%s/%s", pathname, d->d_name); + found_fw_file = 1; } closedir(dir); + if (!found_fw_file) + return -ENOENT; + printf("Loading file %s\n", filename); fd = open(filename, O_RDONLY); @@ -194,6 +199,7 @@ int stlc2500_init(int dd, bdaddr_t *bdaddr) unsigned char buf[254]; uint16_t version; int len; + int err; /* Hci_Cmd_Ericsson_Read_Revision_Information */ len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf)); @@ -209,11 +215,21 @@ int stlc2500_init(int dd, bdaddr_t *bdaddr) version = buf[2] << 8 | buf[1]; - if (load_file(dd, version, ".ptc") < 0) - return -1; + err = load_file(dd, version, ".ptc"); + if (err < 0) { + if (err == -ENOENT) + fprintf(stderr, "No ROM patch file loaded.\n"); + else + return -1; + } - if (load_file(dd, buf[2] << 8 | buf[1], ".ssf") < 0) - return -1; + err = load_file(dd, buf[2] << 8 | buf[1], ".ssf"); + if (err < 0) { + if (err == -ENOENT) + fprintf(stderr, "No static settings file loaded.\n"); + else + return -1; + } cmd[0] = 0xfe; cmd[1] = 0x06; -- cgit From 38f7e247cfe425a3e7b01aa24784b10231998125 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 10 Oct 2007 13:50:40 +0000 Subject: Add two more record handle ranges from Sony Ericsson headsets --- tools/sdptool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 562c75a6..fc4b1f7b 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -3852,7 +3852,9 @@ static char *records_help = static int cmd_records(int argc, char **argv) { struct search_context context; - uint32_t base[] = { 0x10000, 0x1002e, 0x110b, 0x90000, 0x2008000, 0x4000000, 0x100000, 0x1000000 }; + uint32_t base[] = { 0x10000, 0x10300, 0x10500, + 0x1002e, 0x110b, 0x90000, 0x2008000, + 0x4000000, 0x100000, 0x1000000 }; bdaddr_t bdaddr; int i, n, opt, err = 0, num = 32; -- cgit From 312471773c71bfc1e64d9d6e8a71e933d3b9cc98 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 12 Nov 2007 01:19:18 +0000 Subject: Add record handle range from Apple iPhone --- tools/sdptool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index fc4b1f7b..35f75c48 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -3853,8 +3853,8 @@ static int cmd_records(int argc, char **argv) { struct search_context context; uint32_t base[] = { 0x10000, 0x10300, 0x10500, - 0x1002e, 0x110b, 0x90000, 0x2008000, - 0x4000000, 0x100000, 0x1000000 }; + 0x1002e, 0x110b, 0x90000, 0x2008000, + 0x4000000, 0x100000, 0x1000000, 0x4f491100 }; bdaddr_t bdaddr; int i, n, opt, err = 0, num = 32; -- cgit From ae100c4c1395e1b306d2e91b5fed85f7b8d6dfbf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 1 Dec 2007 17:00:13 +0000 Subject: Add build ids for Unified 23c firmwares --- tools/csr.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'tools') diff --git a/tools/csr.c b/tools/csr.c index 51b1081e..5a381f94 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -355,6 +355,20 @@ static struct { { 4374, "Unified 22c" }, { 4532, "Unified 22d" }, { 4533, "Unified 22d" }, + { 4698, "Unified 23c" }, + { 4839, "Unified 23c" }, + { 4841, "Unified 23c" }, + { 4866, "Unified 23c" }, + { 4867, "Unified 23c" }, + { 4868, "Unified 23c" }, + { 4869, "Unified 23c" }, + { 4870, "Unified 23c" }, + { 4871, "Unified 23c" }, + { 4872, "Unified 23c" }, + { 4874, "Unified 23c" }, + { 4875, "Unified 23c" }, + { 4876, "Unified 23c" }, + { 4877, "Unified 23c" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, -- cgit From 720c7262b6d88d296d15de907cd21ad3b30d9aa0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Dec 2007 17:47:22 +0000 Subject: Add fix for Logitech HID proxy switching --- tools/hid2hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 2f1e3a95..327299ed 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -138,7 +138,7 @@ static int send_report(int fd, const char *buf, size_t size) uref.field_index = 0; uref.usage_index = i; uref.usage_code = 0xff000001; - uref.value = buf[i]; + uref.value = buf[i] & 0x000000ff; err = ioctl(fd, HIDIOCSUSAGE, &uref); if (err < 0) return err; -- cgit From 207ed32b02954e52bd162f270db60b8e37d58442 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Dec 2007 20:41:29 +0000 Subject: Add definitions for MDP --- tools/sdptool.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 35f75c48..ac17f9ad 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -322,6 +322,9 @@ static struct uuid_def uuid16_names[] = { { 0x1303, "VideoSource", NULL, 0 }, { 0x1304, "VideoSink", NULL, 0 }, { 0x1305, "VideoDistribution", NULL, 0 }, + { 0x1400, "MDP", NULL, 0 }, + { 0x1401, "MDPSource", NULL, 0 }, + { 0x1402, "MDPSink", NULL, 0 }, { 0x2112, "AppleAgent", NULL, 0 }, }; -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- tools/avctrl.c | 2 +- tools/bccmd.c | 2 +- tools/ciptool.c | 2 +- tools/csr.c | 2 +- tools/csr.h | 2 +- tools/csr_3wire.c | 2 +- tools/csr_bcsp.c | 2 +- tools/csr_h4.c | 2 +- tools/csr_hci.c | 2 +- tools/csr_usb.c | 2 +- tools/dfu.c | 2 +- tools/dfu.h | 2 +- tools/dfubabel.c | 2 +- tools/dfutool.c | 2 +- tools/hciattach.c | 2 +- tools/hciattach_st.c | 2 +- tools/hciconfig.c | 2 +- tools/hcisecfilter.c | 2 +- tools/hcitool.c | 2 +- tools/hid2hci.c | 2 +- tools/l2ping.c | 2 +- tools/ppporc.c | 2 +- tools/sdptool.c | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/avctrl.c b/tools/avctrl.c index a7565c36..61d0180d 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/bccmd.c b/tools/bccmd.c index efce49d8..95cb37bb 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/ciptool.c b/tools/ciptool.c index e5661012..7d95953f 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr.c b/tools/csr.c index 5a381f94..7895363c 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2007 Marcel Holtmann + * Copyright (C) 2003-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr.h b/tools/csr.h index 5d0b989a..5df3cb5a 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2007 Marcel Holtmann + * Copyright (C) 2003-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_3wire.c b/tools/csr_3wire.c index afcc5f50..ed2064cd 100644 --- a/tools/csr_3wire.c +++ b/tools/csr_3wire.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 26887414..0dc334cb 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_h4.c b/tools/csr_h4.c index d31de396..27ea3e3c 100644 --- a/tools/csr_h4.c +++ b/tools/csr_h4.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_hci.c b/tools/csr_hci.c index c9e02341..454cbfb2 100644 --- a/tools/csr_hci.c +++ b/tools/csr_hci.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_usb.c b/tools/csr_usb.c index a7966957..b7703dcf 100644 --- a/tools/csr_usb.c +++ b/tools/csr_usb.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfu.c b/tools/dfu.c index 6863751b..069cbb89 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2007 Marcel Holtmann + * Copyright (C) 2003-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfu.h b/tools/dfu.h index d2ba2fbf..39d25250 100644 --- a/tools/dfu.h +++ b/tools/dfu.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2007 Marcel Holtmann + * Copyright (C) 2003-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfubabel.c b/tools/dfubabel.c index ffcded90..78dfa9f9 100644 --- a/tools/dfubabel.c +++ b/tools/dfubabel.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfutool.c b/tools/dfutool.c index 3d38f8ef..7a8c8dee 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2007 Marcel Holtmann + * Copyright (C) 2003-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciattach.c b/tools/hciattach.c index 781ccd06..00f5cc14 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciattach_st.c b/tools/hciattach_st.c index 13c68278..2c7d7438 100644 --- a/tools/hciattach_st.c +++ b/tools/hciattach_st.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2005-2007 Marcel Holtmann + * Copyright (C) 2005-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ab20a4c0..64c30b11 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 5bab6389..81a2fca4 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hcitool.c b/tools/hcitool.c index ec043d6e..60e196be 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 327299ed..706e1763 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2007 Marcel Holtmann + * Copyright (C) 2003-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/l2ping.c b/tools/l2ping.c index 6b1ae477..1be911ae 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/ppporc.c b/tools/ppporc.c index cf9a10b4..2d8b034d 100644 --- a/tools/ppporc.c +++ b/tools/ppporc.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/sdptool.c b/tools/sdptool.c index ac17f9ad..19882396 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * Copyright (C) 2002-2003 Jean Tourrilhes * -- cgit From d842176ec218c4417321b22a87fa33d037c84795 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 10 Feb 2008 05:27:22 +0000 Subject: Add option for installing generic tools --- tools/Makefile.am | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 2e5ecd68..5d677380 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,12 @@ +if TOOLS +tools_programs = hcitool l2ping sdptool ciptool +tools_manfiles = hcitool.1 l2ping.1 sdptool.1 ciptool.1 +else +tools_programs = +tools_manfiles = +endif + if BCCMD bccmd_programs = bccmd bccmd_manfiles = bccmd.8 @@ -41,7 +49,7 @@ endif sbin_PROGRAMS = hciattach hciconfig $(bccmd_programs) $(avctrl_programs) $(hid2hci_programs) -bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) $(dfubabel_programs) +bin_PROGRAMS = $(tools_programs) $(dfutool_programs) $(dfubabel_programs) noinst_PROGRAMS = hcisecfilter ppporc @@ -51,6 +59,7 @@ hciattach_LDADD = @BLUEZ_LIBS@ hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a +if TOOLS hcitool_SOURCES = hcitool.c hcitool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a @@ -59,6 +68,7 @@ l2ping_LDADD = @BLUEZ_LIBS@ sdptool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a ciptool_LDADD = @BLUEZ_LIBS@ +endif ppporc_LDADD = @BLUEZ_LIBS@ @@ -94,7 +104,7 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common if MANPAGES -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ +man_MANS = hciattach.8 hciconfig.8 $(tools_manfiles) \ $(bccmd_manfiles) $(avctrl_manfiles) $(hid2hci_manfiles) \ $(dfutool_manfiles) $(dfubabel_manfiles) endif -- cgit From 042cbdb0ffbd503738c294ce43c3f1691980633e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 13 Feb 2008 11:12:51 +0000 Subject: Add ifdefs around some baud rate definitions --- tools/hciattach.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 00f5cc14..36f3c72b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -122,14 +122,22 @@ static int uart_speed(int s) return B1500000; case 2000000: return B2000000; +#ifdef B2500000 case 2500000: return B2500000; +#endif +#ifdef B3000000 case 3000000: return B3000000; +#endif +#ifdef B3500000 case 3500000: return B3500000; +#endif +#ifdef B4000000 case 4000000: return B4000000; +#endif default: return B57600; } -- cgit From 79dd6fbaf1115222c723b4b781ad44b07486b00d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 20 Mar 2008 13:45:18 +0000 Subject: Fix wrong error message --- tools/hid2hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 706e1763..124829fb 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -332,7 +332,7 @@ int main(int argc, char *argv[]) if (num <= 0) { if (!quiet) fprintf(stderr, "No devices in %s mode found\n", - mode ? "HID" : "HCI"); + mode ? "HCI" : "HID"); exit(1); } -- cgit From 5f1075f2f9ec9c5d18f09497bd6b0f14511621ea Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 1 Apr 2008 22:57:16 +0000 Subject: Introduce avinfo tool. --- tools/Makefile.am | 5 +- tools/avinfo.c | 569 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 573 insertions(+), 1 deletion(-) create mode 100644 tools/avinfo.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 5d677380..a529a6c5 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -51,7 +51,7 @@ sbin_PROGRAMS = hciattach hciconfig $(bccmd_programs) $(avctrl_programs) $(hid2h bin_PROGRAMS = $(tools_programs) $(dfutool_programs) $(dfubabel_programs) -noinst_PROGRAMS = hcisecfilter ppporc +noinst_PROGRAMS = hcisecfilter ppporc avinfo hciattach_SOURCES = hciattach.c hciattach_st.c hciattach_LDADD = @BLUEZ_LIBS@ @@ -68,6 +68,9 @@ l2ping_LDADD = @BLUEZ_LIBS@ sdptool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a ciptool_LDADD = @BLUEZ_LIBS@ + +avinfo_SOURCES = avinfo.c +avinfo_LDADD = @BLUEZ_LIBS@ endif ppporc_LDADD = @BLUEZ_LIBS@ diff --git a/tools/avinfo.c b/tools/avinfo.c new file mode 100644 index 00000000..f639181a --- /dev/null +++ b/tools/avinfo.c @@ -0,0 +1,569 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2006-2007 Nokia Corporation + * Copyright (C) 2004-2008 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define AVDTP_PSM 25 + +/* Commands */ +#define AVDTP_DISCOVER 0x01 +#define AVDTP_GET_CAPABILITIES 0x02 + +#define AVDTP_PKT_TYPE_SINGLE 0x00 + +#define AVDTP_MSG_TYPE_COMMAND 0x00 + +/* SEP capability categories */ +#define AVDTP_MEDIA_TRANSPORT 0x01 +#define AVDTP_REPORTING 0x02 +#define AVDTP_RECOVERY 0x03 +#define AVDTP_CONTENT_PROTECTION 0x04 +#define AVDTP_HEADER_COMPRESSION 0x05 +#define AVDTP_MULTIPLEXING 0x06 +#define AVDTP_MEDIA_CODEC 0x07 + +/* SEP types definitions */ +#define AVDTP_SEP_TYPE_SOURCE 0x00 +#define AVDTP_SEP_TYPE_SINK 0x01 + +/* Media types definitions */ +#define AVDTP_MEDIA_TYPE_AUDIO 0x00 +#define AVDTP_MEDIA_TYPE_VIDEO 0x01 +#define AVDTP_MEDIA_TYPE_MULTIMEDIA 0x02 + +#define A2DP_CODEC_SBC 0x00 +#define A2DP_CODEC_MPEG12 0x01 +#define A2DP_CODEC_MPEG24 0x02 +#define A2DP_CODEC_ATRAC 0x03 + +#define SBC_SAMPLING_FREQ_16000 (1 << 3) +#define SBC_SAMPLING_FREQ_32000 (1 << 2) +#define SBC_SAMPLING_FREQ_44100 (1 << 1) +#define SBC_SAMPLING_FREQ_48000 1 + +#define SBC_CHANNEL_MODE_MONO (1 << 3) +#define SBC_CHANNEL_MODE_DUAL_CHANNEL (1 << 2) +#define SBC_CHANNEL_MODE_STEREO (1 << 1) +#define SBC_CHANNEL_MODE_JOINT_STEREO 1 + +#define SBC_BLOCK_LENGTH_4 (1 << 3) +#define SBC_BLOCK_LENGTH_8 (1 << 2) +#define SBC_BLOCK_LENGTH_12 (1 << 1) +#define SBC_BLOCK_LENGTH_16 1 + +#define SBC_SUBBANDS_4 (1 << 1) +#define SBC_SUBBANDS_8 1 + +#define SBC_ALLOCATION_SNR (1 << 1) +#define SBC_ALLOCATION_LOUDNESS 1 + +#define MPEG_CHANNEL_MODE_MONO (1 << 3) +#define MPEG_CHANNEL_MODE_DUAL_CHANNEL (1 << 2) +#define MPEG_CHANNEL_MODE_STEREO (1 << 1) +#define MPEG_CHANNEL_MODE_JOINT_STEREO 1 + +#define MPEG_LAYER_MP1 (1 << 2) +#define MPEG_LAYER_MP2 (1 << 1) +#define MPEG_LAYER_MP3 1 + +#define MPEG_SAMPLING_FREQ_16000 (1 << 5) +#define MPEG_SAMPLING_FREQ_22050 (1 << 4) +#define MPEG_SAMPLING_FREQ_24000 (1 << 3) +#define MPEG_SAMPLING_FREQ_32000 (1 << 2) +#define MPEG_SAMPLING_FREQ_44100 (1 << 1) +#define MPEG_SAMPLING_FREQ_48000 1 + +struct avdtp_service_capability { + uint8_t category; + uint8_t length; + uint8_t data[0]; +} __attribute__ ((packed)); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +struct avdtp_header { + uint8_t message_type:2; + uint8_t packet_type:2; + uint8_t transaction:4; + uint8_t signal_id:6; + uint8_t rfa0:2; +} __attribute__ ((packed)); + +struct seid_info { + uint8_t rfa0:1; + uint8_t inuse:1; + uint8_t seid:6; + uint8_t rfa2:3; + uint8_t type:1; + uint8_t media_type:4; +} __attribute__ ((packed)); + +struct seid_req { + struct avdtp_header header; + uint8_t rfa0:2; + uint8_t acp_seid:6; +} __attribute__ ((packed)); + +struct avdtp_media_codec_capability { + uint8_t rfa0:4; + uint8_t media_type:4; + uint8_t media_codec_type; + uint8_t data[0]; +} __attribute__ ((packed)); + +struct sbc_codec_cap { + struct avdtp_media_codec_capability cap; + uint8_t channel_mode:4; + uint8_t frequency:4; + uint8_t allocation_method:2; + uint8_t subbands:2; + uint8_t block_length:4; + uint8_t min_bitpool; + uint8_t max_bitpool; +} __attribute__ ((packed)); + +struct mpeg_codec_cap { + struct avdtp_media_codec_capability cap; + uint8_t channel_mode:4; + uint8_t crc:1; + uint8_t layer:3; + uint8_t frequency:6; + uint8_t mpf:1; + uint8_t rfa:1; + uint16_t bitrate; +} __attribute__ ((packed)); + +#elif __BYTE_ORDER == __BIG_ENDIAN + +struct avdtp_header { + uint8_t transaction:4; + uint8_t packet_type:2; + uint8_t message_type:2; + uint8_t rfa0:2; + uint8_t signal_id:6; +} __attribute__ ((packed)); + +struct seid_info { + uint8_t seid:6; + uint8_t inuse:1; + uint8_t rfa0:1; + uint8_t media_type:4; + uint8_t type:1; + uint8_t rfa2:3; +} __attribute__ ((packed)); + +struct seid_req { + struct avdtp_header header; + uint8_t acp_seid:6; + uint8_t rfa0:2; +} __attribute__ ((packed)); + +struct avdtp_media_codec_capability { + uint8_t media_type:4; + uint8_t rfa0:4; + uint8_t media_codec_type; + uint8_t data[0]; +} __attribute__ ((packed)); + +struct sbc_codec_cap { + struct avdtp_media_codec_capability cap; + uint8_t frequency:4; + uint8_t channel_mode:4; + uint8_t block_length:4; + uint8_t subbands:2; + uint8_t allocation_method:2; + uint8_t min_bitpool; + uint8_t max_bitpool; +} __attribute__ ((packed)); + +struct mpeg_codec_cap { + struct avdtp_media_codec_capability cap; + uint8_t layer:3; + uint8_t crc:1; + uint8_t channel_mode:4; + uint8_t rfa:1; + uint8_t mpf:1; + uint8_t frequency:6; + uint16_t bitrate; +} __attribute__ ((packed)); + +#else +#error "Unknown byte order" +#endif + +struct discover_resp { + struct avdtp_header header; + struct seid_info seps[0]; +} __attribute__ ((packed)); + +struct getcap_resp { + struct avdtp_header header; + uint8_t caps[0]; +} __attribute__ ((packed)); + + +static void print_mpeg12(struct mpeg_codec_cap *mpeg) +{ + printf("\tMedia Codec: MPEG12\n"); +} + +static void print_sbc(struct sbc_codec_cap *sbc) +{ + printf("\tMedia Codec: SBC\n\t\tChannel Modes: "); + + if (sbc->channel_mode & SBC_CHANNEL_MODE_MONO) + printf("Mono "); + if (sbc->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL) + printf("DualChannel "); + if (sbc->channel_mode & SBC_CHANNEL_MODE_STEREO) + printf("Stereo "); + if (sbc->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO) + printf("JointStereo"); + + printf("\n\t\tFrequencies: "); + if (sbc->frequency & SBC_SAMPLING_FREQ_16000) + printf("16Khz "); + if (sbc->frequency & SBC_SAMPLING_FREQ_32000) + printf("32Khz "); + if (sbc->frequency & SBC_SAMPLING_FREQ_44100) + printf("44.1Khz "); + if (sbc->frequency & SBC_SAMPLING_FREQ_48000) + printf("48Khz "); + + printf("\n\t\tSubbands: "); + if (sbc->allocation_method & SBC_SUBBANDS_4) + printf("4 "); + if (sbc->allocation_method & SBC_SUBBANDS_8) + printf("8"); + + printf("\n\t\tBlocks: "); + if (sbc->block_length & SBC_BLOCK_LENGTH_4) + printf("4 "); + if (sbc->block_length & SBC_BLOCK_LENGTH_8) + printf("8 "); + if (sbc->block_length & SBC_BLOCK_LENGTH_12) + printf("12 "); + if (sbc->block_length & SBC_BLOCK_LENGTH_16) + printf("16 "); + + printf("\n\t\tBitpool Range: %d-%d\n", sbc->min_bitpool, sbc->max_bitpool); +} + +static void print_media_codec(struct avdtp_media_codec_capability *cap) +{ + switch (cap->media_codec_type) { + case A2DP_CODEC_SBC: + print_sbc((void *) cap); + break; + + case A2DP_CODEC_MPEG12: + print_mpeg12((void *) cap); + break; + + default: + printf("\tMedia Codec: Unknown\n"); + } +} + +static void print_caps(void *data, int size) +{ + int processed; + + for (processed = 0; processed + 2 < size;) { + struct avdtp_service_capability *cap; + + cap = data; + + if (processed + 2 + cap->length > size) { + printf("Invalid capability data in getcap resp\n"); + break; + } + + switch (cap->category) { + case AVDTP_MEDIA_TRANSPORT: + case AVDTP_REPORTING: + case AVDTP_RECOVERY: + case AVDTP_CONTENT_PROTECTION: + case AVDTP_MULTIPLEXING: + /* FIXME: Add proper functions */ + break; + case AVDTP_MEDIA_CODEC: + print_media_codec((void *) cap->data); + break; + } + processed += 2 + cap->length; + data += 2 + cap->length; + } +} + +static void init_request(struct avdtp_header *header, int request_id) +{ + static int transaction = 0; + + header->packet_type = AVDTP_PKT_TYPE_SINGLE; + header->message_type = AVDTP_MSG_TYPE_COMMAND; + header->transaction = transaction; + header->signal_id = request_id; + + /* clear rfa bits */ + header->rfa0 = 0; + + transaction = (transaction + 1) % 16; +} + +static int avdtp_send(int sk, void *data, int len) +{ + int ret; + + ret = send(sk, data, len, 0); + + if (ret < 0) + ret = -errno; + else if (ret != len) + ret = -EIO; + + if (ret < 0) { + printf("Unable to send message: %s (%d)\n", strerror(-ret), -ret); + return ret; + } + + return ret; +} + +static int avdtp_receive(int sk, void *data, int len) +{ + int ret; + + ret = recv(sk, data, len, 0); + + if (ret < 0) { + printf("Unable to receive message: %s (%d)\n", strerror(errno), + errno); + return -errno; + } + + return ret; +} + +int avdtp_get_caps(int sk, int seid) +{ + struct seid_req req; + char buffer[1024]; + struct getcap_resp *caps = (void *) buffer; + int ret; + + memset(&req, 0, sizeof(req)); + init_request(&req.header, AVDTP_GET_CAPABILITIES); + req.acp_seid = seid; + + ret = avdtp_send(sk, &req, sizeof(req)); + if (ret < 0) + return ret; + + memset(&buffer, 0, sizeof(buffer)); + ret = avdtp_receive(sk, caps, sizeof(buffer)); + if (ret < 0) + return ret; + + if (ret < (sizeof(struct getcap_resp) + 4 + + sizeof(struct avdtp_media_codec_capability))) { + printf("Invalid capabilities\n"); + return -1; + } + + print_caps(caps, ret); + + return 0; +} + +int avdtp_discover(int sk) +{ + struct avdtp_header req; + char buffer[256]; + struct discover_resp *discover = (void *) buffer; + int ret, seps, i; + + memset(&req, 0, sizeof(req)); + init_request(&req, AVDTP_DISCOVER); + + ret = avdtp_send(sk, &req, sizeof(req)); + if (ret < 0) + return ret; + + memset(&buffer, 0, sizeof(buffer)); + ret = avdtp_receive(sk, discover, sizeof(buffer)); + if (ret < 0) + return ret; + + seps = (ret - sizeof(struct avdtp_header)) / sizeof(struct seid_info); + for (i = 0; i < seps; i++) { + const char *type, *media; + + switch (discover->seps[i].type) { + case AVDTP_SEP_TYPE_SOURCE: + type = "Source"; + break; + + case AVDTP_SEP_TYPE_SINK: + type = "Sink"; + break; + + default: + type = "Invalid"; + } + + switch (discover->seps[i].media_type) { + case AVDTP_MEDIA_TYPE_AUDIO: + media = "Audio"; + break; + + case AVDTP_MEDIA_TYPE_VIDEO: + media = "Audio"; + break; + + case AVDTP_MEDIA_TYPE_MULTIMEDIA: + media = "Audio"; + break; + + default: + media = "Invalid"; + } + + printf("Stream End-Point #%d: %s %s %s\n", discover->seps[i].seid, media, type, + discover->seps[i].inuse ? "*" : ""); + avdtp_get_caps(sk, discover->seps[i].seid); + } + + return 0; +} + +static int l2cap_connect(bdaddr_t *src, bdaddr_t *dst) +{ + struct sockaddr_l2 l2a; + int sk; + + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + bacpy(&l2a.l2_bdaddr, src); + + sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (sk < 0) { + printf("Cannot create L2CAP socket. %s(%d)\n", strerror(errno), + errno); + return -errno; + } + + if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) { + printf("Bind failed. %s (%d)\n", strerror(errno), errno); + return -errno; + } + + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + bacpy(&l2a.l2_bdaddr, dst); + l2a.l2_psm = htobs(AVDTP_PSM); + + if (connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) { + printf("Connect failed. %s(%d)\n", strerror(errno), errno); + return -errno; + } + + return sk; +} + +static void usage() +{ + printf("avinfo - Audio/Video Info Tool ver %s\n", VERSION); + printf("Usage:\n" + "\tavinfo \n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + bdaddr_t src, dst; + int opt, sk, dev_id; + + if (argc < 2) { + usage(); + exit(0); + } + + while ((opt = getopt_long(argc, argv, "h", main_options, NULL)) != -1) { + switch (opt) { + case 'h': + default: + usage(); + exit(0); + } + } + + bacpy(&src, BDADDR_ANY); + dev_id = hci_get_route(&src); + if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) { + printf("Cannot find any local adapter\n"); + exit(-1); + } + + printf("Connecting ... \n"); + + if (bachk(argv[1]) < 0) { + printf("Invalid argument\n"); + exit(1); + } + + str2ba(argv[1], &dst); + sk = l2cap_connect(&src, &dst); + if (sk < 0) + exit(1); + + if (avdtp_discover(sk) < 0) + exit(1); + + return 0; +} -- cgit From 4c91cd786d4e4d8d8b9346f008cdad0c7d324b54 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 2 Apr 2008 13:03:27 +0000 Subject: Remove the avinfo_SOURCES line. --- tools/Makefile.am | 1 - 1 file changed, 1 deletion(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index a529a6c5..828aa1b3 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -69,7 +69,6 @@ sdptool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a ciptool_LDADD = @BLUEZ_LIBS@ -avinfo_SOURCES = avinfo.c avinfo_LDADD = @BLUEZ_LIBS@ endif -- cgit From 326c4aedcfa9f7087b9c87614901f41a32f71c63 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 7 Apr 2008 20:45:21 +0000 Subject: Print mpeg sep information. --- tools/avinfo.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/avinfo.c b/tools/avinfo.c index f639181a..f5bb967e 100644 --- a/tools/avinfo.c +++ b/tools/avinfo.c @@ -114,6 +114,23 @@ #define MPEG_SAMPLING_FREQ_44100 (1 << 1) #define MPEG_SAMPLING_FREQ_48000 1 +#define MPEG_BIT_RATE_VBR 0x8000 +#define MPEG_BIT_RATE_320000 0x4000 +#define MPEG_BIT_RATE_256000 0x2000 +#define MPEG_BIT_RATE_224000 0x1000 +#define MPEG_BIT_RATE_192000 0x0800 +#define MPEG_BIT_RATE_160000 0x0400 +#define MPEG_BIT_RATE_128000 0x0200 +#define MPEG_BIT_RATE_112000 0x0100 +#define MPEG_BIT_RATE_96000 0x0080 +#define MPEG_BIT_RATE_80000 0x0040 +#define MPEG_BIT_RATE_64000 0x0020 +#define MPEG_BIT_RATE_56000 0x0010 +#define MPEG_BIT_RATE_48000 0x0008 +#define MPEG_BIT_RATE_40000 0x0004 +#define MPEG_BIT_RATE_32000 0x0002 +#define MPEG_BIT_RATE_FREE 0x0001 + struct avdtp_service_capability { uint8_t category; uint8_t length; @@ -245,7 +262,83 @@ struct getcap_resp { static void print_mpeg12(struct mpeg_codec_cap *mpeg) { - printf("\tMedia Codec: MPEG12\n"); + printf("\tMedia Codec: MPEG12\n\t\tChannel Modes: "); + + if (mpeg->channel_mode & MPEG_CHANNEL_MODE_MONO) + printf("Mono "); + if (mpeg->channel_mode & MPEG_CHANNEL_MODE_DUAL_CHANNEL) + printf("DualChannel "); + if (mpeg->channel_mode & MPEG_CHANNEL_MODE_STEREO) + printf("Stereo "); + if (mpeg->channel_mode & MPEG_CHANNEL_MODE_JOINT_STEREO) + printf("JointStereo"); + + printf("\n\t\tFrequencies: "); + if (mpeg->frequency & MPEG_SAMPLING_FREQ_16000) + printf("16Khz "); + if (mpeg->frequency & MPEG_SAMPLING_FREQ_22050) + printf("22.05Khz "); + if (mpeg->frequency & MPEG_SAMPLING_FREQ_24000) + printf("24Khz "); + if (mpeg->frequency & MPEG_SAMPLING_FREQ_32000) + printf("32Khz "); + if (mpeg->frequency & MPEG_SAMPLING_FREQ_44100) + printf("44.1Khz "); + if (mpeg->frequency & MPEG_SAMPLING_FREQ_48000) + printf("48Khz "); + + printf("\n\t\tCRC: %s", mpeg->crc ? "Yes" : "No"); + + printf("\n\t\tLayer: "); + if (mpeg->layer & MPEG_LAYER_MP1) + printf("1 "); + if (mpeg->layer & MPEG_LAYER_MP2) + printf("2 "); + if (mpeg->layer & MPEG_LAYER_MP3) + printf("3 "); + + printf("\n\t\tBit Rate: "); + if (mpeg->bitrate & MPEG_BIT_RATE_FREE) + printf("Free format"); + else { + if (mpeg->bitrate & MPEG_BIT_RATE_32000) + printf("32kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_40000) + printf("40kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_48000) + printf("48kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_56000) + printf("56kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_64000) + printf("64kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_80000) + printf("80kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_96000) + printf("96kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_112000) + printf("112kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_128000) + printf("128kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_160000) + printf("160kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_192000) + printf("192kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_224000) + printf("224kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_256000) + printf("256kbps "); + if (mpeg->bitrate & MPEG_BIT_RATE_320000) + printf("320kbps "); + } + + printf("\n\t\tVBR: %s", mpeg->bitrate & MPEG_BIT_RATE_VBR ? "Yes" : + "No"); + + printf("\n\t\tPayload Format: "); + if (mpeg->mpf) + printf("RFC-2250 RFC-3119\n"); + else + printf("RFC-2250\n"); } static void print_sbc(struct sbc_codec_cap *sbc) -- cgit From 17ec2826d313495aff0e16cf5330317b6c4f61c5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 15 Apr 2008 07:35:11 +0000 Subject: Fix typos and coding style --- tools/avinfo.c | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'tools') diff --git a/tools/avinfo.c b/tools/avinfo.c index f5bb967e..76d29c0c 100644 --- a/tools/avinfo.c +++ b/tools/avinfo.c @@ -80,39 +80,39 @@ #define SBC_SAMPLING_FREQ_16000 (1 << 3) #define SBC_SAMPLING_FREQ_32000 (1 << 2) #define SBC_SAMPLING_FREQ_44100 (1 << 1) -#define SBC_SAMPLING_FREQ_48000 1 +#define SBC_SAMPLING_FREQ_48000 (1 << 0) #define SBC_CHANNEL_MODE_MONO (1 << 3) #define SBC_CHANNEL_MODE_DUAL_CHANNEL (1 << 2) #define SBC_CHANNEL_MODE_STEREO (1 << 1) -#define SBC_CHANNEL_MODE_JOINT_STEREO 1 +#define SBC_CHANNEL_MODE_JOINT_STEREO (1 << 0) #define SBC_BLOCK_LENGTH_4 (1 << 3) #define SBC_BLOCK_LENGTH_8 (1 << 2) #define SBC_BLOCK_LENGTH_12 (1 << 1) -#define SBC_BLOCK_LENGTH_16 1 +#define SBC_BLOCK_LENGTH_16 (1 << 0) #define SBC_SUBBANDS_4 (1 << 1) -#define SBC_SUBBANDS_8 1 +#define SBC_SUBBANDS_8 (1 << 0) #define SBC_ALLOCATION_SNR (1 << 1) -#define SBC_ALLOCATION_LOUDNESS 1 +#define SBC_ALLOCATION_LOUDNESS (1 << 0) #define MPEG_CHANNEL_MODE_MONO (1 << 3) #define MPEG_CHANNEL_MODE_DUAL_CHANNEL (1 << 2) #define MPEG_CHANNEL_MODE_STEREO (1 << 1) -#define MPEG_CHANNEL_MODE_JOINT_STEREO 1 +#define MPEG_CHANNEL_MODE_JOINT_STEREO (1 << 0) #define MPEG_LAYER_MP1 (1 << 2) #define MPEG_LAYER_MP2 (1 << 1) -#define MPEG_LAYER_MP3 1 +#define MPEG_LAYER_MP3 (1 << 0) #define MPEG_SAMPLING_FREQ_16000 (1 << 5) #define MPEG_SAMPLING_FREQ_22050 (1 << 4) #define MPEG_SAMPLING_FREQ_24000 (1 << 3) #define MPEG_SAMPLING_FREQ_32000 (1 << 2) #define MPEG_SAMPLING_FREQ_44100 (1 << 1) -#define MPEG_SAMPLING_FREQ_48000 1 +#define MPEG_SAMPLING_FREQ_48000 (1 << 0) #define MPEG_BIT_RATE_VBR 0x8000 #define MPEG_BIT_RATE_320000 0x4000 @@ -380,7 +380,8 @@ static void print_sbc(struct sbc_codec_cap *sbc) if (sbc->block_length & SBC_BLOCK_LENGTH_16) printf("16 "); - printf("\n\t\tBitpool Range: %d-%d\n", sbc->min_bitpool, sbc->max_bitpool); + printf("\n\t\tBitpool Range: %d-%d\n", + sbc->min_bitpool, sbc->max_bitpool); } static void print_media_codec(struct avdtp_media_codec_capability *cap) @@ -389,11 +390,9 @@ static void print_media_codec(struct avdtp_media_codec_capability *cap) case A2DP_CODEC_SBC: print_sbc((void *) cap); break; - case A2DP_CODEC_MPEG12: print_mpeg12((void *) cap); break; - default: printf("\tMedia Codec: Unknown\n"); } @@ -425,6 +424,7 @@ static void print_caps(void *data, int size) print_media_codec((void *) cap->data); break; } + processed += 2 + cap->length; data += 2 + cap->length; } @@ -457,7 +457,8 @@ static int avdtp_send(int sk, void *data, int len) ret = -EIO; if (ret < 0) { - printf("Unable to send message: %s (%d)\n", strerror(-ret), -ret); + printf("Unable to send message: %s (%d)\n", + strerror(-ret), -ret); return ret; } @@ -471,8 +472,8 @@ static int avdtp_receive(int sk, void *data, int len) ret = recv(sk, data, len, 0); if (ret < 0) { - printf("Unable to receive message: %s (%d)\n", strerror(errno), - errno); + printf("Unable to receive message: %s (%d)\n", + strerror(errno), errno); return -errno; } @@ -500,7 +501,7 @@ int avdtp_get_caps(int sk, int seid) return ret; if (ret < (sizeof(struct getcap_resp) + 4 + - sizeof(struct avdtp_media_codec_capability))) { + sizeof(struct avdtp_media_codec_capability))) { printf("Invalid capabilities\n"); return -1; } @@ -537,11 +538,9 @@ int avdtp_discover(int sk) case AVDTP_SEP_TYPE_SOURCE: type = "Source"; break; - case AVDTP_SEP_TYPE_SINK: type = "Sink"; break; - default: type = "Invalid"; } @@ -550,21 +549,20 @@ int avdtp_discover(int sk) case AVDTP_MEDIA_TYPE_AUDIO: media = "Audio"; break; - case AVDTP_MEDIA_TYPE_VIDEO: - media = "Audio"; + media = "Video"; break; - case AVDTP_MEDIA_TYPE_MULTIMEDIA: - media = "Audio"; + media = "Multimedia"; break; - default: media = "Invalid"; } - printf("Stream End-Point #%d: %s %s %s\n", discover->seps[i].seid, media, type, - discover->seps[i].inuse ? "*" : ""); + printf("Stream End-Point #%d: %s %s %s\n", + discover->seps[i].seid, media, type, + discover->seps[i].inuse ? "*" : ""); + avdtp_get_caps(sk, discover->seps[i].seid); } -- cgit From 4679885ba99827f4b9836d6b4f7ce0134b82b565 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 May 2008 09:33:51 +0000 Subject: Add support for switching HID proxy devices from Dell --- tools/hid2hci.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'tools') diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 124829fb..eee6da8f 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -211,6 +211,37 @@ static int switch_logitech(struct device_info *devinfo) return err; } +static int switch_dell(struct device_info *devinfo) +{ + char report[] = { 0x7f, 0x13, 0x00, 0x00 }; + + struct usb_dev_handle *handle; + int err; + + handle = usb_open(devinfo->dev); + if (handle) { + usb_claim_interface(handle, 0); + usb_detach_kernel_driver_np(handle, 0); + } + + err = usb_control_msg(handle, + USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0x09, 0x7f | (0x03 << 8), 0, + report, sizeof(report), 10000); + + if (err == 0) { + err = -1; + errno = EALREADY; + } else { + if (errno == ETIMEDOUT) + err = 0; + } + + usb_close(handle); + + return err; +} + static struct device_id device_list[] = { { HCI, 0x0a12, 0x1000, switch_hidproxy }, { HID, 0x0a12, 0x0001, switch_hidproxy }, @@ -229,6 +260,8 @@ static struct device_id device_list[] = { { HCI, 0x046d, 0xc70e, switch_logitech }, /* Logitech diNovo keyboard */ { HCI, 0x046d, 0xc713, switch_logitech }, /* Logitech diNovo Edge */ { HCI, 0x046d, 0xc714, switch_logitech }, /* Logitech diNovo Edge */ + { HCI, 0x413c, 0x8158, switch_dell }, /* Dell Wireless 370 */ + { HCI, 0x413c, 0x8154, switch_dell }, /* Dell Wireless 410 */ { -1 } }; -- cgit From 2aab870f593da0b3ec83095e5ded93b900e4b600 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jun 2008 20:07:34 +0000 Subject: Update autoconf/automake options --- tools/Makefile.am | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 828aa1b3..bc46b3d4 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -15,14 +15,6 @@ bccmd_programs = bccmd_manfiles = endif -if AVCTRL -avctrl_programs = avctrl -avctrl_manfiles = avctrl.8 -else -avctrl_programs = -avctrl_manfiles = -endif - if HID2HCI hid2hci_programs = hid2hci hid2hci_manfiles = hid2hci.8 @@ -39,19 +31,17 @@ dfutool_programs = dfutool_manfiles = endif -if DFUBABEL -dfubabel_programs = dfubabel -dfubabel_manfiles = dfubabel.1 +if USB +usb_programs = dfubabel avctrl else -dfubabel_programs = -dfubabel_manfiles = +usb_programs = endif sbin_PROGRAMS = hciattach hciconfig $(bccmd_programs) $(avctrl_programs) $(hid2hci_programs) bin_PROGRAMS = $(tools_programs) $(dfutool_programs) $(dfubabel_programs) -noinst_PROGRAMS = hcisecfilter ppporc avinfo +noinst_PROGRAMS = hcisecfilter ppporc avinfo $(usb_programs) hciattach_SOURCES = hciattach.c hciattach_st.c hciattach_LDADD = @BLUEZ_LIBS@ @@ -75,7 +65,8 @@ endif ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_bcsp.c csr_h4.c csr_3wire.c ubcsp.h ubcsp.c +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c \ + csr_bcsp.c csr_h4.c csr_3wire.c ubcsp.h ubcsp.c bccmd_LDADD = @BLUEZ_LIBS@ if USB bccmd_SOURCES += csr_usb.c @@ -83,10 +74,6 @@ bccmd_LDADD += @USB_LIBS@ endif endif -if AVCTRL -avctrl_LDADD = @USB_LIBS@ -endif - if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif @@ -96,9 +83,9 @@ dfutool_SOURCES = dfutool.c dfu.h dfu.c dfutool_LDADD = @USB_LIBS@ endif -if DFUBABEL -dfubabel_SOURCES = dfubabel.c +if USB dfubabel_LDADD = @USB_LIBS@ +avctrl_LDADD = @USB_LIBS@ endif AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ @@ -107,8 +94,7 @@ INCLUDES = -I$(top_srcdir)/common if MANPAGES man_MANS = hciattach.8 hciconfig.8 $(tools_manfiles) \ - $(bccmd_manfiles) $(avctrl_manfiles) $(hid2hci_manfiles) \ - $(dfutool_manfiles) $(dfubabel_manfiles) + $(bccmd_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) endif EXTRA_DIST = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ -- cgit From f2a7dfa1566c75a8a52dd6692e9b139e36ddbc9d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Jun 2008 15:31:58 +0000 Subject: There is no kernel security manager --- tools/hciconfig.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'tools') diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 64c30b11..a01937b9 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -226,23 +226,6 @@ static void cmd_encrypt(int ctl, int hdev, char *opt) } } -static void cmd_secmgr(int ctl, int hdev, char *opt) -{ - int val, s = hci_open_dev(hdev); - - if (!strcmp(opt, "secmgr")) - val = 1; - else - val = 0; - - if (ioctl(s, HCISETSECMGR, val) < 0) { - fprintf(stderr, "Can't set security manager on hci%d: %s (%d)\n", - hdev, strerror(errno), errno); - exit(1); - } - close(s); -} - static void cmd_up(int ctl, int hdev, char *opt) { /* Start HCI device */ @@ -1642,8 +1625,6 @@ static struct { { "noauth", cmd_auth, 0, "Disable Authentication" }, { "encrypt", cmd_encrypt, 0, "Enable Encryption" }, { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, - { "secmgr", cmd_secmgr, 0, "Enable Security Manager" }, - { "nosecmgr", cmd_secmgr, 0, "Disable Security Manager" }, { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, { "noscan", cmd_scan, 0, "Disable scan" }, { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, -- cgit From 45c36dbd276501aa76d9798a8fafe6c202db7276 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 11 Jun 2008 13:20:50 +0000 Subject: Avoid direct inclusion of malloc.h --- tools/ciptool.c | 2 +- tools/csr.c | 1 - tools/dfutool.c | 1 - tools/l2ping.c | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/ciptool.c b/tools/ciptool.c index 7d95953f..886e20aa 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tools/csr.c b/tools/csr.c index 7895363c..b32e4162 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/tools/dfutool.c b/tools/dfutool.c index 7a8c8dee..246d92a4 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/tools/l2ping.c b/tools/l2ping.c index 1be911ae..1e2aab6d 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include -- cgit From bbd957c4d906e3107b892b72339716f77c6b4b04 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Jun 2008 21:53:32 +0000 Subject: Add support for reading/setting the link policy --- tools/hcitool.1 | 11 ++++++ tools/hcitool.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 116 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/hcitool.1 b/tools/hcitool.1 index dd32ba21..8a7131d2 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -149,6 +149,17 @@ for the maximum transmit power level. Display AFH channel map for the connection to the device with Bluetooth address .IR bdaddr . .TP +.BI lp " [value]" +With no +.IR value , +displays link policy settings for the connection to the device with Bluetooth address +.IR bdaddr . +If +.IR value +is given, sets the link policy settings for that connection to +.IR value . +Possible values are RSWITCH, HOLD, SNIFF and PARK. +.TP .BI lst " [value]" With no .IR value , diff --git a/tools/hcitool.c b/tools/hcitool.c index 60e196be..02f56a43 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1763,6 +1763,105 @@ static void cmd_cpt(int dev_id, int argc, char **argv) hci_close_dev(dd); } +/* Get/Set link policy settings */ + +static struct option lp_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *lp_help = + "Usage:\n" + "\tlp [link policy]\n"; + +static void cmd_lp(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t policy; + int opt, dd; + + for_each_opt(opt, lp_options, NULL) { + switch (opt) { + default: + printf(lp_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(lp_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (argc == 1) { + char *str; + if (hci_read_link_policy(dd, htobs(cr->conn_info->handle), + &policy, 1000) < 0) { + perror("HCI read_link_policy_settings request failed"); + exit(1); + } + + policy = btohs(policy); + str = hci_lptostr(policy); + if (str) { + printf("Link policy settings: %s\n", str); + bt_free(str); + } else { + fprintf(stderr, "Invalig settings\n"); + exit(1); + } + } else { + unsigned int val; + if (hci_strtolp(argv[1], &val) < 0) { + fprintf(stderr, "Invalig arguments\n"); + exit(1); + } + policy = val; + + if (hci_write_link_policy(dd, htobs(cr->conn_info->handle), + htobs(policy), 1000) < 0) { + perror("HCI write_link_policy_settings request failed"); + exit(1); + } + } + + free(cr); + + hci_close_dev(dd); +} + /* Get/Set link supervision timeout */ static struct option lst_options[] = { @@ -1826,7 +1925,8 @@ static void cmd_lst(int dev_id, int argc, char **argv) } if (argc == 1) { - if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), &timeout, 1000) < 0) { + if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), + &timeout, 1000) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); } @@ -1839,9 +1939,10 @@ static void cmd_lst(int dev_id, int argc, char **argv) else printf("Link supervision timeout never expires\n"); } else { - timeout = btohs(strtol(argv[1], NULL, 10)); + timeout = strtol(argv[1], NULL, 10); - if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), timeout, 1000) < 0) { + if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), + htobs(timeout), 1000) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); } @@ -2253,6 +2354,7 @@ static struct { { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, { "afh", cmd_afh, "Display AFH channel map" }, + { "lp", cmd_lp, "Set/display link policy settings" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, -- cgit From ee0b35445ba76b7b73badbcdefbeca4ac9d5dc77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 01:15:44 +0000 Subject: Add extra attributes to the serial port record --- tools/sdptool.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 19882396..eb890df9 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1199,7 +1199,15 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) add_lang_attr(&record); - sdp_set_info_attr(&record, "Serial Port", 0, "COM Port"); + sdp_set_info_attr(&record, "Serial Port", "BlueZ", "COM Port"); + + sdp_set_url_attr(&record, "http://www.bluez.org/", + "http://www.bluez.org/", "http://www.bluez.org/"); + + sdp_set_service_id(&record, sp_uuid); + sdp_set_service_ttl(&record, 0xffff); + sdp_set_service_avail(&record, 0xff); + sdp_set_record_state(&record, 0x00001234); if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); -- cgit From 976827b9191dd074b26dd93b02cff8d639ec8bdc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 01:21:30 +0000 Subject: Use Handsfree version 0x0105 for the gateway role --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index eb890df9..1c49ed4e 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1564,7 +1564,7 @@ static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID); - profile.version = 0x0100; + profile.version = 0x0105; pfseq = sdp_list_append(0, &profile); sdp_set_profile_descs(&record, pfseq); -- cgit From 6930e84ba9858aabce5c8941a9511b593e0859d4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 01:34:08 +0000 Subject: Add example record for headset audio gateway record --- tools/sdptool.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'tools') diff --git a/tools/sdptool.c b/tools/sdptool.c index 1c49ed4e..003d8875 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1470,6 +1470,76 @@ end: return ret; } +static int add_headset_ag(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel ? si->channel : 7; + uint16_t u16 = 0x17; + sdp_data_t *channel, *features; + uint8_t netid = si->network ? si->network : 0x01; // ???? profile document + sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); + int ret = 0; + + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + features = sdp_data_alloc(SDP_UINT16, &u16); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Voice Gateway", 0, 0); + + sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + + printf("Headset AG service registered\n"); + +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + + return ret; +} + static int add_handsfree(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -3302,6 +3372,7 @@ struct { { "PRINT", DIRECT_PRINTING_SVCLASS_ID, add_directprint }, { "HS", HEADSET_SVCLASS_ID, add_headset }, + { "HSAG", HEADSET_AGW_SVCLASS_ID, add_headset_ag }, { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, { "HFAG", HANDSFREE_AGW_SVCLASS_ID, add_handsfree_ag}, { "SAP", SAP_SVCLASS_ID, add_simaccess }, -- cgit From c24fa29e216026c41a14a89690002f45d8031e86 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 02:24:46 +0000 Subject: Mention the broken bgb2xx init routine --- tools/hciattach.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 36f3c72b..0210519e 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -897,7 +897,11 @@ static int stlc2500(int fd, struct uart_t *u, struct termios *ti) return stlc2500_init(fd, &bdaddr); } -extern int bgb2xx_init(int fd, bdaddr_t *bdaddr); +static int bgb2xx_init(int fd, bdaddr_t *bdaddr) +{ + /* This is broken and the routine got lost somewhere */ + return -EIO; +} static int bgb2xx(int fd, struct uart_t *u, struct termios *ti) { -- cgit From e0c96954340a6ccb8f40bb7106f8208484fa8599 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 02:31:48 +0000 Subject: Set input speed and the LL protocol identifier --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/hciattach.c b/tools/hciattach.c index 0210519e..7f699d92 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,7 @@ #define HCI_UART_BCSP 1 #define HCI_UART_3WIRE 2 #define HCI_UART_H4DS 3 +#define HCI_UART_LL 4 struct uart_t { char *type; @@ -146,6 +148,7 @@ static int uart_speed(int s) static int set_speed(int fd, struct termios *ti, int speed) { cfsetospeed(ti, uart_speed(speed)); + cfsetispeed(ti, uart_speed(speed)); return tcsetattr(fd, TCSANOW, ti); } -- cgit From 13c0e26a0213f67f5bb9bd6915fddee9a7ca3b49 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 02:47:01 +0000 Subject: Add alternate TI init routine --- tools/Makefile.am | 2 +- tools/hciattach.c | 10 +- tools/hciattach_tialt.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 tools/hciattach_tialt.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index bc46b3d4..a94c786a 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -43,7 +43,7 @@ bin_PROGRAMS = $(tools_programs) $(dfutool_programs) $(dfubabel_programs) noinst_PROGRAMS = hcisecfilter ppporc avinfo $(usb_programs) -hciattach_SOURCES = hciattach.c hciattach_st.c +hciattach_SOURCES = hciattach.c hciattach_st.c hciattach_tialt.c hciattach_LDADD = @BLUEZ_LIBS@ hciconfig_SOURCES = hciconfig.c csr.h csr.c diff --git a/tools/hciattach.c b/tools/hciattach.c index 7f699d92..1ef961b2 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -155,7 +155,7 @@ static int set_speed(int fd, struct termios *ti, int speed) /* * Read an HCI event from the given file descriptor. */ -static int read_hci_event(int fd, unsigned char* buf, int size) +int read_hci_event(int fd, unsigned char* buf, int size) { int remain, r; int count = 0; @@ -343,6 +343,13 @@ static int texas(int fd, struct uart_t *u, struct termios *ti) return 0; } +extern int texasalt_init(int fd, int speed); + +static int texasalt(int fd, struct uart_t *u, struct termios *ti) +{ + return texasalt_init(fd, u->speed); +} + static int read_check(int fd, void *buf, int count) { int res; @@ -1061,6 +1068,7 @@ struct uart_t uart[] = { { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, NULL, ericsson }, { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, NULL, digi }, { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, texas }, + { "texasalt", 0x0000, 0x0000, HCI_UART_LL, 115200, 115200, FLOW_CTL, NULL, texasalt }, { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, diff --git a/tools/hciattach_tialt.c b/tools/hciattach_tialt.c new file mode 100644 index 00000000..39292c04 --- /dev/null +++ b/tools/hciattach_tialt.c @@ -0,0 +1,272 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2008 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define FAILIF(x, args...) do { \ + if (x) { \ + fprintf(stderr, ##args); \ + return -1; \ + } \ +} while(0) + +typedef struct { + uint8_t uart_prefix; + hci_event_hdr hci_hdr; + evt_cmd_complete cmd_complete; + uint8_t status; + uint8_t data[16]; +} __attribute__((packed)) command_complete_t; + +extern int read_hci_event(int fd, unsigned char* buf, int size); + +static int read_command_complete(int fd, unsigned short opcode, unsigned char len) { + command_complete_t resp; + /* Read reply. */ + FAILIF(read_hci_event(fd, (unsigned char *)&resp, sizeof(resp)) < 0, + "Failed to read response"); + + /* Parse speed-change reply */ + FAILIF(resp.uart_prefix != HCI_EVENT_PKT, + "Error in response: not an event packet, but 0x%02x!\n", + resp.uart_prefix); + + FAILIF(resp.hci_hdr.evt != EVT_CMD_COMPLETE, /* event must be event-complete */ + "Error in response: not a cmd-complete event, " + "but 0x%02x!\n", resp.hci_hdr.evt); + + FAILIF(resp.hci_hdr.plen < 4, /* plen >= 4 for EVT_CMD_COMPLETE */ + "Error in response: plen is not >= 4, but 0x%02x!\n", + resp.hci_hdr.plen); + + /* cmd-complete event: opcode */ + FAILIF(resp.cmd_complete.opcode != (uint16_t)opcode, + "Error in response: opcode is 0x%04x, not 0x%04x!", + resp.cmd_complete.opcode, opcode); + + return resp.status == 0 ? 0 : -1; +} + +typedef struct { + uint8_t uart_prefix; + hci_command_hdr hci_hdr; + uint32_t speed; +} __attribute__((packed)) texas_speed_change_cmd_t; + +static int texas_change_speed(int fd, uint32_t speed) { + + return 0; + + /* Send a speed-change request */ + + texas_speed_change_cmd_t cmd; + int n; + + cmd.uart_prefix = HCI_COMMAND_PKT; + cmd.hci_hdr.opcode = 0xff36; + cmd.hci_hdr.plen = sizeof(uint32_t); + cmd.speed = speed; + + fprintf(stdout, "Setting speed to %d\n", speed); + n = write(fd, &cmd, sizeof(cmd)); + if (n < 0) { + perror("Failed to write speed-set command"); + return -1; + } + + n = write(fd, &cmd, sizeof(cmd)); + if (n < 0) { + perror("Failed to write command."); + return -1; + } + if (n < (int)sizeof(cmd)) { + fprintf(stderr, "Wanted to write %d bytes, could only write %d. " + "Stop\n", (int)sizeof(cmd), n); + return -1; + } + + /* Parse speed-change reply */ + if (read_command_complete(fd, 0xff36, 4) < 0) { + return -1; + } + fprintf(stdout, "Speed changed to %d.\n", speed); +} + +static int texas_load_firmware(int fd, const char *firmware) { + + fprintf(stdout, "Opening firmware file: %s\n", firmware); + int fw = open(firmware, O_RDONLY); + FAILIF(fw < 0, + "Could not open firmware file %s: %s (%d).\n", + firmware, strerror(errno), errno); + + fprintf(stdout, "Uploading firmware...\n"); + do { + int nr; + /* Read each command and wait for a response. */ + unsigned char cmdp[1 + sizeof(hci_command_hdr)]; + nr = read(fw, cmdp, sizeof(cmdp)); + if (!nr) + break; + hci_command_hdr *cmd = (hci_command_hdr *)(cmdp + 1); + FAILIF(nr != sizeof(cmdp), "Could not read H4 + HCI header!\n"); + FAILIF(*cmdp != HCI_COMMAND_PKT, "Command is not an H4 command packet!\n"); + + unsigned char data[1024]; + FAILIF(read(fw, data, cmd->plen) != cmd->plen, + "Could not read %d bytes of data for command with opcode %04x!\n", + cmd->plen, + cmd->opcode); + + { +#if 0 + fprintf(stdout, "\topcode 0x%04x (%d bytes of data).\n", + cmd->opcode, + cmd->plen); +#endif + struct iovec iov_cmd[2]; + iov_cmd[0].iov_base = cmdp; + iov_cmd[0].iov_len = sizeof(cmdp); + iov_cmd[1].iov_base = data; + iov_cmd[1].iov_len = cmd->plen; + int nw = writev(fd, iov_cmd, 2); + FAILIF(nw != sizeof(cmd) + cmd->plen, + "Could not send entire command (sent only %d bytes)!\n", + nw); + } + + /* Wait for response */ + if (read_command_complete(fd, + cmd->opcode, + cmd->plen) < 0) { + return -1; + } + + } while(1); + fprintf(stdout, "Firmware upload successful.\n"); + + close(fw); + return 0; +} + +int texasalt_init(int fd, int speed, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[4]; + unsigned char resp[100]; /* Response */ + int n; + + memset(resp,'\0', 100); + + /* It is possible to get software version with manufacturer specific + HCI command HCI_VS_TI_Version_Number. But the only thing you get more + is if this is point-to-point or point-to-multipoint module */ + + /* Get Manufacturer and LMP version */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x01; + cmd[2] = 0x10; + cmd[3] = 0x00; + + do { + n = write(fd, cmd, 4); + if (n < 0) { + perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)"); + return -1; + } + if (n < 4) { + fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n); + return -1; + } + + /* Read reply. */ + if (read_hci_event(fd, resp, 100) < 0) { + perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)"); + return -1; + } + + /* Wait for command complete event for our Opcode */ + } while (resp[4] != cmd[1] && resp[5] != cmd[2]); + + /* Verify manufacturer */ + if ((resp[11] & 0xFF) != 0x0d) + fprintf(stderr,"WARNING : module's manufacturer is not Texas Instrument\n"); + + /* Print LMP version */ + fprintf(stderr, "Texas module LMP version : 0x%02x\n", resp[10] & 0xFF); + + /* Print LMP subversion */ + { + unsigned short lmp_subv = resp[13] | (resp[14] << 8); + unsigned short brf_chip = (lmp_subv & 0x7c00) >> 10; + static const char *c_brf_chip[5] = { + "unknown", + "unknown", + "brf6100", + "brf6150", + "brf6300" + }; + + fprintf(stderr, "Texas module LMP sub-version : 0x%04x\n", lmp_subv); + + fprintf(stderr, + "\tinternal version freeze: %d\n" + "\tsoftware version: %d\n" + "\tchip: %s (%d)\n", + lmp_subv & 0x7f, + ((lmp_subv & 0x8000) >> (15-3)) | ((lmp_subv & 0x380) >> 7), + ((brf_chip > 4) ? "unknown" : c_brf_chip[brf_chip]), + brf_chip); + + char fw[100]; + sprintf(fw, "/etc/firmware/%s.bin", c_brf_chip[brf_chip]); + texas_load_firmware(fd, fw); + + texas_change_speed(fd, speed); + } + nanosleep(&tm, NULL); + return 0; +} -- cgit From 14f84d602a7584f0805c93ae9ad1bd26e2387f6d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 06:10:50 +0000 Subject: Update the TI init routine with BRF support --- tools/Makefile.am | 2 +- tools/hciattach.c | 76 +++----- tools/hciattach_ti.c | 520 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 542 insertions(+), 56 deletions(-) create mode 100644 tools/hciattach_ti.c (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index a94c786a..eb4dcc74 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -43,7 +43,7 @@ bin_PROGRAMS = $(tools_programs) $(dfutool_programs) $(dfubabel_programs) noinst_PROGRAMS = hcisecfilter ppporc avinfo $(usb_programs) -hciattach_SOURCES = hciattach.c hciattach_st.c hciattach_tialt.c +hciattach_SOURCES = hciattach.c hciattach_st.c hciattach_ti.c hciattach_tialt.c hciattach_LDADD = @BLUEZ_LIBS@ hciconfig_SOURCES = hciconfig.c csr.h csr.c diff --git a/tools/hciattach.c b/tools/hciattach.c index 1ef961b2..439b6658 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -72,6 +72,7 @@ struct uart_t { int flags; char *bdaddr; int (*init) (int fd, struct uart_t *u, struct termios *ti); + int (*post) (int fd, struct uart_t *u, struct termios *ti); }; #define FLOW_CTL 0x0001 @@ -145,7 +146,7 @@ static int uart_speed(int s) } } -static int set_speed(int fd, struct termios *ti, int speed) +int set_speed(int fd, struct termios *ti, int speed) { cfsetospeed(ti, uart_speed(speed)); cfsetispeed(ti, uart_speed(speed)); @@ -290,57 +291,17 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) return 0; } +extern int texas_init(int fd, struct termios *ti); +extern int texas_post(int fd, struct termios *ti); + static int texas(int fd, struct uart_t *u, struct termios *ti) { - struct timespec tm = {0, 50000}; - char cmd[4]; - unsigned char resp[100]; /* Response */ - int n; - - memset(resp,'\0', 100); - - /* It is possible to get software version with manufacturer specific - HCI command HCI_VS_TI_Version_Number. But the only thing you get more - is if this is point-to-point or point-to-multipoint module */ - - /* Get Manufacturer and LMP version */ - cmd[0] = HCI_COMMAND_PKT; - cmd[1] = 0x01; - cmd[2] = 0x10; - cmd[3] = 0x00; - - do { - n = write(fd, cmd, 4); - if (n < 0) { - perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)"); - return -1; - } - if (n < 4) { - fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n); - return -1; - } - - /* Read reply. */ - if (read_hci_event(fd, resp, 100) < 0) { - perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)"); - return -1; - } - - /* Wait for command complete event for our Opcode */ - } while (resp[4] != cmd[1] && resp[5] != cmd[2]); - - /* Verify manufacturer */ - if ((resp[11] & 0xFF) != 0x0d) - fprintf(stderr,"WARNING : module's manufacturer is not Texas Instrument\n"); - - /* Print LMP version */ - fprintf(stderr, "Texas module LMP version : 0x%02x\n", resp[10] & 0xFF); - - /* Print LMP subversion */ - fprintf(stderr, "Texas module LMP sub-version : 0x%02x%02x\n", resp[14] & 0xFF, resp[13] & 0xFF); + return texas_init(fd, ti); +} - nanosleep(&tm, NULL); - return 0; +static int texas2(int fd, struct uart_t *u, struct termios *ti) +{ + return texas_post(fd, ti); } extern int texasalt_init(int fd, int speed); @@ -1067,8 +1028,6 @@ struct uart_t uart[] = { { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, NULL }, { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, NULL, ericsson }, { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, NULL, digi }, - { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, texas }, - { "texasalt", 0x0000, 0x0000, HCI_UART_LL, 115200, 115200, FLOW_CTL, NULL, texasalt }, { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, NULL, bcsp }, @@ -1084,17 +1043,21 @@ struct uart_t uart[] = { /* Silicon Wave kits */ { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, swave }, + /* Texas Instruments Bluelink (BRF) modules */ + { "texas", 0x0000, 0x0000, HCI_UART_LL, 115200, 115200, FLOW_CTL, NULL, texas, texas2 }, + { "texasalt", 0x0000, 0x0000, HCI_UART_LL, 115200, 115200, FLOW_CTL, NULL, texasalt, NULL }, + /* ST Microelectronics minikits based on STLC2410/STLC2415 */ { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, NULL, st }, /* ST Microelectronics minikits based on STLC2500 */ - { "stlc2500", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, "00:80:E1:00:AB:BA", stlc2500 }, + { "stlc2500", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, "00:80:E1:00:AB:BA", stlc2500 }, /* Philips generic Ericsson IP core based */ { "philips", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, NULL }, /* Philips BGB2xx Module */ - { "bgb2xx", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, "BD:B2:10:00:AB:BA", bgb2xx }, + { "bgb2xx", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, "BD:B2:10:00:AB:BA", bgb2xx }, /* Sphinx Electronics PICO Card */ { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL, NULL }, @@ -1220,6 +1183,9 @@ int init_uart(char *dev, struct uart_t *u, int send_break) return -1; } + if (u->post && u->post(fd, u, &ti) < 0) + return -1; + return fd; } @@ -1235,7 +1201,7 @@ int main(int argc, char *argv[]) { struct uart_t *u = NULL; int detach, printpid, opt, i, n, ld, err; - int to = 5; + int to = 10; int init_speed = 0; int send_break = 0; pid_t pid; @@ -1348,7 +1314,7 @@ int main(int argc, char *argv[]) sa.sa_handler = sig_alarm; sigaction(SIGALRM, &sa, NULL); - /* 5 seconds should be enough for initialization */ + /* 10 seconds should be enough for initialization */ alarm(to); n = init_uart(dev, u, send_break); diff --git a/tools/hciattach_ti.c b/tools/hciattach_ti.c new file mode 100644 index 00000000..7eefef47 --- /dev/null +++ b/tools/hciattach_ti.c @@ -0,0 +1,520 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2008 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef HCIATTACH_DEBUG +#define DPRINTF(x...) printf(x) +#else +#define DPRINTF(x...) +#endif + +#define HCIUARTGETDEVICE _IOR('U', 202, int) + +#define MAKEWORD(a, b) ((uint16_t)(((uint8_t)(a)) | ((uint16_t)((uint8_t)(b))) << 8)) + +#define TI_MANUFACTURER_ID 13 + +#define FIRMWARE_DIRECTORY "/lib/firmware/" + +#define ACTION_SEND_COMMAND 1 +#define ACTION_WAIT_EVENT 2 +#define ACTION_SERIAL 3 +#define ACTION_DELAY 4 +#define ACTION_RUN_SCRIPT 5 +#define ACTION_REMARKS 6 + +#define BRF_DEEP_SLEEP_OPCODE_BYTE_1 0x0c +#define BRF_DEEP_SLEEP_OPCODE_BYTE_2 0xfd +#define BRF_DEEP_SLEEP_OPCODE \ + (BRF_DEEP_SLEEP_OPCODE_BYTE_1 | (BRF_DEEP_SLEEP_OPCODE_BYTE_2 << 8)) + +#define FILE_HEADER_MAGIC 0x42535442 + +/* + * BRF Firmware header + */ +struct bts_header { + uint32_t magic; + uint32_t version; + uint8_t future[24]; + uint8_t actions[0]; +}__attribute__ ((packed)); + +/* + * BRF Actions structure + */ +struct bts_action { + uint16_t type; + uint16_t size; + uint8_t data[0]; +} __attribute__ ((packed)); + +struct bts_action_send { + uint8_t data[0]; +} __attribute__ ((packed)); + +struct bts_action_wait { + uint32_t msec; + uint32_t size; + uint8_t data[0]; +}__attribute__ ((packed)); + +struct bts_action_delay { + uint32_t msec; +}__attribute__ ((packed)); + +struct bts_action_serial { + uint32_t baud; + uint32_t flow_control; +}__attribute__ ((packed)); + +extern int set_speed(int fd, struct termios *ti, int speed); +extern int read_hci_event(int fd, unsigned char* buf, int size); + +static FILE *bts_load_script(const char* file_name, uint32_t* version) +{ + struct bts_header header; + FILE* fp; + + fp = fopen(file_name, "rb"); + if (!fp) { + perror("can't open firmware file"); + goto out; + } + + if (1 != fread(&header, sizeof(struct bts_header), 1, fp)) { + perror("can't read firmware file"); + goto errclose; + } + + if (header.magic != FILE_HEADER_MAGIC) { + fprintf(stderr, "%s not a legal TI firmware file\n", file_name); + goto errclose; + } + + if (NULL != version) + *version = header.version; + + goto out; + +errclose: + fclose(fp); + fp = NULL; +out: + return fp; +} + +static unsigned long bts_fetch_action(FILE* fp, unsigned char* action_buf, + unsigned long buf_size, uint16_t* action_type) +{ + struct bts_action action_hdr; + unsigned long nread; + + if (!fp) + return 0; + + if (1 != fread(&action_hdr, sizeof(struct bts_action), 1, fp)) + return 0; + + if (action_hdr.size > buf_size) { + fprintf(stderr, "bts_next_action: not enough space to read next action\n"); + return 0; + } + + nread = fread(action_buf, sizeof(uint8_t), action_hdr.size, fp); + if (nread != (action_hdr.size)) { + fprintf(stderr, "bts_next_action: fread failed to read next action\n"); + return 0; + } + + *action_type = action_hdr.type; + + return nread * sizeof(uint8_t); +} + +static void bts_unload_script(FILE* fp) +{ + if (fp) + fclose(fp); +} + +static int is_it_texas(const uint8_t *respond) +{ + uint16_t manufacturer_id; + + manufacturer_id = MAKEWORD(respond[11], respond[12]); + + return TI_MANUFACTURER_ID == manufacturer_id ? 1 : 0; +} + +static const char *get_firmware_name(const uint8_t *respond) +{ + static char firmware_file_name[PATH_MAX] = {0}; + uint16_t version = 0, chip = 0, min_ver = 0, maj_ver = 0; + + version = MAKEWORD(respond[13], respond[14]); + chip = (version & 0x7C00) >> 10; + min_ver = (version & 0x007F); + maj_ver = (version & 0x0380) >> 7; + + if (version & 0x8000) + maj_ver |= 0x0008; + + sprintf(firmware_file_name, FIRMWARE_DIRECTORY "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver); + + return firmware_file_name; +} + +static void brf_delay(struct bts_action_delay *delay) +{ + usleep(1000 * delay->msec); +} + +static int brf_set_serial_params(struct bts_action_serial *serial_action, + int fd, struct termios *ti) +{ + fprintf(stderr, "texas: changing baud rate to %u, flow control to %u\n", + serial_action->baud, serial_action->flow_control ); + tcflush(fd, TCIOFLUSH); + + if (serial_action->flow_control) + ti->c_cflag |= CRTSCTS; + else + ti->c_cflag &= ~CRTSCTS; + + if (tcsetattr(fd, TCSANOW, ti) < 0) { + perror("Can't set port settings"); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (set_speed(fd, ti, serial_action->baud) < 0) { + perror("Can't set baud rate"); + return -1; + } + + return 0; +} + +static int brf_send_command_socket(int fd, struct bts_action_send* send_action) +{ + char response[1024] = {0}; + hci_command_hdr *cmd = (hci_command_hdr *) send_action->data; + uint16_t opcode = cmd->opcode; + + struct hci_request rq; + memset(&rq, 0, sizeof(rq)); + rq.ogf = cmd_opcode_ogf(opcode); + rq.ocf = cmd_opcode_ocf(opcode); + rq.event = EVT_CMD_COMPLETE; + rq.cparam = &send_action->data[3]; + rq.clen = send_action->data[2]; + rq.rparam = response; + rq.rlen = sizeof(response); + + if (hci_send_req(fd, &rq, 15) < 0) { + perror("Cannot send hci command to socket"); + return -1; + } + + /* verify success */ + if (response[0]) { + errno = EIO; + return -1; + } + + return 0; +} + +static int brf_send_command_file(int fd, struct bts_action_send* send_action, long size) +{ + unsigned char response[1024] = {0}; + long ret = 0; + + /* send command */ + if (size != write(fd, send_action, size)) { + perror("Texas: Failed to write action command"); + return -1; + } + + /* read response */ + ret = read_hci_event(fd, response, sizeof(response)); + if (ret < 0) { + perror("texas: failed to read command response"); + return -1; + } + + /* verify success */ + if (ret < 7 || 0 != response[6]) { + fprintf( stderr, "TI init command failed.\n" ); + errno = EIO; + return -1; + } + + return 0; +} + + +static int brf_send_command(int fd, struct bts_action_send* send_action, long size, int hcill_installed) +{ + int ret = 0; + char *fixed_action; + + /* remove packet type when giving to socket API */ + if (hcill_installed) { + fixed_action = ((char *) send_action) + 1; + ret = brf_send_command_socket(fd, (struct bts_action_send *) fixed_action); + } else { + ret = brf_send_command_file(fd, send_action, size); + } + + return ret; +} + +static int brf_do_action(uint16_t brf_type, uint8_t *brf_action, long brf_size, + int fd, struct termios *ti, int hcill_installed) +{ + int ret = 0; + + switch (brf_type) { + case ACTION_SEND_COMMAND: + DPRINTF("W"); + ret = brf_send_command(fd, (struct bts_action_send*) brf_action, brf_size, hcill_installed); + break; + case ACTION_WAIT_EVENT: + DPRINTF("R"); + break; + case ACTION_SERIAL: + DPRINTF("S"); + ret = brf_set_serial_params((struct bts_action_serial *) brf_action, fd, ti); + break; + case ACTION_DELAY: + DPRINTF("D"); + brf_delay((struct bts_action_delay *) brf_action); + break; + case ACTION_REMARKS: + DPRINTF("C"); + break; + default: + fprintf(stderr, "brf_init: unknown firmware action type (%d)\n", brf_type); + break; + } + + return ret; +} + +/* + * tests whether a given brf action is a HCI_VS_Sleep_Mode_Configurations cmd + */ +static int brf_action_is_deep_sleep(uint8_t *brf_action, long brf_size, + uint16_t brf_type) +{ + uint16_t opcode; + + if (brf_type != ACTION_SEND_COMMAND) + return 0; + + if (brf_size < 3) + return 0; + + if (brf_action[0] != HCI_COMMAND_PKT) + return 0; + + /* HCI data is little endian */ + opcode = brf_action[1] | (brf_action[2] << 8); + + if (opcode != BRF_DEEP_SLEEP_OPCODE) + return 0; + + /* action is deep sleep configuration command ! */ + return 1; +} + +/* + * This function is called twice. + * The first time it is called, it loads the brf script, and executes its + * commands until it reaches a deep sleep command (or its end). + * The second time it is called, it assumes HCILL protocol is set up, + * and sends rest of brf script via the supplied socket. + */ +static int brf_do_script(int fd, struct termios *ti, const char *bts_file) +{ + int ret = 0, hcill_installed = bts_file ? 0 : 1; + uint32_t vers; + static FILE *brf_script_file = NULL; + static uint8_t brf_action[256]; + static long brf_size; + static uint16_t brf_type; + + /* is it the first time we are called ? */ + if (0 == hcill_installed) { + DPRINTF("Sending script to serial device\n"); + brf_script_file = bts_load_script(bts_file, &vers ); + if (!brf_script_file) { + fprintf(stderr, "Warning: cannot find BTS file: %s\n", + bts_file); + return 0; + } + + fprintf( stderr, "Loaded BTS script version %u\n", vers ); + + brf_size = bts_fetch_action(brf_script_file, brf_action, + sizeof(brf_action), &brf_type); + if (brf_size == 0) { + fprintf(stderr, "Warning: BTS file is empty !"); + return 0; + } + } + else { + DPRINTF("Sending script to bluetooth socket\n"); + } + + /* execute current action and continue to parse brf script file */ + while (brf_size != 0) { + ret = brf_do_action(brf_type, brf_action, brf_size, + fd, ti, hcill_installed); + if (ret == -1) + break; + + brf_size = bts_fetch_action(brf_script_file, brf_action, + sizeof(brf_action), &brf_type); + + /* if this is the first time we run (no HCILL yet) */ + /* and a deep sleep command is encountered */ + /* we exit */ + if (!hcill_installed && + brf_action_is_deep_sleep(brf_action, + brf_size, brf_type)) + return 0; + } + + bts_unload_script(brf_script_file); + brf_script_file = NULL; + DPRINTF("\n"); + + return ret; +} + +int texas_init(int fd, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[4]; + unsigned char resp[100]; /* Response */ + const char *bts_file; + int n; + + memset(resp,'\0', 100); + + /* It is possible to get software version with manufacturer specific + HCI command HCI_VS_TI_Version_Number. But the only thing you get more + is if this is point-to-point or point-to-multipoint module */ + + /* Get Manufacturer and LMP version */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x01; + cmd[2] = 0x10; + cmd[3] = 0x00; + + do { + n = write(fd, cmd, 4); + if (n < 0) { + perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)"); + return -1; + } + if (n < 4) { + fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n); + return -1; + } + + /* Read reply. */ + if (read_hci_event(fd, resp, 100) < 0) { + perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)"); + return -1; + } + + /* Wait for command complete event for our Opcode */ + } while (resp[4] != cmd[1] && resp[5] != cmd[2]); + + /* Verify manufacturer */ + if (! is_it_texas(resp)) { + fprintf(stderr,"ERROR: module's manufacturer is not Texas Instruments\n"); + return -1; + } + + fprintf(stderr, "Found a Texas Instruments' chip!\n"); + + bts_file = get_firmware_name(resp); + fprintf(stderr, "Firmware file : %s\n", bts_file); + + n = brf_do_script(fd, ti, bts_file); + + nanosleep(&tm, NULL); + + return n; +} + +int texas_post(int fd, struct termios *ti) +{ + int dev_id, dd, ret = 0; + + sleep(1); + + dev_id = ioctl(fd, HCIUARTGETDEVICE, 0); + if (dev_id < 0) { + perror("cannot get device id"); + return -1; + } + + DPRINTF("\nAdded device hci%d\n", dev_id); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + return -1; + } + + ret = brf_do_script(dd, ti, NULL); + + hci_close_dev(dd); + + return ret; +} -- cgit From d048c324b31c685b6123098b415222b4ee6699bc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 06:45:36 +0000 Subject: Fix BCSP sent/receive handling --- tools/csr_bcsp.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 0dc334cb..bcf56a35 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -188,19 +188,6 @@ static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t while (1) { delay = ubcsp_poll(&activity); - if (activity & UBCSP_PACKET_RECEIVED) { - if (sent && receive_packet.channel == 5 && - receive_packet.payload[0] == 0xff) { - memcpy(rp, receive_packet.payload, - receive_packet.length); - break; - } - - receive_packet.length = 512; - ubcsp_receive_packet(&receive_packet); - timeout = 0; - } - if (activity & UBCSP_PACKET_SENT) { switch (varid) { case CSR_VARID_COLD_RESET: @@ -214,6 +201,19 @@ static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t timeout = 0; } + if (activity & UBCSP_PACKET_RECEIVED) { + if (sent && receive_packet.channel == 5 && + receive_packet.payload[0] == 0xff) { + memcpy(rp, receive_packet.payload, + receive_packet.length); + break; + } + + receive_packet.length = 512; + ubcsp_receive_packet(&receive_packet); + timeout = 0; + } + if (delay) { usleep(delay * 100); -- cgit From 972eeffa2bc0ef8962b1097183675c6a1691490b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 07:23:53 +0000 Subject: Fix include issue for PATH_MAX --- tools/hciattach_ti.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/hciattach_ti.c b/tools/hciattach_ti.c index 7eefef47..f79342dd 100644 --- a/tools/hciattach_ti.c +++ b/tools/hciattach_ti.c @@ -28,10 +28,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -- cgit From 8af2789f18e64aaee0ae52680f4474814b0be0b8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 08:46:06 +0000 Subject: Add the TI copyright note --- tools/hciattach_ti.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/hciattach_ti.c b/tools/hciattach_ti.c index f79342dd..7c1d58f9 100644 --- a/tools/hciattach_ti.c +++ b/tools/hciattach_ti.c @@ -2,6 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * + * Copyright (C) 2007-2008 Texas Instruments, Inc. * Copyright (C) 2005-2008 Marcel Holtmann * * -- cgit