From 038f1bf188e57dafd8efb08315651b33947b3c76 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Wed, 17 Dec 2008 18:04:08 -0800 Subject: [PATCH] Code drop from //branches/cupcake/...@124589 --- Android.mk | 2 + hcidump/AUTHORS | 5 + hcidump/Android.mk | 39 + hcidump/ChangeLog | 276 +++ hcidump/INSTALL | 236 ++ hcidump/MODULE_LICENSE_GPL | 0 hcidump/Makefile.am | 6 + hcidump/Makefile.in | 598 +++++ hcidump/NEWS | 0 hcidump/NOTICE | 340 +++ hcidump/README | 34 + hcidump/acinclude.m4 | 82 + hcidump/aclocal.m4 | 1062 +++++++++ hcidump/config.h.in | 25 + hcidump/configure | 5111 +++++++++++++++++++++++++++++++++++++++++ hcidump/configure.in | 22 + hcidump/depcomp | 584 +++++ hcidump/install-sh | 507 ++++ hcidump/missing | 367 +++ hcidump/parser/Makefile.am | 12 + hcidump/parser/Makefile.in | 419 ++++ hcidump/parser/avctp.c | 45 + hcidump/parser/avdtp.c | 493 ++++ hcidump/parser/bnep.c | 328 +++ hcidump/parser/bpa.c | 65 + hcidump/parser/capi.c | 849 +++++++ hcidump/parser/cmtp.c | 211 ++ hcidump/parser/csr.c | 628 +++++ hcidump/parser/ericsson.c | 53 + hcidump/parser/hci.c | 3247 ++++++++++++++++++++++++++ hcidump/parser/hcrp.c | 116 + hcidump/parser/hidp.c | 171 ++ hcidump/parser/l2cap.c | 971 ++++++++ hcidump/parser/lmp.c | 1349 +++++++++++ hcidump/parser/obex.c | 309 +++ hcidump/parser/parser.c | 346 +++ hcidump/parser/parser.h | 252 ++ hcidump/parser/ppp.c | 229 ++ hcidump/parser/rfcomm.c | 350 +++ hcidump/parser/rfcomm.h | 494 ++++ hcidump/parser/sdp.c | 808 +++++++ hcidump/parser/sdp.h | 162 ++ hcidump/parser/tcpip.c | 142 ++ hcidump/src/Makefile.am | 16 + hcidump/src/Makefile.in | 490 ++++ hcidump/src/bpasniff.c | 476 ++++ hcidump/src/csrsniff.c | 282 +++ hcidump/src/hcidump.8 | 148 ++ hcidump/src/hcidump.c | 1172 ++++++++++ hcidump/src/magic.btsnoop | 12 + utils/audio/Android.mk | 86 +- utils/audio/avdtp.c | 3 + utils/audio/control.c | 17 +- utils/audio/liba2dp.c | 691 ++++++ utils/audio/liba2dp.h | 13 + utils/common/Android.mk | 18 +- utils/dund/Android.mk | 28 +- utils/eglib/Android.mk | 5 +- utils/gdbus/Android.mk | 15 +- utils/hcid/Android.mk | 53 +- utils/hcid/main.c | 4 - utils/input/Android.mk | 39 + utils/input/manager.c | 1 + utils/rfcomm/Android.mk | 21 +- utils/sbc/sbc.c.arm | 3 + utils/sdpd/Android.mk | 14 +- utils/tools/Android.mk | 76 +- utils/tools/hciattach.c | 6 +- utils/tools/hciattach_tialt.c | 140 +- utils/tools/l2ping.c | 8 +- utils/tools/sdptool.c | 6 +- 71 files changed, 24937 insertions(+), 251 deletions(-) create mode 100644 hcidump/AUTHORS create mode 100755 hcidump/Android.mk create mode 100644 hcidump/ChangeLog create mode 100644 hcidump/INSTALL create mode 100644 hcidump/MODULE_LICENSE_GPL create mode 100644 hcidump/Makefile.am create mode 100644 hcidump/Makefile.in create mode 100644 hcidump/NEWS create mode 100644 hcidump/NOTICE create mode 100644 hcidump/README create mode 100644 hcidump/acinclude.m4 create mode 100644 hcidump/aclocal.m4 create mode 100644 hcidump/config.h.in create mode 100755 hcidump/configure create mode 100644 hcidump/configure.in create mode 100755 hcidump/depcomp create mode 100755 hcidump/install-sh create mode 100755 hcidump/missing create mode 100644 hcidump/parser/Makefile.am create mode 100644 hcidump/parser/Makefile.in create mode 100644 hcidump/parser/avctp.c create mode 100644 hcidump/parser/avdtp.c create mode 100644 hcidump/parser/bnep.c create mode 100644 hcidump/parser/bpa.c create mode 100644 hcidump/parser/capi.c create mode 100644 hcidump/parser/cmtp.c create mode 100644 hcidump/parser/csr.c create mode 100644 hcidump/parser/ericsson.c create mode 100644 hcidump/parser/hci.c create mode 100644 hcidump/parser/hcrp.c create mode 100644 hcidump/parser/hidp.c create mode 100644 hcidump/parser/l2cap.c create mode 100644 hcidump/parser/lmp.c create mode 100644 hcidump/parser/obex.c create mode 100644 hcidump/parser/parser.c create mode 100644 hcidump/parser/parser.h create mode 100644 hcidump/parser/ppp.c create mode 100644 hcidump/parser/rfcomm.c create mode 100644 hcidump/parser/rfcomm.h create mode 100644 hcidump/parser/sdp.c create mode 100644 hcidump/parser/sdp.h create mode 100644 hcidump/parser/tcpip.c create mode 100644 hcidump/src/Makefile.am create mode 100644 hcidump/src/Makefile.in create mode 100644 hcidump/src/bpasniff.c create mode 100644 hcidump/src/csrsniff.c create mode 100644 hcidump/src/hcidump.8 create mode 100644 hcidump/src/hcidump.c create mode 100644 hcidump/src/magic.btsnoop create mode 100644 utils/audio/liba2dp.c create mode 100644 utils/audio/liba2dp.h create mode 100644 utils/input/Android.mk create mode 100644 utils/sbc/sbc.c.arm diff --git a/Android.mk b/Android.mk index 02c1bec64..456efddcd 100644 --- a/Android.mk +++ b/Android.mk @@ -14,5 +14,7 @@ # limitations under the License. # ifneq ($(TARGET_SIMULATOR),true) +ifeq ($(BOARD_HAVE_BLUETOOTH),true) include $(all-subdir-makefiles) endif +endif diff --git a/hcidump/AUTHORS b/hcidump/AUTHORS new file mode 100644 index 000000000..804e2f605 --- /dev/null +++ b/hcidump/AUTHORS @@ -0,0 +1,5 @@ +Maxim Krasnyansky +Marcel Holtmann +Wayne Lee +Ricky Yuen +Takashi Sasai diff --git a/hcidump/Android.mk b/hcidump/Android.mk new file mode 100755 index 000000000..32cbc2652 --- /dev/null +++ b/hcidump/Android.mk @@ -0,0 +1,39 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_C_INCLUDES:= \ + $(call include-path-for,bluez-libs) + +LOCAL_CFLAGS:= \ + -DVERSION=\"1.41\" \ + +LOCAL_SRC_FILES:= \ + src/hcidump.c \ + parser/avctp.c \ + parser/avdtp.c \ + parser/bnep.c \ + parser/bpa.c \ + parser/capi.c \ + parser/cmtp.c \ + parser/csr.c \ + parser/ericsson.c \ + parser/hci.c \ + parser/hcrp.c \ + parser/hidp.c \ + parser/l2cap.c \ + parser/lmp.c \ + parser/obex.c \ + parser/parser.c \ + parser/ppp.c \ + parser/rfcomm.c \ + parser/sdp.c \ + parser/tcpip.c + +LOCAL_SHARED_LIBRARIES := \ + libbluetooth + +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE:=hcidump + +include $(BUILD_EXECUTABLE) diff --git a/hcidump/ChangeLog b/hcidump/ChangeLog new file mode 100644 index 000000000..1fd80669a --- /dev/null +++ b/hcidump/ChangeLog @@ -0,0 +1,276 @@ +ver 1.41: + Improve decoding of HCI connection link type. + Fix handling of unsupported L2CAP config options. + Add full decoding of L2CAP RFC config option. + Reset to L2CAP basic mode when MTU config request is sent. + +ver 1.40: + Add HCI and LMP decoding support for Simple Pairing. + + Note: + This version needs at least bluez-libs-3.14 + +ver 1.39: + Add support for daemon discover protocol. + Fix device disconnect handling. + +ver 1.38: + Add support for daemon mode. + +ver 1.37: + Add decoding for SCO packet flags. + Add decoding for more extended inquiry features. + Add missing HCI command and event decodings. + + Note: + This version needs at least bluez-libs-3.12 + +ver 1.36: + Add missing HCI command definitions. + Add missing HCI event definitions. + Add missing HCI error definitions. + +ver 1.35: + Add partial decoding for eSCO setup. + Fix HCI command array size. + +ver 1.34: + Add reading support for MacOS X packet logger format. + Add decoding for AFH host channel classification command. + Add decoding for QoS setup command. + +ver 1.33: + Add support for IPv6 decoding. + Add IPv6 connection support. + +ver 1.32: + Add decoding for link supervision timeout change event. + Add decoding for host controller to host flow control setting. + Add decoding for host number of completed packets. + Add decoding for host buffer size command. + Fix OBEX header parsing. + + Note: + This version needs at least bluez-libs-3.3 + +ver 1.31: + Add Ericsson LMP decoding support. + Update sniff subrating decoding. + Update UUID and attribute definitions. + + Note: + This version needs at least bluez-libs-3.0 + +ver 1.30: + Add decoding for pause encryption feature. + Add generic RFCOMM streaming helpers. + Add HDLC decoding support to the PPP parser. + Add unslip support and basic protocol decoding. + Add PPP extraction support. + Move TCP/IP decoders into a separate file. + Fix DoS problem of the L2CAP parser. + +ver 1.29: + Obfuscate the BD_ADDR if no vendor events are requested. + Decode and display binary strings correctly. + Allow null-terminated text strings. + Add definitions for Apple Agent. + Add skeleton for AVCTP parser. + Add skeleton for PPP parser. + +ver 1.28: + Add missing UUID definitions and translations. + Add option to disable vendor commands and events. + Add decoding for hold mode, sniff mode and park state. + Add decoding for sniff subrate command complete event. + Decode class of device and BD_ADDR for inquiry filter. + Make it possible to obfuscate pin codes and link keys. + + Note: + This version needs at least bluez-libs-2.23 + +ver 1.27: + Decode the extended inquiry response payload. + Update HCI_DEV_NONE frame format. + Update the CSR PS key handling. + Add another bunch LMP message decodings. + Add compile time buffer checks (FORTIFY SOURCE). + +ver 1.26: + Fix memory leak with lmp_vertostr() function. + Fix FHS packet decoding for slave connections. + Add support for decoding more LMP messages. + Display the data of extended inquiry results. + Correct HCI command and event string arrays. + Add SCO audio extraction support. + +ver 1.25: + Add new attribute identifiers and UUID definitions. + Add decoding support for extended inquiry response. + Add more detailed BCCMD decoding. + + Note: + This version needs at least bluez-libs-2.20 + +ver 1.24: + Allow selection of system device. + Handle system events and commands. + +ver 1.23: + Add decoding support for inquiry scan type. + Fix connection accept timeout and scan enable decoding. + Show human readable timestamps only in verbose decoding mode. + Dump raw BNEP payload only in non-verbose decoding mode. + Update CSR BCCMD support and correct uint32 decoding. + + Note: + This version needs at least bluez-libs-2.18 + +ver 1.22: + Only do verbose decoding when requested. + Fix number of completed packets decoding. + Improve the decoding of CSR vendor commands and events. + Use human readable timestamps. + Add support for the BTSnoop file format. + +ver 1.21: + Clear L2CAP states when receiving the HCI disconnect. + Make the OBEX parser aware of that RFCOMM is a stream. + Update HCI verbose decoding routines. + Add CSR verbose decoding support. + + Note: + This version needs at least bluez-libs-2.17 + +ver 1.20: + Workaround for inquiry results with RSSI and page scan mode. + Decode almost every used HCI commands and events. + + Note: + This version needs at least bluez-libs-2.16 + +ver 1.19: + Fix error message decoding. + Add IAC decoding support. + Add LMP parser support. + Add BCCMD decoding support. + Add L2CAP retransmission and flow control decoding. + +ver 1.18: + Fix declaration of the SDP data structures. + Extend the HCI verbose decoding support. + +ver 1.17: + Add support for HCI verbose decoding. + Add support for L2CAP verbose decoding. + Add first version of the BPA sniffer utility. + + Note: + This version needs at least bluez-libs-2.15 + +ver 1.16: + Add UUID translation for WAP. + Fix display of UUID 128. + Fix display of L2CAP config hint bit and QoS option. + Fix parsing of SDP continuation state. + +ver 1.15: + Update the L2CAP channel counting routine. + Fix SBC codec specific decoding. + Fix AVDTP signal channel header decoding. + Add decoding for the AVDTP media channel header. + +ver 1.14: + Count the number of L2CAP channels per PSM. + Differ between the AVDTP signal and media channel. + Add full decoding of the AVDTP signal channel information. + +ver 1.13: + Update many UUID to text translations. + Add support for sending and receiving dumps over TCP. + Add support for the vendor packets of the Digianswer BPA. + + Note: + This version needs at least bluez-libs-2.11 + +ver 1.12: + Fix whitespace stuff for extended dump. + Add support for dynamic RFCOMM channels. + Add initial OBEX parser support. + +ver 1.11: + Trace company id from the chip manufacturer. + Support extended dump functionality. + Use the L2CAP_CONF_RFC_MODE value. + Use bt_get_unaligned() for unaligned access. + Make compiling with debug information optional. + Don't override CFLAGS from configure. + + Note: + This version needs at least bluez-libs-2.10 + +ver 1.10: + Fix display of L2CAP CID. + Show L2CAP config values only when they are present. + Decode L2CAP information request and response. + Update autoconf and automake routines. + +ver 1.9: + Initial AVDTP parser support. + Various minor fixes and cleanups. + +ver 1.8: + Support Bluetooth 1.2 HCI commands and events. + Decode RFCOMM credit based flow control. + +ver 1.7: + HCRP parser support. + CAPI parser support. + CMTP reassembly support. + Support for dynamic PSM. + +ver 1.6: + HIDP parser support. + Various fixes for the SDP parser. + +ver 1.5: + Included man page for hcidump. + Minor fix for HCI grabber. + +ver 1.4: + CMTP parser support. + Various fixes for SDP, RFCOMM and BNEP parsers. + +ver 1.3: + RFCOMM and BNEP parser fixes. + Use getopt_long instead of argp. + Added --psm option. + Automake build environment. + Other minor fixes. + +ver 1.2: + BNEP support. + Correct filter initialization. + Minor fixes. + +ver 1.1: + SCO support. + Support for frame time stamps. + RAW mode and other minor fixes. + +ver 1.0: + L2CAP fragment reassembly. + RFCOMM parser (Wayne Lee). + SDP parser (Ricky Yuen). + Simple filtering. + +ver 0.2: + L2CAP parsing. PSM tracking. + HCI events and commands parsing. + Packet parser moved to unified library (libparser). + HCI socket filter support. + Improved command line option parsing. + Improved output format. + +ver 0.1: + Initial implementation. diff --git a/hcidump/INSTALL b/hcidump/INSTALL new file mode 100644 index 000000000..56b077d6a --- /dev/null +++ b/hcidump/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PREFIX', the package will +use PREFIX as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/hcidump/MODULE_LICENSE_GPL b/hcidump/MODULE_LICENSE_GPL new file mode 100644 index 000000000..e69de29bb diff --git a/hcidump/Makefile.am b/hcidump/Makefile.am new file mode 100644 index 000000000..ee3bba33a --- /dev/null +++ b/hcidump/Makefile.am @@ -0,0 +1,6 @@ + +SUBDIRS = parser src + +MAINTAINERCLEANFILES = Makefile.in \ + aclocal.m4 configure config.h.in \ + depcomp missing install-sh mkinstalldirs diff --git a/hcidump/Makefile.in b/hcidump/Makefile.in new file mode 100644 index 000000000..71d861151 --- /dev/null +++ b/hcidump/Makefile.in @@ -0,0 +1,598 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ + depcomp install-sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ_CFLAGS = @BLUEZ_CFLAGS@ +BLUEZ_LIBS = @BLUEZ_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = parser src +MAINTAINERCLEANFILES = Makefile.in \ + aclocal.m4 configure config.h.in \ + depcomp missing install-sh mkinstalldirs + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ + cd $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d $(distdir) || mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-exec-am: + +install-html: install-html-recursive + +install-info: install-info-recursive + +install-man: + +install-pdf: install-pdf-recursive + +install-ps: install-ps-recursive + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-generic distclean-hdr distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags tags-recursive uninstall uninstall-am + +# 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/hcidump/NEWS b/hcidump/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/hcidump/NOTICE b/hcidump/NOTICE new file mode 100644 index 000000000..3912109b5 --- /dev/null +++ b/hcidump/NOTICE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/hcidump/README b/hcidump/README new file mode 100644 index 000000000..46b411e19 --- /dev/null +++ b/hcidump/README @@ -0,0 +1,34 @@ +BlueZ - Bluetooth protocol stack for Linux +****************************************** + +Copyright (C) 2000-2002 Maxim Krasnyansky +Copyright (C) 2003-2007 Marcel Holtmann + +Bluetooth packet analyzer + + +Compilation and installation +============================ + +In order to compile Bluetooth analyzer you need following software packages: + - Linux Bluetooth protocol stack (BlueZ) + - GCC compiler + +To configure run: + ./configure --prefix=/usr --mandir=/usr/share/man + +Configure automatically searches for all required components and packages. + +To compile and install run: + make && make install + + +Information +=========== + +Mailing lists: + bluez-users@lists.sf.net - BlueZ general questions and discussions + bluez-devel@lists.sf.net - BlueZ development + +For additional information about the project visit BlueZ web site: + http://www.bluez.org diff --git a/hcidump/acinclude.m4 b/hcidump/acinclude.m4 new file mode 100644 index 000000000..683d9c396 --- /dev/null +++ b/hcidump/acinclude.m4 @@ -0,0 +1,82 @@ +AC_DEFUN([AC_PROG_CC_PIE], [ + AC_CACHE_CHECK([whether ${CC-cc} accepts -fPIE], ac_cv_prog_cc_pie, [ + echo 'void f(){}' > conftest.c + if test -z "`${CC-cc} -fPIE -pie -c conftest.c 2>&1`"; then + ac_cv_prog_cc_pie=yes + else + ac_cv_prog_cc_pie=no + fi + rm -rf conftest* + ]) +]) + +AC_DEFUN([AC_INIT_BLUEZ], [ + AC_PREFIX_DEFAULT(/usr/local) + + if (test "${CFLAGS}" = ""); then + CFLAGS="-Wall -O2" + fi + + if (test "${prefix}" = "NONE"); then + dnl no prefix and no sysconfdir, so default to /etc + if (test "$sysconfdir" = '${prefix}/etc'); then + AC_SUBST([sysconfdir], ['/etc']) + fi + + dnl no prefix and no mandir, so use ${prefix}/share/man as default + if (test "$mandir" = '${prefix}/man'); then + AC_SUBST([mandir], ['${prefix}/share/man']) + fi + + prefix="${ac_default_prefix}" + fi + + if (test "${libdir}" = '${exec_prefix}/lib'); then + libdir="${prefix}/lib" + fi + + if (test "$sysconfdir" = '${prefix}/etc'); then + configdir="${prefix}/etc/bluetooth" + else + configdir="${sysconfdir}/bluetooth" + fi + + AC_DEFINE_UNQUOTED(CONFIGDIR, "${configdir}", [Directory for the configuration files]) +]) + +AC_DEFUN([AC_PATH_BLUEZ], [ + PKG_CHECK_MODULES(BLUEZ, bluez, dummy=yes, AC_MSG_ERROR(Bluetooth library is required)) + AC_SUBST(BLUEZ_CFLAGS) + AC_SUBST(BLUEZ_LIBS) +]) + +AC_DEFUN([AC_ARG_BLUEZ], [ + fortify_enable=yes + debug_enable=no + pie_enable=no + + AC_ARG_ENABLE(fortify, AC_HELP_STRING([--disable-fortify], [disable compile time buffer checks]), [ + fortify_enable=${enableval} + ]) + + AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [ + debug_enable=${enableval} + ]) + + AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie], [enable position independent executables flag]), [ + pie_enable=${enableval} + ]) + + if (test "${fortify_enable}" = "yes"); then + CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" + fi + + if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then + CFLAGS="$CFLAGS -g" + fi + + if (test "${pie_enable}" = "yes" && test "${ac_cv_prog_cc_pie}" = "yes"); then + CFLAGS="$CFLAGS -fPIE" + LDFLAGS="$LDFLAGS -pie" + fi +]) diff --git a/hcidump/aclocal.m4 b/hcidump/aclocal.m4 new file mode 100644 index 000000000..32e6582bd --- /dev/null +++ b/hcidump/aclocal.m4 @@ -0,0 +1,1062 @@ +# generated automatically by aclocal 1.10 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006 Free Software Foundation, Inc. +# This file 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. + +m4_if(m4_PACKAGE_VERSION, [2.61],, +[m4_fatal([this file was generated for autoconf 2.61. +You have another version of autoconf. If you want to use that, +you should regenerate the build system entirely.], [63])]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant . +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi + +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# +# Similar to PKG_CHECK_MODULES, make sure that the first instance of +# this or PKG_CHECK_MODULES is called, or make sure to call +# PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_ifval([$2], [$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$PKG_CONFIG"; then + if test -n "$$1"; then + pkg_cv_[]$1="$$1" + else + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + fi +else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + ifelse([$4], , [AC_MSG_ERROR(dnl +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT +])], + [AC_MSG_RESULT([no]) + $4]) +elif test $pkg_failed = untried; then + ifelse([$4], , [AC_MSG_FAILURE(dnl +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])], + [$4]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + ifelse([$3], , :, [$3]) +fi[]dnl +])# PKG_CHECK_MODULES + +# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. +# +# This file 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. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.10' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.10], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.10])dnl +_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file 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. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 8 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 9 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file 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. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006 Free Software Foundation, Inc. +# +# This file 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. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.60])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file 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. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file 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. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 4 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file 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. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 5 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file 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. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file 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. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file 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. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006 Free Software Foundation, Inc. +# +# This file 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. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file 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. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff --git a/hcidump/config.h.in b/hcidump/config.h.in new file mode 100644 index 000000000..21e655e8f --- /dev/null +++ b/hcidump/config.h.in @@ -0,0 +1,25 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Directory for the configuration files */ +#undef CONFIGDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/hcidump/configure b/hcidump/configure new file mode 100755 index 000000000..46fa4650a --- /dev/null +++ b/hcidump/configure @@ -0,0 +1,5111 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_default_prefix=/usr/local +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +am__isrc +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +MAINTAINER_MODE_TRUE +MAINTAINER_MODE_FALSE +MAINT +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +RANLIB +PKG_CONFIG +BLUEZ_CFLAGS +BLUEZ_LIBS +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +PKG_CONFIG +BLUEZ_CFLAGS +BLUEZ_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --disable-fortify disable compile time buffer checks + --enable-debug enable compiling with debugging information + --enable-pie enable position independent executables flag + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + PKG_CONFIG path to pkg-config utility + BLUEZ_CFLAGS + C compiler flags for BLUEZ, overriding pkg-config + BLUEZ_LIBS linker flags for BLUEZ, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +am__api_version='1.10' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done +done +IFS=$as_save_IFS + +fi + + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + test -d ./--version && rmdir ./--version + MKDIR_P="$ac_install_sh -d" + fi +fi +{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +echo "${ECHO_T}$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=bluez-hcidump + VERSION=1.41 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +ac_config_headers="$ac_config_headers config.h" + + +{ echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 +echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + + + + + if (test "${CFLAGS}" = ""); then + CFLAGS="-Wall -O2" + fi + + if (test "${prefix}" = "NONE"); then + if (test "$sysconfdir" = '${prefix}/etc'); then + sysconfdir='/etc' + + fi + + if (test "$mandir" = '${prefix}/man'); then + mandir='${prefix}/share/man' + + fi + + prefix="${ac_default_prefix}" + fi + + if (test "${libdir}" = '${exec_prefix}/lib'); then + libdir="${prefix}/lib" + fi + + if (test "$sysconfdir" = '${prefix}/etc'); then + configdir="${prefix}/etc/bluetooth" + else + configdir="${sysconfdir}/bluetooth" + fi + + +cat >>confdefs.h <<_ACEOF +#define CONFIGDIR "${configdir}" +_ACEOF + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + { echo "$as_me:$LINENO: checking whether ${CC-cc} accepts -fPIE" >&5 +echo $ECHO_N "checking whether ${CC-cc} accepts -fPIE... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_pie+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + echo 'void f(){}' > conftest.c + if test -z "`${CC-cc} -fPIE -pie -c conftest.c 2>&1`"; then + ac_cv_prog_cc_pie=yes + else + ac_cv_prog_cc_pie=no + fi + rm -rf conftest* + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_pie" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_pie" >&6; } + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { echo "$as_me:$LINENO: result: $ac_pt_PKG_CONFIG" >&5 +echo "${ECHO_T}$ac_pt_PKG_CONFIG" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { echo "$as_me:$LINENO: checking pkg-config is at least version $_pkg_min_version" >&5 +echo $ECHO_N "checking pkg-config is at least version $_pkg_min_version... $ECHO_C" >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + PKG_CONFIG="" + fi + +fi + + +pkg_failed=no +{ echo "$as_me:$LINENO: checking for BLUEZ" >&5 +echo $ECHO_N "checking for BLUEZ... $ECHO_C" >&6; } + +if test -n "$PKG_CONFIG"; then + if test -n "$BLUEZ_CFLAGS"; then + pkg_cv_BLUEZ_CFLAGS="$BLUEZ_CFLAGS" + else + if test -n "$PKG_CONFIG" && \ + { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"bluez\"") >&5 + ($PKG_CONFIG --exists --print-errors "bluez") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + pkg_cv_BLUEZ_CFLAGS=`$PKG_CONFIG --cflags "bluez" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi +if test -n "$PKG_CONFIG"; then + if test -n "$BLUEZ_LIBS"; then + pkg_cv_BLUEZ_LIBS="$BLUEZ_LIBS" + else + if test -n "$PKG_CONFIG" && \ + { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"bluez\"") >&5 + ($PKG_CONFIG --exists --print-errors "bluez") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + pkg_cv_BLUEZ_LIBS=`$PKG_CONFIG --libs "bluez" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + BLUEZ_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "bluez"` + else + BLUEZ_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "bluez"` + fi + # Put the nasty error message in config.log where it belongs + echo "$BLUEZ_PKG_ERRORS" >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { { echo "$as_me:$LINENO: error: Bluetooth library is required" >&5 +echo "$as_me: error: Bluetooth library is required" >&2;} + { (exit 1); exit 1; }; } +elif test $pkg_failed = untried; then + { { echo "$as_me:$LINENO: error: Bluetooth library is required" >&5 +echo "$as_me: error: Bluetooth library is required" >&2;} + { (exit 1); exit 1; }; } +else + BLUEZ_CFLAGS=$pkg_cv_BLUEZ_CFLAGS + BLUEZ_LIBS=$pkg_cv_BLUEZ_LIBS + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + dummy=yes +fi + + + + + + fortify_enable=yes + debug_enable=no + pie_enable=no + + # Check whether --enable-fortify was given. +if test "${enable_fortify+set}" = set; then + enableval=$enable_fortify; + fortify_enable=${enableval} + +fi + + + # Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then + enableval=$enable_debug; + debug_enable=${enableval} + +fi + + + # Check whether --enable-pie was given. +if test "${enable_pie+set}" = set; then + enableval=$enable_pie; + pie_enable=${enableval} + +fi + + + if (test "${fortify_enable}" = "yes"); then + CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" + fi + + if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then + CFLAGS="$CFLAGS -g" + fi + + if (test "${pie_enable}" = "yes" && test "${ac_cv_prog_cc_pie}" = "yes"); then + CFLAGS="$CFLAGS -fPIE" + LDFLAGS="$LDFLAGS -pie" + fi + + +ac_config_files="$ac_config_files Makefile src/Makefile parser/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "parser/Makefile") CONFIG_FILES="$CONFIG_FILES parser/Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +am__isrc!$am__isrc$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +MAINTAINER_MODE_TRUE!$MAINTAINER_MODE_TRUE$ac_delim +MAINTAINER_MODE_FALSE!$MAINTAINER_MODE_FALSE$ac_delim +MAINT!$MAINT$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +RANLIB!$RANLIB$ac_delim +PKG_CONFIG!$PKG_CONFIG$ac_delim +BLUEZ_CFLAGS!$BLUEZ_CFLAGS$ac_delim +BLUEZ_LIBS!$BLUEZ_LIBS$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 84; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| . 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/hcidump/configure.in b/hcidump/configure.in new file mode 100644 index 000000000..5a6363352 --- /dev/null +++ b/hcidump/configure.in @@ -0,0 +1,22 @@ +AC_PREREQ(2.50) +AC_INIT() + +AM_INIT_AUTOMAKE(bluez-hcidump, 1.41) +AM_CONFIG_HEADER(config.h) + +AM_MAINTAINER_MODE + +AC_INIT_BLUEZ + +AC_LANG_C + +AC_PROG_CC +AC_PROG_CC_PIE +AC_PROG_INSTALL +AC_PROG_RANLIB + +AC_PATH_BLUEZ + +AC_ARG_BLUEZ + +AC_OUTPUT(Makefile src/Makefile parser/Makefile) diff --git a/hcidump/depcomp b/hcidump/depcomp new file mode 100755 index 000000000..ca5ea4e1e --- /dev/null +++ b/hcidump/depcomp @@ -0,0 +1,584 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2006-10-15.18 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software +# Foundation, Inc. + +# 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, 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 Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/hcidump/install-sh b/hcidump/install-sh new file mode 100755 index 000000000..4fbbae7b7 --- /dev/null +++ b/hcidump/install-sh @@ -0,0 +1,507 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-10-14.15 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# 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 +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +posix_glob= +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chmodcmd=$chmodprog +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + shift + shift + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac +done + +if test $# -ne 0 && test -z "$dir_arg$dstarg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix=/ ;; + -*) prefix=./ ;; + *) prefix= ;; + esac + + case $posix_glob in + '') + if (set -f) 2>/dev/null; then + posix_glob=true + else + posix_glob=false + fi ;; + esac + + oIFS=$IFS + IFS=/ + $posix_glob && set -f + set fnord $dstdir + shift + $posix_glob && set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dst"; then + $doit $rmcmd -f "$dst" 2>/dev/null \ + || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ + && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ + || { + echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + } || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/hcidump/missing b/hcidump/missing new file mode 100755 index 000000000..1c8ff7049 --- /dev/null +++ b/hcidump/missing @@ -0,0 +1,367 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2006-05-10.23 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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, 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 Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case $1 in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $1 in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/hcidump/parser/Makefile.am b/hcidump/parser/Makefile.am new file mode 100644 index 000000000..cfaa0482e --- /dev/null +++ b/hcidump/parser/Makefile.am @@ -0,0 +1,12 @@ + +noinst_LIBRARIES = libparser.a + +libparser_a_SOURCES = \ + parser.c parser.h lmp.c hci.c \ + l2cap.c sdp.c sdp.h rfcomm.c rfcomm.h \ + bnep.c cmtp.c hidp.c hcrp.c avdtp.c avctp.c \ + obex.c capi.c ppp.c tcpip.c ericsson.c csr.c bpa.c + +AM_CFLAGS = @BLUEZ_CFLAGS@ + +MAINTAINERCLEANFILES = Makefile.in diff --git a/hcidump/parser/Makefile.in b/hcidump/parser/Makefile.in new file mode 100644 index 000000000..84b244e1f --- /dev/null +++ b/hcidump/parser/Makefile.in @@ -0,0 +1,419 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = parser +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libparser_a_AR = $(AR) $(ARFLAGS) +libparser_a_LIBADD = +am_libparser_a_OBJECTS = parser.$(OBJEXT) lmp.$(OBJEXT) hci.$(OBJEXT) \ + l2cap.$(OBJEXT) sdp.$(OBJEXT) rfcomm.$(OBJEXT) bnep.$(OBJEXT) \ + cmtp.$(OBJEXT) hidp.$(OBJEXT) hcrp.$(OBJEXT) avdtp.$(OBJEXT) \ + avctp.$(OBJEXT) obex.$(OBJEXT) capi.$(OBJEXT) ppp.$(OBJEXT) \ + tcpip.$(OBJEXT) ericsson.$(OBJEXT) csr.$(OBJEXT) bpa.$(OBJEXT) +libparser_a_OBJECTS = $(am_libparser_a_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libparser_a_SOURCES) +DIST_SOURCES = $(libparser_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ_CFLAGS = @BLUEZ_CFLAGS@ +BLUEZ_LIBS = @BLUEZ_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libparser.a +libparser_a_SOURCES = \ + parser.c parser.h lmp.c hci.c \ + l2cap.c sdp.c sdp.h rfcomm.c rfcomm.h \ + bnep.c cmtp.c hidp.c hcrp.c avdtp.c avctp.c \ + obex.c capi.c ppp.c tcpip.c ericsson.c csr.c bpa.c + +AM_CFLAGS = @BLUEZ_CFLAGS@ +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu parser/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu parser/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libparser.a: $(libparser_a_OBJECTS) $(libparser_a_DEPENDENCIES) + -rm -f libparser.a + $(libparser_a_AR) libparser.a $(libparser_a_OBJECTS) $(libparser_a_LIBADD) + $(RANLIB) libparser.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/avctp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/avdtp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bnep.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/capi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmtp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ericsson.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hci.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hcrp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hidp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/l2cap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obex.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfcomm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcpip.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am + +# 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/hcidump/parser/avctp.c b/hcidump/parser/avctp.c new file mode 100644 index 000000000..d9eb4f1eb --- /dev/null +++ b/hcidump/parser/avctp.c @@ -0,0 +1,45 @@ +/* + * + * 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 + +#include "parser.h" + +void avctp_dump(int level, struct frame *frm) +{ + p_indent(level, frm); + printf("AVCTP:\n"); + + raw_dump(level, frm); +} diff --git a/hcidump/parser/avdtp.c b/hcidump/parser/avdtp.c new file mode 100644 index 000000000..22c128a40 --- /dev/null +++ b/hcidump/parser/avdtp.c @@ -0,0 +1,493 @@ +/* + * + * 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 + +#include "parser.h" + +static char *si2str(uint8_t si) +{ + switch (si & 0x7f) { + case 0x01: + return "Discover"; + case 0x02: + return "Capabilities"; + case 0x03: + return "Set config"; + case 0x04: + return "Get config"; + case 0x05: + return "Reconfigure"; + case 0x06: + return "Open"; + case 0x07: + return "Start"; + case 0x08: + return "Close"; + case 0x09: + return "Suspend"; + case 0x0a: + return "Abort"; + case 0x0b: + return "Security"; + default: + return "Unknown"; + } +} + +static char *pt2str(uint8_t hdr) +{ + switch (hdr & 0x0c) { + case 0x00: + return "Single"; + case 0x04: + return "Start"; + case 0x08: + return "Cont"; + case 0x0c: + return "End"; + default: + return "Unk"; + } +} + +static char *mt2str(uint8_t hdr) +{ + switch (hdr & 0x03) { + case 0x00: + return "cmd"; + case 0x02: + return "rsp"; + case 0x03: + return "rej"; + default: + return "rfd"; + } +} + +static char *media2str(uint8_t type) +{ + switch (type) { + case 0: + return "Audio"; + case 1: + return "Video"; + case 2: + return "Multimedia"; + default: + return "Reserved"; + } +} + +static char *codec2str(uint8_t type, uint8_t codec) +{ + switch (type) { + case 0: + switch (codec) { + case 0: + return "SBC"; + case 1: + return "MPEG-1,2 Audio"; + case 2: + return "MPEG-2,4 AAC"; + case 4: + return "ATRAC family"; + case 255: + return "non-A2DP"; + default: + return "Reserved"; + } + break; + case 1: + switch (codec) { + case 1: + return "H.263 baseline"; + case 2: + return "MPEG-4 Visual Simple Profile"; + case 3: + return "H.263 profile 3"; + case 4: + return "H.263 profile 8"; + case 255: + return "Non-VDP"; + default: + return "Reserved"; + } + break; + } + return "Unknown"; +} + +static char *cat2str(uint8_t cat) +{ + switch (cat) { + case 1: + return "Media Transport"; + case 2: + return "Reporting"; + case 3: + return "Recovery"; + case 4: + return "Content Protection"; + case 5: + return "Header Compression"; + case 6: + return "Multiplexing"; + case 7: + return "Media Codec"; + default: + return "Reserved"; + } +} + +static void errorcode(int level, struct frame *frm) +{ + uint8_t code; + + p_indent(level, frm); + code = get_u8(frm); + printf("Error code %d\n", code); +} + +static void acp_seid(int level, struct frame *frm) +{ + uint8_t seid; + + p_indent(level, frm); + seid = get_u8(frm); + printf("ACP SEID %d\n", seid >> 2); +} + +static void acp_int_seid(int level, struct frame *frm) +{ + uint8_t acp_seid, int_seid; + + p_indent(level, frm); + acp_seid = get_u8(frm); + int_seid = get_u8(frm); + printf("ACP SEID %d - INT SEID %d\n", acp_seid >> 2, int_seid >> 2); +} + +static void capabilities(int level, struct frame *frm) +{ + uint8_t cat, len; + + while (frm->len > 1) { + p_indent(level, frm); + cat = get_u8(frm); + len = get_u8(frm); + + if (cat == 7) { + uint8_t type, codec, tmp; + + type = get_u8(frm); + codec = get_u8(frm); + + printf("%s - %s\n", cat2str(cat), codec2str(type, codec)); + + switch (codec) { + case 0: + tmp = get_u8(frm); + p_indent(level + 1, frm); + if (tmp & 0x80) + printf("16kHz "); + if (tmp & 0x40) + printf("32kHz "); + if (tmp & 0x20) + printf("44.1kHz "); + if (tmp & 0x10) + printf("48kHz "); + printf("\n"); + p_indent(level + 1, frm); + if (tmp & 0x08) + printf("Mono "); + if (tmp & 0x04) + printf("DualChannel "); + if (tmp & 0x02) + printf("Stereo "); + if (tmp & 0x01) + printf("JointStereo "); + printf("\n"); + tmp = get_u8(frm); + p_indent(level + 1, frm); + if (tmp & 0x80) + printf("4 "); + if (tmp & 0x40) + printf("8 "); + if (tmp & 0x20) + printf("12 "); + if (tmp & 0x10) + printf("16 "); + printf("Blocks\n"); + p_indent(level + 1, frm); + if (tmp & 0x08) + printf("4 "); + if (tmp & 0x04) + printf("8 "); + printf("Subbands\n"); + p_indent(level + 1, frm); + if (tmp & 0x02) + printf("SNR "); + if (tmp & 0x01) + printf("Loudness "); + printf("\n"); + tmp = get_u8(frm); + p_indent(level + 1, frm); + printf("Bitpool Range %d-%d\n", tmp, get_u8(frm)); + break; + default: + hex_dump(level + 1, frm, len - 2); + frm->ptr += (len - 2); + frm->len -= (len - 2); + break; + } + } else { + printf("%s\n", cat2str(cat)); + hex_dump(level + 1, frm, len); + + frm->ptr += len; + frm->len -= len; + } + } +} + +static inline void discover(int level, uint8_t hdr, struct frame *frm) +{ + uint8_t seid, type; + + switch (hdr & 0x03) { + case 0x02: + while (frm->len > 1) { + p_indent(level, frm); + seid = get_u8(frm); + type = get_u8(frm); + printf("ACP SEID %d - %s %s%s\n", + seid >> 2, media2str(type >> 4), + type & 0x08 ? "Sink" : "Source", + seid & 0x02 ? " (InUse)" : ""); + } + break; + case 0x03: + errorcode(level, frm); + break; + } +} + +static inline void get_capabilities(int level, uint8_t hdr, struct frame *frm) +{ + switch (hdr & 0x03) { + case 0x00: + acp_seid(level, frm); + break; + case 0x02: + capabilities(level, frm); + break; + case 0x03: + errorcode(level, frm); + break; + } +} + +static inline void set_configuration(int level, uint8_t hdr, struct frame *frm) +{ + uint8_t cat; + + switch (hdr & 0x03) { + case 0x00: + acp_int_seid(level, frm); + capabilities(level, frm); + break; + case 0x03: + p_indent(level, frm); + cat = get_u8(frm); + printf("%s\n", cat2str(cat)); + errorcode(level, frm); + break; + } +} + +static inline void get_configuration(int level, uint8_t hdr, struct frame *frm) +{ + switch (hdr & 0x03) { + case 0x00: + acp_seid(level, frm); + case 0x02: + capabilities(level, frm); + break; + case 0x03: + errorcode(level, frm); + break; + } +} + +static inline void reconfigure(int level, uint8_t hdr, struct frame *frm) +{ + uint8_t cat; + + switch (hdr & 0x03) { + case 0x00: + acp_seid(level, frm); + capabilities(level, frm); + break; + case 0x03: + p_indent(level, frm); + cat = get_u8(frm); + printf("%s\n", cat2str(cat)); + errorcode(level, frm); + break; + } +} + +static inline void open_close_stream(int level, uint8_t hdr, struct frame *frm) +{ + switch (hdr & 0x03) { + case 0x00: + acp_seid(level, frm); + break; + case 0x03: + errorcode(level, frm); + break; + } +} + +static inline void start_suspend_stream(int level, uint8_t hdr, struct frame *frm) +{ + switch (hdr & 0x03) { + case 0x00: + while (frm->len > 0) + acp_seid(level, frm); + break; + case 0x03: + acp_seid(level, frm); + errorcode(level, frm); + break; + } +} + +static inline void abort_streaming(int level, uint8_t hdr, struct frame *frm) +{ + switch (hdr & 0x03) { + case 0x00: + acp_seid(level, frm); + break; + } +} + +static inline void security(int level, uint8_t hdr, struct frame *frm) +{ + switch (hdr & 0x03) { + case 0x00: + acp_seid(level, frm); + case 0x02: + hex_dump(level + 1, frm, frm->len); + frm->ptr += frm->len; + frm->len = 0; + break; + case 0x03: + errorcode(level, frm); + break; + } +} + +void avdtp_dump(int level, struct frame *frm) +{ + uint8_t hdr, sid, nsp, type; + uint16_t seqn; + uint32_t time, ssrc; + + switch (frm->num) { + case 1: + p_indent(level, frm); + hdr = get_u8(frm); + + nsp = (hdr & 0x0c) == 0x04 ? get_u8(frm) : 0; + sid = hdr & 0x08 ? 0x00 : get_u8(frm); + + printf("AVDTP(s): %s %s: transaction %d\n", + hdr & 0x08 ? pt2str(hdr) : si2str(sid), mt2str(hdr), hdr >> 4); + + switch (sid & 0x7f) { + case 0x01: + discover(level + 1, hdr, frm); + break; + case 0x02: + get_capabilities(level + 1, hdr, frm); + break; + case 0x03: + set_configuration(level + 1, hdr, frm); + break; + case 0x04: + get_configuration(level + 1, hdr, frm); + break; + case 0x05: + reconfigure(level + 1, hdr, frm); + break; + case 0x06: + open_close_stream(level + 1, hdr, frm); + break; + case 0x07: + start_suspend_stream(level + 1, hdr, frm); + break; + case 0x08: + open_close_stream(level + 1, hdr, frm); + break; + case 0x09: + start_suspend_stream(level + 1, hdr, frm); + break; + case 0x0a: + abort_streaming(level + 1, hdr, frm); + break; + case 0x0b: + security(level + 1, hdr, frm); + break; + } + + break; + + case 2: + p_indent(level, frm); + hdr = get_u8(frm); + type = get_u8(frm); + seqn = get_u16(frm); + time = get_u32(frm); + ssrc = get_u32(frm); + + printf("AVDTP(m): ver %d %s%scc %d %spt %d seqn %d time %d ssrc %d\n", + hdr >> 6, hdr & 0x20 ? "pad " : "", hdr & 0x10 ? "ext " : "", + hdr & 0xf, type & 0x80 ? "mark " : "", type & 0x7f, seqn, time, ssrc); + break; + } + + raw_dump(level, frm); +} diff --git a/hcidump/parser/bnep.c b/hcidump/parser/bnep.c new file mode 100644 index 000000000..91b1aec23 --- /dev/null +++ b/hcidump/parser/bnep.c @@ -0,0 +1,328 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Takashi Sasai + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include "parser.h" + +#ifndef ETHERTYPE_ARP +#define ETHERTYPE_ARP ETH_P_ARP +#endif +#ifndef ETHERTYPE_REVARP +#define ETHERTYPE_REVARP ETH_P_RARP +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP ETH_P_IP +#endif + +/* BNEP Type */ +#define BNEP_GENERAL_ETHERNET 0x00 +#define BNEP_CONTROL 0x01 +#define BNEP_COMPRESSED_ETHERNET 0x02 +#define BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY 0x03 +#define BNEP_COMPRESSED_ETHERNET_DEST_ONLY 0x04 + +/* BNEP Control Packet Type */ +#define BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD 0x00 +#define BNEP_SETUP_CONNECTION_REQUEST_MSG 0x01 +#define BNEP_SETUP_CONNECTION_RESPONSE_MSG 0x02 +#define BNEP_FILTER_NET_TYPE_SET_MSG 0x03 +#define BNEP_FILTER_NET_TYPE_RESPONSE_MSG 0x04 +#define BNEP_FILTER_MULT_ADDR_SET_MSG 0x05 +#define BNEP_FILTER_MULT_ADDR_RESPONSE_MSG 0x06 + +/* BNEP Extension Type */ +#define BNEP_EXTENSION_CONTROL 0x00 + +#ifndef ETHERTYPE_IPV6 +#define ETHERTYPE_IPV6 ETH_P_IPV6 +#endif + +static char *get_macaddr(struct frame *frm) +{ + static char str[20]; + unsigned char *buf = frm->ptr; + + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + + frm->ptr += 6; + frm->len -= 6; + + return str; +} + +static void bnep_control(int level, struct frame *frm, int header_length) +{ + uint8_t uuid_size; + int i, length; + char *s; + uint32_t uuid = 0; + uint8_t type = get_u8(frm); + + p_indent(++level, frm); + switch (type) { + case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD: + printf("Not Understood(0x%02x) type 0x%02x\n", type, get_u8(frm)); + break; + + case BNEP_SETUP_CONNECTION_REQUEST_MSG: + uuid_size = get_u8(frm); + printf("Setup Req(0x%02x) size 0x%02x ", type, uuid_size); + switch (uuid_size) { + case 2: + uuid = get_u16(frm); + printf("dst 0x%x", uuid); + if ((s = get_uuid_name(uuid)) != 0) + printf("(%s)", s); + uuid = get_u16(frm); + printf(" src 0x%x", uuid); + if ((s = get_uuid_name(uuid)) != 0) + printf("(%s)", s); + printf("\n"); + break; + case 4: + uuid = get_u32(frm); + printf("dst 0x%x", uuid); + if ((s = get_uuid_name(uuid)) != 0) + printf("(%s)", s); + uuid = get_u32(frm); + printf(" src 0x%x", uuid); + if ((s = get_uuid_name(uuid)) != 0) + printf("(%s)", s); + printf("\n"); + break; + case 16: + uuid = get_u32(frm); + printf("dst 0x%x", uuid); + if ((s = get_uuid_name(uuid)) != 0) + printf("(%s)", s); + frm->ptr += 12; + frm->len -= 12; + uuid = get_u32(frm); + printf(" src 0x%x", uuid); + if ((s = get_uuid_name(uuid)) != 0) + printf("(%s)", s); + printf("\n"); + frm->ptr += 12; + frm->len -= 12; + break; + default: + frm->ptr += (uuid_size * 2); + frm->len -= (uuid_size * 2); + break; + } + break; + + case BNEP_SETUP_CONNECTION_RESPONSE_MSG: + printf("Setup Rsp(0x%02x) res 0x%04x\n", + type, get_u16(frm)); + break; + + case BNEP_FILTER_NET_TYPE_SET_MSG: + length = get_u16(frm); + printf("Filter NetType Set(0x%02x) len 0x%04x\n", + type, length); + for (i = 0; i < length / 4; i++) { + p_indent(level + 1, frm); + printf("0x%04x - ", get_u16(frm)); + printf("0x%04x\n", get_u16(frm)); + } + break; + + case BNEP_FILTER_NET_TYPE_RESPONSE_MSG: + printf("Filter NetType Rsp(0x%02x) res 0x%04x\n", + type, get_u16(frm)); + break; + + case BNEP_FILTER_MULT_ADDR_SET_MSG: + length = get_u16(frm); + printf("Filter MultAddr Set(0x%02x) len 0x%04x\n", + type, length); + for (i = 0; i < length / 12; i++) { + p_indent(level + 1, frm); + printf("%s - ", get_macaddr(frm)); + printf("%s\n", get_macaddr(frm)); + } + break; + + case BNEP_FILTER_MULT_ADDR_RESPONSE_MSG: + printf("Filter MultAddr Rsp(0x%02x) res 0x%04x\n", + type, get_u16(frm)); + break; + + default: + printf("Unknown control type(0x%02x)\n", type); + raw_ndump(level + 1, frm, header_length - 1); + frm->ptr += header_length - 1; + frm->len -= header_length - 1; + return; + } +} + +static void bnep_eval_extension(int level, struct frame *frm) +{ + uint8_t type = get_u8(frm); + uint8_t length = get_u8(frm); + int extension = type & 0x80; + + p_indent(level, frm); + + switch (type & 0x7f) { + case BNEP_EXTENSION_CONTROL: + printf("Ext Control(0x%02x|%s) len 0x%02x\n", + type & 0x7f, extension ? "1" : "0", length); + bnep_control(level, frm, length); + break; + + default: + printf("Ext Unknown(0x%02x|%s) len 0x%02x\n", + type & 0x7f, extension ? "1" : "0", length); + raw_ndump(level + 1, frm, length); + frm->ptr += length; + frm->len -= length; + } + + if (extension) + bnep_eval_extension(level, frm); +} + +void bnep_dump(int level, struct frame *frm) +{ + uint8_t type = get_u8(frm); + uint16_t proto = 0x0000; + int extension = type & 0x80; + + p_indent(level, frm); + + switch (type & 0x7f) { + case BNEP_CONTROL: + printf("BNEP: Control(0x%02x|%s)\n", + type & 0x7f, extension ? "1" : "0"); + bnep_control(level, frm, -1); + break; + + case BNEP_COMPRESSED_ETHERNET: + printf("BNEP: Compressed(0x%02x|%s)\n", + type & 0x7f, extension ? "1" : "0"); + p_indent(++level, frm); + proto = get_u16(frm); + printf("[proto 0x%04x]\n", proto); + break; + + case BNEP_GENERAL_ETHERNET: + printf("BNEP: General ethernet(0x%02x|%s)\n", + type & 0x7f, extension ? "1" : "0"); + p_indent(++level, frm); + printf("dst %s ", get_macaddr(frm)); + printf("src %s ", get_macaddr(frm)); + proto = get_u16(frm); + printf("[proto 0x%04x]\n", proto); + break; + + case BNEP_COMPRESSED_ETHERNET_DEST_ONLY: + printf("BNEP: Compressed DestOnly(0x%02x|%s)\n", + type & 0x7f, extension ? "1" : "0"); + p_indent(++level, frm); + printf("dst %s ", get_macaddr(frm)); + proto = get_u16(frm); + printf("[proto 0x%04x]\n", proto); + break; + + case BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY: + printf("BNEP: Compressed SrcOnly(0x%02x|%s)\n", + type & 0x7f, extension ? "1" : "0"); + p_indent(++level, frm); + printf("src %s ", get_macaddr(frm)); + proto = get_u16(frm); + printf("[proto 0x%04x]\n", proto); + break; + + default: + printf("(Unknown packet type)\n"); + return; + } + + /* Extension info */ + if (extension) + bnep_eval_extension(++level, frm); + + /* Control packet => No payload info */ + if ((type & 0x7f) == BNEP_CONTROL) + return; + + /* 802.1p header */ + if (proto == 0x8100) { + p_indent(level, frm); + printf("802.1p Header: 0x%04x ", get_u16(frm)); + proto = get_u16(frm); + printf("[proto 0x%04x]\n", proto); + } + + if (!(parser.flags & DUMP_VERBOSE)) { + raw_dump(level, frm); + return; + } + + switch (proto) { + case ETHERTYPE_ARP: + p_indent(++level, frm); + printf("ARP: "); + arp_dump(level, frm); + break; + + case ETHERTYPE_REVARP: + p_indent(++level, frm); + printf("RARP: "); + arp_dump(level, frm); + break; + + case ETHERTYPE_IP: + p_indent(++level, frm); + printf("IP: "); + ip_dump(level, frm); + break; + + case ETHERTYPE_IPV6: + p_indent(++level, frm); + printf("IPV6: "); + ip_dump(level, frm); + break; + + default: + raw_dump(level, frm); + break; + } +} diff --git a/hcidump/parser/bpa.c b/hcidump/parser/bpa.c new file mode 100644 index 000000000..fa7974c92 --- /dev/null +++ b/hcidump/parser/bpa.c @@ -0,0 +1,65 @@ +/* + * + * 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 + +#include +#include + +#include "parser.h" + +#define BPA_U8(frm) (get_u8(frm)) +#define BPA_U16(frm) (btohs(htons(get_u16(frm)))) +#define BPA_U32(frm) (btohl(htonl(get_u32(frm)))) + +void bpa_dump(int level, struct frame *frm) +{ + uint8_t id, status, channel; + uint16_t num, len; + uint32_t time; + + id = get_u8(frm); + num = get_u16(frm); + len = BPA_U16(frm); + + status = get_u8(frm); + time = get_u32(frm); + channel = get_u8(frm); + + p_indent(level, frm); + printf("BPA: id %d num %d status 0x%02x time %d channel %d\n", + id, num, status, time, channel); + + raw_dump(level, frm); +} diff --git a/hcidump/parser/capi.c b/hcidump/parser/capi.c new file mode 100644 index 000000000..36d57aad8 --- /dev/null +++ b/hcidump/parser/capi.c @@ -0,0 +1,849 @@ +/* + * + * 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 +#include + +#include + +#include "parser.h" + +#define CAPI_U8(frm) (get_u8(frm)) +#define CAPI_U16(frm) (btohs(htons(get_u16(frm)))) +#define CAPI_U32(frm) (btohl(htonl(get_u32(frm)))) + +static char *cmd2str(uint8_t cmd) +{ + switch (cmd) { + case 0x01: + return "ALERT"; + case 0x02: + return "CONNECT"; + case 0x03: + return "CONNECT_ACTIVE"; + case 0x04: + return "DISCONNECT"; + case 0x05: + return "LISTEN"; + case 0x08: + return "INFO"; + case 0x20: + return "INTEROPERABILITY"; + case 0x41: + return "SELECT_B_PROTOCOL"; + case 0x80: + return "FACILITY"; + case 0x82: + return "CONNECT_B3"; + case 0x83: + return "CONNECT_B3_ACTIVE"; + case 0x84: + return "DISCONNECT_B3"; + case 0x86: + return "DATA_B3"; + case 0x87: + return "RESET_B3"; + case 0x88: + return "CONNECT_B3_T90_ACTIVE"; + case 0xff: + return "MANUFACTURER"; + default: + return "UNKNOWN"; + } +} + +static char *subcmd2str(uint8_t subcmd) +{ + switch (subcmd) { + case 0x80: + return "REQ"; + case 0x81: + return "CONF"; + case 0x82: + return "IND"; + case 0x83: + return "RESP"; + default: + return "UNKN"; + } +} + +static char *interopsel2str(uint16_t sel) +{ + switch (sel) { + case 0x0000: + return "USB Device Management"; + case 0x0001: + return "Bluetooth Device Management"; + default: + return "Unknown"; + } +} + +static char *func2str(uint16_t func) +{ + switch (func) { + case 0: + return "Register"; + case 1: + return "Release"; + case 2: + return "Get_Profile"; + case 3: + return "Get_Manufacturer"; + case 4: + return "Get_Version"; + case 5: + return "Get_Serial_Number"; + case 6: + return "Manufacturer"; + case 7: + return "Echo_Loopback"; + default: + return "Unknown"; + } +} + +static char *facilitysel2str(uint16_t sel) +{ + switch (sel) { + case 0x0000: + return "Handset"; + case 0x0001: + return "DTMF"; + case 0x0002: + return "V.42 bis"; + case 0x0003: + return "Supplementary Services"; + case 0x0004: + return "Power management wakeup"; + case 0x0005: + return "Line Interconnect"; + case 0x0006: + return "DTMF"; + default: + return "Unknown"; + } +} + +static char *info2str(uint16_t info) +{ + switch (info) { + case 0x0000: + return "No error"; + case 0x0001: + return "NCPI not supported by current protocol, NCPI ignored"; + case 0x0002: + return "Flags not supported by current protocol, flags ignored"; + case 0x2001: + return "Message not supported in current state"; + case 0x2002: + return "Incorrect Controller/PLCI/NCCI"; + case 0x2003: + return "No PLCI available"; + case 0x2004: + return "No NCCI available"; + case 0x2005: + return "No Listen resources available"; + case 0x2007: + return "Illegal message parameter coding"; + case 0x2008: + return "No interconnection resources available"; + case 0x3001: + return "B1 protocol not supported"; + case 0x3002: + return "B2 protocol not supported"; + case 0x3003: + return "B3 protocol not supported"; + case 0x3004: + return "B1 protocol parameter not supported"; + case 0x3005: + return "B2 protocol parameter not supported"; + case 0x3006: + return "B3 protocol parameter not supported"; + case 0x3007: + return "B protocol combination not supported"; + case 0x3008: + return "NCPI not supported"; + case 0x3009: + return "CIP Value unknown"; + case 0x300A: + return "Flags not supported (reserved bits)"; + case 0x300B: + return "Facility not supported"; + case 0x300C: + return "Data length not supported by current protocol"; + case 0x300D: + return "Reset procedure not supported by current protocol"; + case 0x300F: + return "Unsupported interoperability"; + case 0x3011: + return "Facility specific function not supported"; + case 0x3301: + return "Protocol error, Layer 1"; + case 0x3302: + return "Protocol error, Layer 2"; + case 0x3303: + return "Protocol error, Layer 3"; + case 0x3304: + return "Another application got that call"; + case 0x3305: + return "Cleared by Call Control Supervision"; + case 0x3400: + /* The cause value received from the network in a cause + * information element (Octet 4) is indicated in the field 00 */ + return "Disconnect cause from the network in accordance with Q.850/ETS 300 102-1"; + default: + return "Unknown"; + } +} + +static void profile(int level, struct frame *frm) +{ + uint16_t nctr, nchn; + uint32_t value; + + nctr = CAPI_U16(frm); + nchn = CAPI_U16(frm); + + if (nchn > 0) { + p_indent(level, frm); + printf("Controller: %d\n", nctr); + p_indent(level, frm); + printf("Number of B-channels: %d\n", nchn); + + value = CAPI_U32(frm); + p_indent(level, frm); + printf("Global options: 0x%04x\n", value); + value = CAPI_U32(frm); + p_indent(level, frm); + printf("B1 protocol support: 0x%08x\n", value); + value = CAPI_U32(frm); + p_indent(level, frm); + printf("B2 protocol support: 0x%08x\n", value); + value = CAPI_U32(frm); + p_indent(level, frm); + printf("B3 protocol support: 0x%08x\n", value); + + frm->ptr += 24; + frm->len -= 24; + + p_indent(level, frm); + printf("Manufacturer-specific information:\n"); + hex_dump(level, frm, 20); + } else { + p_indent(level, frm); + printf("Number of controllers: %d\n", nctr); + } +} + +static void cmd_common(int level, uint8_t subcmd, struct frame *frm) +{ + uint32_t val; + uint16_t info, ncci; + uint8_t ctr, plci; + + val = CAPI_U32(frm); + ctr = val & 0xff; + plci = (val & 0xff00) >> 8; + ncci = (val & 0xffff0000) >> 16; + + p_indent(level, frm); + printf("Controller: %d %s\n", ctr & 0x7f, ctr & 0x80 ? "Ext." : "Int."); + + if (plci > 0) { + p_indent(level, frm); + printf("PLCI: 0x%02x\n", plci); + } + + if (ncci > 0) { + p_indent(level, frm); + printf("NCCI: 0x%04x\n", ncci); + } + + if (subcmd == 0x81) { + info = CAPI_U16(frm); + p_indent(level, frm); + printf("Info: 0x%04x (%s)\n", info, info2str(info)); + } +} + +static void cmd_alert(int level, uint8_t subcmd, struct frame *frm) +{ + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x80) { + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Additional info:\n"); + hex_dump(level, frm, len); + } + } +} + +static void cmd_connect(int level, uint8_t subcmd, struct frame *frm) +{ + uint16_t cip; + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x81) + return; + + cip = CAPI_U16(frm); + p_indent(level, frm); + printf("CIP value: 0x%04x\n", cip); + + len = CAPI_U8(frm); + frm->ptr += len; + frm->len -= len; + len = CAPI_U8(frm); + frm->ptr += len; + frm->len -= len; + len = CAPI_U8(frm); + frm->ptr += len; + frm->len -= len; + len = CAPI_U8(frm); + frm->ptr += len; + frm->len -= len; + + raw_dump(level, frm); +} + +static void cmd_disconnect(int level, uint8_t subcmd, struct frame *frm) +{ + uint16_t reason; + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x80) { + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Additional info:\n"); + hex_dump(level, frm, len); + } + } + + if (subcmd == 0x82) { + reason = CAPI_U16(frm); + p_indent(level, frm); + printf("Reason: 0x%04x (%s)\n", reason, info2str(reason)); + } +} + +static void cmd_connect_active(int level, uint8_t subcmd, struct frame *frm) +{ + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x82) { + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Connected number:\n"); + hex_dump(level, frm, len); + } + + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Connected subaddress:\n"); + hex_dump(level, frm, len); + } + + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("LLC:\n"); + hex_dump(level, frm, len); + } + } +} + +static void cmd_listen(int level, uint8_t subcmd, struct frame *frm) +{ + uint32_t mask; + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x80) { + mask = CAPI_U32(frm); + p_indent(level, frm); + printf("Info mask: 0x%08x\n", mask); + + mask = CAPI_U32(frm); + p_indent(level, frm); + printf("CIP mask: 0x%08x", mask); + + mask = CAPI_U32(frm); + if (mask > 0) + printf(" 0x%08x\n", mask); + else + printf("\n"); + + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Calling party number:\n"); + hex_dump(level, frm, len); + } + frm->ptr += len; + frm->len -= len; + + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Calling party subaddress:\n"); + hex_dump(level, frm, len); + } + frm->ptr += len; + frm->len -= len; + } +} + +static void cmd_info(int level, uint8_t subcmd, struct frame *frm) +{ + uint8_t len; + uint16_t info; + + cmd_common(level, subcmd, frm); + + switch (subcmd) { + case 0x80: + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Called party number:\n"); + hex_dump(level, frm, len); + } + frm->ptr += len; + frm->len -= len; + + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Additional info:\n"); + hex_dump(level, frm, len); + } + break; + + case 0x82: + info = CAPI_U16(frm); + p_indent(level, frm); + printf("Info number: %d\n", info); + + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("Info element:\n"); + hex_dump(level, frm, len); + } + break; + } +} + +static void cmd_interoperability(int level, uint8_t subcmd, struct frame *frm) +{ + uint16_t sel, func, info; + uint16_t nconn, datablkcnt, datablklen; + uint32_t ctr, value, major, minor; + + info = (subcmd == 0x81) ? CAPI_U16(frm) : 0; + sel = CAPI_U16(frm); + CAPI_U8(frm); + if (subcmd != 0x83) { + func = CAPI_U16(frm); + CAPI_U8(frm); + } else + func = 0; + + p_indent(level, frm); + printf("Selector: 0x%04x (%s)\n", sel, interopsel2str(sel)); + + switch (sel) { + case 0x0001: + p_indent(level, frm); + printf("Function: %d (%s)\n", func, func2str(func)); + + switch (subcmd) { + case 0x80: + switch (func) { + case 0: + nconn = CAPI_U16(frm); + p_indent(level + 1, frm); + printf("maxLogicalConnections: %d\n", nconn); + datablkcnt = CAPI_U16(frm); + p_indent(level + 1, frm); + printf("maxBDataBlocks: %d\n", datablkcnt); + datablklen = CAPI_U16(frm); + p_indent(level + 1, frm); + printf("maxBDataLen: %d\n", datablklen); + break; + case 2: + case 3: + case 4: + case 5: + ctr = CAPI_U32(frm); + p_indent(level + 1, frm); + printf("Controller: %d\n", ctr); + break; + default: + raw_dump(level + 1, frm); + break; + } + break; + + case 0x81: + switch (func) { + case 0: + case 1: + info = CAPI_U16(frm); + p_indent(level + 1, frm); + printf("Info: 0x%04x (%s)\n", info, info2str(info)); + break; + case 2: + info = CAPI_U16(frm); + p_indent(level + 1, frm); + printf("Info: 0x%04x (%s)\n", info, info2str(info)); + CAPI_U8(frm); + profile(level + 1, frm); + break; + case 3: + info = CAPI_U16(frm); + p_indent(level + 1, frm); + printf("Info: 0x%04x (%s)\n", info, info2str(info)); + ctr = CAPI_U32(frm); + p_indent(level + 1, frm); + printf("Controller: %d\n", ctr); + CAPI_U8(frm); + p_indent(level + 1, frm); + printf("Identification: \"%s\"\n", (char *) frm->ptr); + break; + case 4: + value = CAPI_U32(frm); + p_indent(level + 1, frm); + printf("Return value: 0x%04x\n", value); + ctr = CAPI_U32(frm); + p_indent(level + 1, frm); + printf("Controller: %d\n", ctr); + p_indent(level + 1, frm); + major = CAPI_U32(frm); + minor = CAPI_U32(frm); + printf("CAPI: %d.%d\n", major, minor); + major = CAPI_U32(frm); + minor = CAPI_U32(frm); + p_indent(level + 1, frm); + printf("Manufacture: %u.%01x%01x-%02u (%d.%d)\n", + (major & 0xf0) >> 4, (major & 0x0f) << 4, + (minor & 0xf0) >> 4, minor & 0x0f, + major, minor); + break; + case 5: + value = CAPI_U32(frm); + p_indent(level + 1, frm); + printf("Return value: 0x%04x\n", value); + ctr = CAPI_U32(frm); + p_indent(level + 1, frm); + printf("Controller: %d\n", ctr); + CAPI_U8(frm); + p_indent(level + 1, frm); + printf("Serial number: %.7s\n", (char *) frm->ptr); + break; + default: + raw_dump(level + 1, frm); + break; + } + break; + + default: + raw_dump(level, frm); + break; + } + break; + + default: + p_indent(level, frm); + printf("Function: %d\n", func); + if (subcmd == 0x81) { + p_indent(level, frm); + printf("Info: 0x%04x (%s)\n", info, info2str(info)); + } + raw_dump(level + 1, frm); + break; + } +} + +static void cmd_facility(int level, uint8_t subcmd, struct frame *frm) +{ + uint16_t sel; + + cmd_common(level, subcmd, frm); + + sel = CAPI_U16(frm); + CAPI_U8(frm); + + p_indent(level, frm); + printf("Selector: 0x%04x (%s)\n", sel, facilitysel2str(sel)); + + raw_dump(level, frm); +} + +static void cmd_connect_b3(int level, uint8_t subcmd, struct frame *frm) +{ + uint16_t reject; + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x81) + return; + + if (subcmd == 0x83) { + reject = CAPI_U16(frm); + p_indent(level, frm); + printf("Reject: 0x%04x (%s)\n", reject, info2str(reject)); + } + + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("NCPI:\n"); + hex_dump(level, frm, len); + } +} + +static void cmd_connect_b3_active(int level, uint8_t subcmd, struct frame *frm) +{ + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x82) { + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("NCPI:\n"); + hex_dump(level, frm, len); + } + } +} + +static void cmd_disconnect_b3(int level, uint8_t subcmd, struct frame *frm) +{ + uint16_t reason; + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x82) { + reason = CAPI_U16(frm); + p_indent(level, frm); + printf("Reason: 0x%04x (%s)\n", reason, info2str(reason)); + } + + if (subcmd == 0x80 || subcmd == 0x82) { + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("NCPI:\n"); + hex_dump(level, frm, len); + } + } +} + +static void cmd_data_b3(int level, uint8_t subcmd, struct frame *frm) +{ + uint32_t data; + uint64_t data64; + uint16_t length, handle, flags, info; + + cmd_common(level, 0x00, frm); + + if (subcmd == 0x81 || subcmd == 0x83) { + handle = CAPI_U16(frm); + p_indent(level, frm); + printf("Data handle: 0x%04x\n", handle); + + if (subcmd == 0x81) { + info = CAPI_U16(frm); + p_indent(level, frm); + printf("Info: 0x%04x (%s)\n", info, info2str(info)); + } + } else { + data = CAPI_U32(frm); + + length = CAPI_U16(frm); + p_indent(level, frm); + printf("Data length: 0x%04x (%d bytes)\n", length, length); + + handle = CAPI_U16(frm); + p_indent(level, frm); + printf("Data handle: 0x%04x\n", handle); + + flags = CAPI_U16(frm); + p_indent(level, frm); + printf("Flags: 0x%04x\n", flags); + + if (data == 0) + data64 = get_u64(frm); + + raw_dump(level, frm); + } +} + +static void cmd_reset_b3(int level, uint8_t subcmd, struct frame *frm) +{ + uint8_t len; + + cmd_common(level, subcmd, frm); + + if (subcmd == 0x80 || subcmd == 0x82) { + len = CAPI_U8(frm); + if (len > 0) { + p_indent(level, frm); + printf("NCPI:\n"); + hex_dump(level, frm, len); + } + } +} + +static void cmd_manufacturer(int level, uint8_t subcmd, struct frame *frm) +{ + uint32_t ctr, class, func; + uint16_t len; + unsigned char *id; + + ctr = CAPI_U32(frm); + p_indent(level, frm); + printf("Controller: %d\n", ctr); + + id = (unsigned char *) frm->ptr; + p_indent(level, frm); + if (isprint(id[0]) && isprint(id[1]) && isprint(id[2]) && isprint(id[3])) + printf("Manufacturer: %.4s", id); + else + printf("Manufacturer: 0x%02x 0x%02x 0x%02x 0x%02x", + id[0], id[1], id[2], id[3]); + frm->ptr += 4; + frm->len -= 4; + + if (!strncmp((char *) id, "AVM!", 4)) { + class = CAPI_U32(frm); + func = CAPI_U32(frm); + len = CAPI_U8(frm); + if (len == 0xff) + len = CAPI_U16(frm); + + printf(" [class %d func %d len %d]\n", class, func, len); + } else + printf("\n"); + + raw_dump(level, frm); +} + +void capi_dump(int level, struct frame *frm) +{ + uint16_t len, appl, msgnum; + uint8_t cmd, subcmd; + + len = CAPI_U16(frm) - 8; + appl = CAPI_U16(frm); + cmd = CAPI_U8(frm); + subcmd = CAPI_U8(frm); + msgnum = CAPI_U16(frm); + + p_indent(level, frm); + + printf("CAPI_%s_%s: appl %d msgnum %d len %d\n", + cmd2str(cmd), subcmd2str(subcmd), appl, msgnum, len); + + switch (cmd) { + case 0x01: + cmd_alert(level + 1, subcmd, frm); + break; + case 0x02: + cmd_connect(level + 1, subcmd, frm); + break; + case 0x03: + cmd_connect_active(level + 1, subcmd, frm); + break; + case 0x04: + cmd_disconnect(level + 1, subcmd, frm); + break; + case 0x05: + cmd_listen(level + 1, subcmd, frm); + break; + case 0x08: + cmd_info(level + 1, subcmd, frm); + break; + case 0x20: + cmd_interoperability(level + 1, subcmd, frm); + break; + case 0x80: + cmd_facility(level + 1, subcmd, frm); + break; + case 0x82: + cmd_connect_b3(level + 1, subcmd, frm); + break; + case 0x83: + case 0x88: + cmd_connect_b3_active(level + 1, subcmd, frm); + break; + case 0x84: + cmd_disconnect_b3(level + 1, subcmd, frm); + break; + case 0x86: + cmd_data_b3(level + 1, subcmd, frm); + break; + case 0x87: + cmd_reset_b3(level + 1, subcmd, frm); + break; + case 0xff: + cmd_manufacturer(level + 1, subcmd, frm); + break; + default: + raw_dump(level, frm); + frm->ptr += len; + frm->len -= len; + break; + } +} diff --git a/hcidump/parser/cmtp.c b/hcidump/parser/cmtp.c new file mode 100644 index 000000000..bdc202438 --- /dev/null +++ b/hcidump/parser/cmtp.c @@ -0,0 +1,211 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "parser.h" + +#define TABLE_SIZE 10 + +static struct { + uint16_t handle; + uint16_t cid; + struct frame msg[16]; +} table[TABLE_SIZE]; + +static void add_segment(uint8_t bid, struct frame *frm, int len) +{ + uint16_t handle = frm->handle, cid = frm->cid; + struct frame *msg; + void *data; + int i, pos = -1; + + if (bid > 15) + return; + + for (i = 0; i < TABLE_SIZE; i++) { + if (table[i].handle == handle && table[i].cid == cid) { + pos = i; + break; + } + + if (pos < 0 && !table[i].handle && !table[i].cid) + pos = i; + } + + if (pos < 0) + return; + + table[pos].handle = handle; + table[pos].cid = cid; + msg = &table[pos].msg[bid]; + + data = malloc(msg->data_len + len); + if (!data) + return; + + if (msg->data_len > 0) + memcpy(data, msg->data, msg->data_len); + + memcpy(data + msg->data_len, frm->ptr, len); + free(msg->data); + msg->data = data; + msg->data_len += len; + msg->ptr = msg->data; + msg->len = msg->data_len; + msg->in = frm->in; + msg->ts = frm->ts; + msg->handle = handle; + msg->cid = cid; +} + +static void free_segment(uint8_t bid, struct frame *frm) +{ + uint16_t handle = frm->handle, cid = frm->cid; + struct frame *msg; + int i, len = 0, pos = -1; + + if (bid > 15) + return; + + for (i = 0; i < TABLE_SIZE; i++) + if (table[i].handle == handle && table[i].cid == cid) { + pos = i; + break; + } + + if (pos < 0) + return; + + msg = &table[pos].msg[bid]; + + if (msg->data) + free(msg->data); + + msg->data = NULL; + msg->data_len = 0; + + for (i = 0; i < 16; i++) + len += table[pos].msg[i].data_len; + + if (!len) { + table[pos].handle = 0; + table[pos].cid = 0; + } +} + +static struct frame *get_segment(uint8_t bid, struct frame *frm) +{ + uint16_t handle = frm->handle, cid = frm->cid; + int i; + + if (bid > 15) + return NULL; + + for (i = 0; i < TABLE_SIZE; i++) + if (table[i].handle == handle && table[i].cid == cid) + return &table[i].msg[bid]; + + return NULL; +} + +static char *bst2str(uint8_t bst) +{ + switch (bst) { + case 0x00: + return "complete CAPI Message"; + case 0x01: + return "segmented CAPI Message"; + case 0x02: + return "error"; + case 0x03: + return "reserved"; + default: + return "unknown"; + } +} + +void cmtp_dump(int level, struct frame *frm) +{ + struct frame *msg; + uint8_t hdr, bid; + uint16_t len; + + while (frm->len > 0) { + + hdr = get_u8(frm); + bid = (hdr & 0x3c) >> 2; + + switch ((hdr & 0xc0) >> 6) { + case 0x01: + len = get_u8(frm); + break; + case 0x02: + len = htons(get_u16(frm)); + break; + default: + len = 0; + break; + } + + p_indent(level, frm); + + printf("CMTP: %s: id %d len %d\n", bst2str(hdr & 0x03), bid, len); + + switch (hdr & 0x03) { + case 0x00: + add_segment(bid, frm, len); + msg = get_segment(bid, frm); + if (!msg) + break; + + if (!p_filter(FILT_CAPI)) + capi_dump(level + 1, msg); + else + raw_dump(level, msg); + + free_segment(bid, frm); + break; + case 0x01: + add_segment(bid, frm, len); + break; + default: + free_segment(bid, frm); + break; + } + + frm->ptr += len; + frm->len -= len; + } +} diff --git a/hcidump/parser/csr.c b/hcidump/parser/csr.c new file mode 100644 index 000000000..6cce85b35 --- /dev/null +++ b/hcidump/parser/csr.c @@ -0,0 +1,628 @@ +/* + * + * 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 + +#include "parser.h" + +#define CSR_U8(frm) (get_u8(frm)) +#define CSR_U16(frm) (btohs(htons(get_u16(frm)))) +#define CSR_U32(frm) ((CSR_U16(frm) << 16) + CSR_U16(frm)) +#define CSR_S16(frm) (btohs(htons(get_u16(frm)))) + +static char *type2str(uint16_t type) +{ + switch (type) { + case 0x0000: + return "Get req"; + case 0x0001: + return "Get rsp"; + case 0x0002: + return "Set req"; + default: + return "Reserved"; + } +} + +static inline void valueless_dump(int level, char *str, struct frame *frm) +{ + p_indent(level, frm); + printf("%s\n", str); +} + +static inline void complex_dump(int level, char *str, struct frame *frm) +{ + p_indent(level, frm); + printf("%s\n", str); + + raw_dump(level, frm); +} + +static inline void bool_dump(int level, char *str, struct frame *frm) +{ + uint16_t value; + + value = CSR_U16(frm); + + p_indent(level, frm); + printf("%s: value %s (%d)\n", str, value ? "TRUE" : "FALSE", value); +} + +static inline void int8_dump(int level, char *str, struct frame *frm) +{ + int16_t value; + + value = CSR_S16(frm); + + p_indent(level, frm); + printf("%s: value %d (0x%2.2x)\n", str, value, value); +} + +static inline void int16_dump(int level, char *str, struct frame *frm) +{ + int16_t value; + + value = CSR_S16(frm); + + p_indent(level, frm); + printf("%s: value %d (0x%2.2x)\n", str, value, value); +} + +static inline void uint16_dump(int level, char *str, struct frame *frm) +{ + uint16_t value; + + value = CSR_U16(frm); + + p_indent(level, frm); + printf("%s: value %d (0x%4.4x)\n", str, value, value); +} + +static inline void uint32_dump(int level, char *str, struct frame *frm) +{ + uint32_t value; + + value = CSR_U32(frm); + + p_indent(level, frm); + printf("%s: value %d (0x%4.4x)\n", str, value, value); +} + +static inline void bdaddr_dump(int level, char *str, struct frame *frm) +{ + char addr[18]; + + p_ba2str(frm->ptr, addr); + + p_indent(level, frm); + printf("%s: bdaddr %s\n", str, addr); +} + +static inline void features_dump(int level, char *str, struct frame *frm) +{ + unsigned char features[8]; + int i; + + memcpy(features, frm->ptr, 8); + + p_indent(level, frm); + printf("%s: features", str); + for (i = 0; i < 8; i++) + printf(" 0x%02x", features[i]); + printf("\n"); +} + +static inline void commands_dump(int level, char *str, struct frame *frm) +{ + unsigned char commands[64]; + int i; + + memcpy(commands, frm->ptr, frm->len); + + p_indent(level, frm); + printf("%s: commands", str); + for (i = 0; i < frm->len; i++) + printf(" 0x%02x", commands[i]); + printf("\n"); +} + +static inline void handle_length_dump(int level, char *str, struct frame *frm) +{ + uint16_t handle, length; + + handle = CSR_U16(frm); + length = CSR_U16(frm); + + p_indent(level, frm); + printf("%s: handle %d length %d\n", str, handle, length); +} + +static inline void handle_clock_dump(int level, char *str, struct frame *frm) +{ + uint16_t handle; + uint32_t clock; + + handle = CSR_U16(frm); + clock = CSR_U32(frm); + + p_indent(level, frm); + printf("%s: handle %d clock 0x%4.4x\n", str, handle, clock); +} + +static inline void radiotest_dump(int level, char *str, struct frame *frm) +{ + uint16_t testid; + + testid = CSR_U16(frm); + + p_indent(level, frm); + printf("%s: test id %d\n", str, testid); + + raw_dump(level, frm); +} + +static inline void psmemtype_dump(int level, char *str, struct frame *frm) +{ + uint16_t store, type; + + store = CSR_U16(frm); + type = CSR_U16(frm); + + p_indent(level, frm); + printf("%s: store 0x%4.4x type %d\n", str, store, type); +} + +static inline void psnext_dump(int level, char *str, struct frame *frm) +{ + uint16_t key, stores, next; + + key = CSR_U16(frm); + stores = CSR_U16(frm); + next = CSR_U16(frm); + + p_indent(level, frm); + printf("%s: key 0x%4.4x stores 0x%4.4x next 0x%4.4x\n", str, key, stores, next); +} + +static inline void pssize_dump(int level, char *str, struct frame *frm) +{ + uint16_t key, length; + + key = CSR_U16(frm); + length = CSR_U16(frm); + + p_indent(level, frm); + printf("%s: key 0x%4.4x %s 0x%4.4x\n", str, key, + frm->in ? "len" : "stores", length); +} + +static inline void psstores_dump(int level, char *str, struct frame *frm) +{ + uint16_t key, stores; + + key = CSR_U16(frm); + stores = CSR_U16(frm); + + p_indent(level, frm); + printf("%s: key 0x%4.4x stores 0x%4.4x\n", str, key, stores); +} + +static inline void pskey_dump(int level, struct frame *frm) +{ + uint16_t key, length, stores; + + key = CSR_U16(frm); + length = CSR_U16(frm); + stores = CSR_U16(frm); + + p_indent(level, frm); + printf("PSKEY: key 0x%4.4x len %d stores 0x%4.4x\n", key, length, stores); + + switch (key) { + case 0x0001: + bdaddr_dump(level + 1, "BDADDR", frm); + break; + case 0x0002: + uint16_dump(level + 1, "COUNTRYCODE", frm); + break; + case 0x0003: + uint32_dump(level + 1, "CLASSOFDEVICE", frm); + break; + case 0x0004: + uint16_dump(level + 1, "DEVICE_DRIFT", frm); + break; + case 0x0005: + uint16_dump(level + 1, "DEVICE_JITTER", frm); + break; + case 0x000d: + uint16_dump(level + 1, "MAX_ACLS", frm); + break; + case 0x000e: + uint16_dump(level + 1, "MAX_SCOS", frm); + break; + case 0x000f: + uint16_dump(level + 1, "MAX_REMOTE_MASTERS", frm); + break; + case 0x00da: + uint16_dump(level + 1, "ENC_KEY_LMIN", frm); + break; + case 0x00db: + uint16_dump(level + 1, "ENC_KEY_LMAX", frm); + break; + case 0x00ef: + features_dump(level + 1, "LOCAL_SUPPORTED_FEATURES", frm); + break; + case 0x0106: + commands_dump(level + 1, "LOCAL_SUPPORTED_COMMANDS", frm); + break; + case 0x010d: + uint16_dump(level + 1, "HCI_LMP_LOCAL_VERSION", frm); + break; + case 0x010e: + uint16_dump(level + 1, "LMP_REMOTE_VERSION", frm); + break; + case 0x01a5: + bool_dump(level + 1, "HOSTIO_USE_HCI_EXTN", frm); + break; + case 0x01ab: + bool_dump(level + 1, "HOSTIO_MAP_SCO_PCM", frm); + break; + case 0x01be: + uint16_dump(level + 1, "UART_BAUDRATE", frm); + break; + case 0x01f6: + uint16_dump(level + 1, "ANA_FTRIM", frm); + break; + case 0x01f9: + uint16_dump(level + 1, "HOST_INTERFACE", frm); + break; + case 0x01fe: + uint16_dump(level + 1, "ANA_FREQ", frm); + break; + case 0x02be: + uint16_dump(level + 1, "USB_VENDOR_ID", frm); + break; + case 0x02bf: + uint16_dump(level + 1, "USB_PRODUCT_ID", frm); + break; + case 0x02cb: + uint16_dump(level + 1, "USB_DFU_PRODUCT_ID", frm); + break; + case 0x03cd: + int16_dump(level + 1, "INITIAL_BOOTMODE", frm); + break; + default: + raw_dump(level + 1, frm); + break; + } +} + +static inline void bccmd_dump(int level, struct frame *frm) +{ + uint16_t type, length, seqno, varid, status; + + type = CSR_U16(frm); + length = CSR_U16(frm); + seqno = CSR_U16(frm); + varid = CSR_U16(frm); + status = CSR_U16(frm); + + p_indent(level, frm); + printf("BCCMD: %s: len %d seqno %d varid 0x%4.4x status %d\n", + type2str(type), length, seqno, varid, status); + + if (!(parser.flags & DUMP_VERBOSE)) { + raw_dump(level + 1, frm); + return; + } + + switch (varid) { + case 0x000b: + valueless_dump(level + 1, "PS_CLR_ALL", frm); + break; + case 0x000c: + valueless_dump(level + 1, "PS_FACTORY_SET", frm); + break; + case 0x082d: + uint16_dump(level + 1, "PS_CLR_ALL_STORES", frm); + break; + case 0x2801: + uint16_dump(level + 1, "BC01_STATUS", frm); + break; + case 0x2819: + uint16_dump(level + 1, "BUILDID", frm); + break; + case 0x281a: + uint16_dump(level + 1, "CHIPVER", frm); + break; + case 0x281b: + uint16_dump(level + 1, "CHIPREV", frm); + break; + case 0x2825: + uint16_dump(level + 1, "INTERFACE_VERSION", frm); + break; + case 0x282a: + uint16_dump(level + 1, "RAND", frm); + break; + case 0x282c: + uint16_dump(level + 1, "MAX_CRYPT_KEY_LENGTH", frm); + break; + case 0x2833: + uint16_dump(level + 1, "E2_APP_SIZE", frm); + break; + case 0x2836: + uint16_dump(level + 1, "CHIPANAREV", frm); + break; + case 0x2838: + uint16_dump(level + 1, "BUILDID_LOADER", frm); + break; + case 0x2c00: + uint32_dump(level + 1, "BT_CLOCK", frm); + break; + case 0x3005: + psnext_dump(level + 1, "PS_NEXT", frm); + break; + case 0x3006: + pssize_dump(level + 1, "PS_SIZE", frm); + break; + case 0x3008: + handle_length_dump(level + 1, "CRYPT_KEY_LENGTH", frm); + break; + case 0x3009: + handle_clock_dump(level + 1, "PICONET_INSTANCE", frm); + break; + case 0x300a: + complex_dump(level + 1, "GET_CLR_EVT", frm); + break; + case 0x300b: + complex_dump(level + 1, "GET_NEXT_BUILDDEF", frm); + break; + case 0x300e: + complex_dump(level + 1, "E2_DEVICE", frm); + break; + case 0x300f: + complex_dump(level + 1, "E2_APP_DATA", frm); + break; + case 0x3012: + psmemtype_dump(level + 1, "PS_MEMORY_TYPE", frm); + break; + case 0x301c: + complex_dump(level + 1, "READ_BUILD_NAME", frm); + break; + case 0x4001: + valueless_dump(level + 1, "COLD_RESET", frm); + break; + case 0x4002: + valueless_dump(level + 1, "WARM_RESET", frm); + break; + case 0x4003: + valueless_dump(level + 1, "COLD_HALT", frm); + break; + case 0x4004: + valueless_dump(level + 1, "WARM_HALT", frm); + break; + case 0x4005: + valueless_dump(level + 1, "INIT_BT_STACK", frm); + break; + case 0x4006: + valueless_dump(level + 1, "ACTIVATE_BT_STACK", frm); + break; + case 0x4007: + valueless_dump(level + 1, "ENABLE_TX", frm); + break; + case 0x4008: + valueless_dump(level + 1, "DISABLE_TX", frm); + break; + case 0x4009: + valueless_dump(level + 1, "RECAL", frm); + break; + case 0x400d: + valueless_dump(level + 1, "PS_FACTORY_RESTORE", frm); + break; + case 0x400e: + valueless_dump(level + 1, "PS_FACTORY_RESTORE_ALL", frm); + break; + case 0x400f: + valueless_dump(level + 1, "PS_DEFRAG_RESET", frm); + break; + case 0x4011: + valueless_dump(level + 1, "HOPPING_ON", frm); + break; + case 0x4012: + valueless_dump(level + 1, "CANCEL_PAGE", frm); + break; + case 0x4818: + uint16_dump(level + 1, "PS_CLR", frm); + break; + case 0x481c: + uint16_dump(level + 1, "MAP_SCO_PCM", frm); + break; + case 0x482e: + uint16_dump(level + 1, "SINGLE_CHAN", frm); + break; + case 0x5004: + radiotest_dump(level + 1, "RADIOTEST", frm); + break; + case 0x500c: + psstores_dump(level + 1, "PS_CLR_STORES", frm); + break; + case 0x6000: + valueless_dump(level + 1, "NO_VARIABLE", frm); + break; + case 0x6802: + uint16_dump(level + 1, "CONFIG_UART", frm); + break; + case 0x6805: + uint16_dump(level + 1, "PANIC_ARG", frm); + break; + case 0x6806: + uint16_dump(level + 1, "FAULT_ARG", frm); + break; + case 0x6827: + int8_dump(level + 1, "MAX_TX_POWER", frm); + break; + case 0x682b: + int8_dump(level + 1, "DEFAULT_TX_POWER", frm); + break; + case 0x7003: + pskey_dump(level + 1, frm); + break; + default: + raw_dump(level + 1, frm); + break; + } +} + +static char *cid2str(uint8_t cid) +{ + switch (cid & 0x3f) { + case 0: + return "BCSP Internal"; + case 1: + return "BCSP Link"; + case 2: + return "BCCMD"; + case 3: + return "HQ"; + case 4: + return "Device Mgt"; + case 5: + return "HCI Cmd/Evt"; + case 6: + return "HCI ACL"; + case 7: + return "HCI SCO"; + case 8: + return "L2CAP"; + case 9: + return "RFCOMM"; + case 10: + return "SDP"; + case 11: + return "Debug"; + case 12: + return "DFU"; + case 13: + return "VM"; + case 14: + return "Unused"; + case 15: + return "Reserved"; + default: + return "Unknown"; + } +} + +static char *frag2str(uint8_t frag) +{ + switch (frag & 0xc0) { + case 0x00: + return " middle fragment"; + case 0x40: + return " first fragment"; + case 0x80: + return " last fragment"; + default: + return ""; + } +} + +void csr_dump(int level, struct frame *frm) +{ + uint8_t desc, cid, type; + uint16_t handle, master, addr; + + desc = CSR_U8(frm); + + cid = desc & 0x3f; + + switch (cid) { + case 2: + bccmd_dump(level, frm); + break; + + case 20: + type = CSR_U8(frm); + + if (!p_filter(FILT_LMP)) { + switch (type) { + case 0x0f: + frm->handle = ((uint8_t *) frm->ptr)[17]; + frm->master = 0; + frm->len--; + lmp_dump(level, frm); + return; + case 0x10: + frm->handle = ((uint8_t *) frm->ptr)[17]; + frm->master = 1; + frm->len--; + lmp_dump(level, frm); + return; + case 0x12: + handle = CSR_U16(frm); + master = CSR_U16(frm); + addr = CSR_U16(frm); + p_indent(level, frm); + printf("FHS: handle %d addr %d (%s)\n", handle, + addr, master ? "master" : "slave"); + if (!master) { + char addr[18]; + p_ba2str((bdaddr_t *) frm->ptr, addr); + p_indent(level + 1, frm); + printf("bdaddr %s class " + "0x%2.2x%2.2x%2.2x\n", addr, + ((uint8_t *) frm->ptr)[8], + ((uint8_t *) frm->ptr)[7], + ((uint8_t *) frm->ptr)[6]); + } + return; + case 0x7b: + p_indent(level, frm); + printf("LMP(r): duplicate (same SEQN)\n"); + return; + } + } + + p_indent(level, frm); + printf("CSR: Debug (type 0x%2.2x)\n", type); + raw_dump(level, frm); + break; + + default: + p_indent(level, frm); + printf("CSR: %s (channel %d)%s\n", cid2str(cid), cid, frag2str(desc)); + raw_dump(level, frm); + break; + } +} diff --git a/hcidump/parser/ericsson.c b/hcidump/parser/ericsson.c new file mode 100644 index 000000000..a9546d6bb --- /dev/null +++ b/hcidump/parser/ericsson.c @@ -0,0 +1,53 @@ +/* + * + * 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 "parser.h" + +void ericsson_dump(int level, struct frame *frm) +{ + uint8_t event = get_u8(frm); + uint8_t *buf = (uint8_t *) frm->ptr; + + if (event != 0x10) { + p_indent(level, frm); + printf("Ericsson: event 0x%2.2x\n", event); + raw_dump(level, frm); + } + + frm->master = !(buf[0] & 0x01); + frm->handle = buf[1] | (buf[2] << 8); + + buf[5] = (buf[5] << 1) | (buf[3] & 0x01); + + frm->ptr += 5; + frm->len -= 5; + + lmp_dump(level, frm); +} diff --git a/hcidump/parser/hci.c b/hcidump/parser/hci.c new file mode 100644 index 000000000..7c35f47dc --- /dev/null +++ b/hcidump/parser/hci.c @@ -0,0 +1,3247 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2002 Maxim Krasnyansky + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "parser.h" + +static uint16_t manufacturer = DEFAULT_COMPID; + +static inline uint16_t get_manufacturer(void) +{ + return (manufacturer == DEFAULT_COMPID ? parser.defcompid : manufacturer); +} + +#define EVENT_NUM 61 +static char *event_str[EVENT_NUM + 1] = { + "Unknown", + "Inquiry Complete", + "Inquiry Result", + "Connect Complete", + "Connect Request", + "Disconn Complete", + "Auth Complete", + "Remote Name Req Complete", + "Encrypt Change", + "Change Connection Link Key Complete", + "Master Link Key Complete", + "Read Remote Supported Features", + "Read Remote Ver Info Complete", + "QoS Setup Complete", + "Command Complete", + "Command Status", + "Hardware Error", + "Flush Occurred", + "Role Change", + "Number of Completed Packets", + "Mode Change", + "Return Link Keys", + "PIN Code Request", + "Link Key Request", + "Link Key Notification", + "Loopback Command", + "Data Buffer Overflow", + "Max Slots Change", + "Read Clock Offset Complete", + "Connection Packet Type Changed", + "QoS Violation", + "Page Scan Mode Change", + "Page Scan Repetition Mode Change", + "Flow Specification Complete", + "Inquiry Result with RSSI", + "Read Remote Extended Features", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Synchronous Connect Complete", + "Synchronous Connect Changed", + "Sniff Subrate", + "Extended Inquiry Result", + "Encryption Key Refresh Complete", + "IO Capability Request", + "IO Capability Response", + "User Confirmation Request", + "User Passkey Request", + "Remote OOB Data Request", + "Simple Pairing Complete", + "Unknown", + "Link Supervision Timeout Change", + "Enhanced Flush Complete", + "Unknown", + "User Passkey Notification", + "Keypress Notification", + "Remote Host Supported Features Notification", +}; + +#define CMD_LINKCTL_NUM 52 +static char *cmd_linkctl_str[CMD_LINKCTL_NUM + 1] = { + "Unknown", + "Inquiry", + "Inquiry Cancel", + "Periodic Inquiry Mode", + "Exit Periodic Inquiry Mode", + "Create Connection", + "Disconnect", + "Add SCO Connection", + "Create Connection Cancel", + "Accept Connection Request", + "Reject Connection Request", + "Link Key Request Reply", + "Link Key Request Negative Reply", + "PIN Code Request Reply", + "PIN Code Request Negative Reply", + "Change Connection Packet Type", + "Unknown", + "Authentication Requested", + "Unknown", + "Set Connection Encryption", + "Unknown", + "Change Connection Link Key", + "Unknown", + "Master Link Key", + "Unknown", + "Remote Name Request", + "Remote Name Request Cancel", + "Read Remote Supported Features", + "Read Remote Extended Features", + "Read Remote Version Information", + "Unknown", + "Read Clock Offset", + "Read LMP Handle", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Setup Synchronous Connection", + "Accept Synchronous Connection", + "Reject Synchronous Connection", + "IO Capability Request Reply", + "User Confirmation Request Reply", + "User Confirmation Request Negative Reply", + "User Passkey Request Reply", + "User Passkey Request Negative Reply", + "Remote OOB Data Request Reply", + "Unknown", + "Unknown", + "Remote OOB Data Request Negative Reply", + "IO Capability Request Negative Reply", +}; + +#define CMD_LINKPOL_NUM 17 +static char *cmd_linkpol_str[CMD_LINKPOL_NUM + 1] = { + "Unknown", + "Hold Mode", + "Unknown", + "Sniff Mode", + "Exit Sniff Mode", + "Park State", + "Exit Park State", + "QoS Setup", + "Unknown", + "Role Discovery", + "Unknown", + "Switch Role", + "Read Link Policy Settings", + "Write Link Policy Settings", + "Read Default Link Policy Settings", + "Write Default Link Policy Settings", + "Flow Specification", + "Sniff Subrating", +}; + +#define CMD_HOSTCTL_NUM 95 +static char *cmd_hostctl_str[CMD_HOSTCTL_NUM + 1] = { + "Unknown", + "Set Event Mask", + "Unknown", + "Reset", + "Unknown", + "Set Event Filter", + "Unknown", + "Unknown", + "Flush", + "Read PIN Type ", + "Write PIN Type", + "Create New Unit Key", + "Unknown", + "Read Stored Link Key", + "Unknown", + "Unknown", + "Unknown", + "Write Stored Link Key", + "Delete Stored Link Key", + "Write Local Name", + "Read Local Name", + "Read Connection Accept Timeout", + "Write Connection Accept Timeout", + "Read Page Timeout", + "Write Page Timeout", + "Read Scan Enable", + "Write Scan Enable", + "Read Page Scan Activity", + "Write Page Scan Activity", + "Read Inquiry Scan Activity", + "Write Inquiry Scan Activity", + "Read Authentication Enable", + "Write Authentication Enable", + "Read Encryption Mode", + "Write Encryption Mode", + "Read Class of Device", + "Write Class of Device", + "Read Voice Setting", + "Write Voice Setting", + "Read Automatic Flush Timeout", + "Write Automatic Flush Timeout", + "Read Num Broadcast Retransmissions", + "Write Num Broadcast Retransmissions", + "Read Hold Mode Activity ", + "Write Hold Mode Activity", + "Read Transmit Power Level", + "Read Synchronous Flow Control Enable", + "Write Synchronous Flow Control Enable", + "Unknown", + "Set Host Controller To Host Flow Control", + "Unknown", + "Host Buffer Size", + "Unknown", + "Host Number of Completed Packets", + "Read Link Supervision Timeout", + "Write Link Supervision Timeout", + "Read Number of Supported IAC", + "Read Current IAC LAP", + "Write Current IAC LAP", + "Read Page Scan Period Mode", + "Write Page Scan Period Mode", + "Read Page Scan Mode", + "Write Page Scan Mode", + "Set AFH Host Channel Classification", + "Unknown", + "Unknown", + "Read Inquiry Scan Type", + "Write Inquiry Scan Type", + "Read Inquiry Mode", + "Write Inquiry Mode", + "Read Page Scan Type", + "Write Page Scan Type", + "Read AFH Channel Assessment Mode", + "Write AFH Channel Assessment Mode", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Read Extended Inquiry Response", + "Write Extended Inquiry Response", + "Refresh Encryption Key", + "Unknown", + "Read Simple Pairing Mode", + "Write Simple Pairing Mode", + "Read Local OOB Data", + "Read Inquiry Response Transmit Power Level", + "Write Inquiry Response Transmit Power Level", + "Read Default Erroneous Data Reporting", + "Write Default Erroneous Data Reporting", + "Unknown", + "Unknown", + "Unknown", + "Enhanced Flush" + "Unknown", +}; + +#define CMD_INFO_NUM 9 +static char *cmd_info_str[CMD_INFO_NUM + 1] = { + "Unknown", + "Read Local Version Information", + "Read Local Supported Commands", + "Read Local Supported Features", + "Read Local Extended Features", + "Read Buffer Size", + "Unknown", + "Read Country Code", + "Unknown", + "Read BD ADDR", +}; + +#define CMD_STATUS_NUM 7 +static char *cmd_status_str[CMD_STATUS_NUM + 1] = { + "Unknown", + "Read Failed Contact Counter", + "Reset Failed Contact Counter", + "Read Link Quality", + "Unknown", + "Read RSSI", + "Read AFH Channel Map", + "Read Clock", +}; + +#define CMD_TESTING_NUM 4 +static char *cmd_testing_str[CMD_TESTING_NUM + 1] = { + "Unknown", + "Read Loopback Mode", + "Write Loopback Mode", + "Enable Device Under Test mode", + "Unknown", +}; + +#define ERROR_CODE_NUM 56 +static char *error_code_str[ERROR_CODE_NUM + 1] = { + "Success", + "Unknown HCI Command", + "Unknown Connection Identifier", + "Hardware Failure", + "Page Timeout", + "Authentication Failure", + "PIN or Key Missing", + "Memory Capacity Exceeded", + "Connection Timeout", + "Connection Limit Exceeded", + "Synchronous Connection to a Device Exceeded", + "ACL Connection Already Exists", + "Command Disallowed", + "Connection Rejected due to Limited Resources", + "Connection Rejected due to Security Reasons", + "Connection Rejected due to Unacceptable BD_ADDR", + "Connection Accept Timeout Exceeded", + "Unsupported Feature or Parameter Value", + "Invalid HCI Command Parameters", + "Remote User Terminated Connection", + "Remote Device Terminated Connection due to Low Resources", + "Remote Device Terminated Connection due to Power Off", + "Connection Terminated by Local Host", + "Repeated Attempts", + "Pairing Not Allowed", + "Unknown LMP PDU", + "Unsupported Remote Feature / Unsupported LMP Feature", + "SCO Offset Rejected", + "SCO Interval Rejected", + "SCO Air Mode Rejected", + "Invalid LMP Parameters", + "Unspecified Error", + "Unsupported LMP Parameter Value", + "Role Change Not Allowed", + "LMP Response Timeout", + "LMP Error Transaction Collision", + "LMP PDU Not Allowed", + "Encryption Mode Not Acceptable", + "Link Key Can Not be Changed", + "Requested QoS Not Supported", + "Instant Passed", + "Pairing with Unit Key Not Supported", + "Different Transaction Collision", + "Reserved", + "QoS Unacceptable Parameter", + "QoS Rejected", + "Channel Classification Not Supported", + "Insufficient Security", + "Parameter out of Mandatory Range", + "Reserved", + "Role Switch Pending", + "Reserved", + "Reserved Slot Violation", + "Role Switch Failed", + "Extended Inquiry Response Too Large", + "Simple Pairing Not Supported by Host", + "Host Busy - Pairing", +}; + +static char *status2str(uint8_t status) +{ + char *str; + + if (status <= ERROR_CODE_NUM) + str = error_code_str[status]; + else + str = "Unknown"; + + return str; +} + +static char *opcode2str(uint16_t opcode) +{ + uint16_t ogf = cmd_opcode_ogf(opcode); + uint16_t ocf = cmd_opcode_ocf(opcode); + char *cmd; + + switch (ogf) { + case OGF_INFO_PARAM: + if (ocf <= CMD_INFO_NUM) + cmd = cmd_info_str[ocf]; + else + cmd = "Unknown"; + break; + + case OGF_HOST_CTL: + if (ocf <= CMD_HOSTCTL_NUM) + cmd = cmd_hostctl_str[ocf]; + else + cmd = "Unknown"; + break; + + case OGF_LINK_CTL: + if (ocf <= CMD_LINKCTL_NUM) + cmd = cmd_linkctl_str[ocf]; + else + cmd = "Unknown"; + break; + + case OGF_LINK_POLICY: + if (ocf <= CMD_LINKPOL_NUM) + cmd = cmd_linkpol_str[ocf]; + else + cmd = "Unknown"; + break; + + case OGF_STATUS_PARAM: + if (ocf <= CMD_STATUS_NUM) + cmd = cmd_status_str[ocf]; + else + cmd = "Unknown"; + break; + + case OGF_TESTING_CMD: + if (ocf <= CMD_TESTING_NUM) + cmd = cmd_testing_str[ocf]; + else + cmd = "Unknown"; + break; + + case OGF_VENDOR_CMD: + cmd = "Vendor"; + break; + + default: + cmd = "Unknown"; + break; + } + + return cmd; +} + +static char *linktype2str(uint8_t type) +{ + switch (type) { + case 0x00: + return "SCO"; + case 0x01: + return "ACL"; + case 0x02: + return "eSCO"; + default: + return "Unknown"; + } +} + +static char *role2str(uint8_t role) +{ + switch (role) { + case 0x00: + return "Master"; + case 0x01: + return "Slave"; + default: + return "Unknown"; + } +} + +static char *mode2str(uint8_t mode) +{ + switch (mode) { + case 0x00: + return "Active"; + case 0x01: + return "Hold"; + case 0x02: + return "Sniff"; + case 0x03: + return "Park"; + default: + return "Unknown"; + } +} + +static char *airmode2str(uint8_t mode) +{ + switch (mode) { + case 0x00: + return "u-law log"; + case 0x01: + return "A-law log"; + case 0x02: + return "CVSD"; + case 0x04: + return "Transparent data"; + default: + return "Reserved"; + } +} + +static char *keytype2str(uint8_t type) +{ + switch (type) { + case 0x00: + return "Combination Key"; + case 0x01: + return "Local Unit Key"; + case 0x02: + return "Remote Unit Key"; + case 0x03: + return "Debug Combination Key"; + case 0x04: + return "Unauthenticated Combination Key"; + case 0x05: + return "Authenticated Combination Key"; + case 0x06: + return "Changed Combination Key"; + default: + return "Reserved"; + } +} + +static char *capability2str(uint8_t capability) +{ + switch (capability) { + case 0x00: + return "DisplayOnly"; + case 0x01: + return "DisplayYesNo"; + case 0x02: + return "KeyboardOnly"; + case 0x03: + return "NoInputNoOutput"; + default: + return "Reserved"; + } +} + +static char *authentication2str(uint8_t authentication) +{ + switch (authentication) { + case 0x00: + return "No Bonding (No MITM Protection)"; + case 0x01: + return "No Bonding (MITM Protection)"; + case 0x02: + return "Dedicated Bonding (No MITM Protection)"; + case 0x03: + return "Dedicated Bonding (MITM Protection)"; + case 0x04: + return "General Bonding (No MITM Protection)"; + case 0x05: + return "General Bonding (MITM Protection)"; + default: + return "Reserved"; + } +} + +static inline void ext_inquiry_response_dump(int level, struct frame *frm) +{ + void *ptr = frm->ptr; + uint32_t len = frm->len; + uint8_t type, length; + char *str; + int i; + + length = get_u8(frm); + + while (length > 0) { + type = get_u8(frm); + length--; + + switch (type) { + case 0x01: + p_indent(level, frm); + printf("Flags:"); + for (i = 0; i < length; i++) + printf(" 0x%2.2x", *((uint8_t *) (frm->ptr + i))); + printf("\n"); + break; + + case 0x02: + case 0x03: + p_indent(level, frm); + printf("%s service classes:", + type == 0x02 ? "Shortened" : "Complete"); + for (i = 0; i < length / 2; i++) { + uint16_t val = btohs(bt_get_unaligned((uint16_t *) (frm->ptr + (i * 2)))); + printf(" 0x%4.4x", val); + } + printf("\n"); + break; + + case 0x08: + case 0x09: + str = malloc(length + 1); + if (str) { + snprintf(str, length + 1, "%s", (char *) frm->ptr); + for (i = 0; i < length; i++) + if (!isprint(str[i])) + str[i] = '.'; + p_indent(level, frm); + printf("%s local name: \'%s\'\n", + type == 0x08 ? "Shortened" : "Complete", str); + free(str); + } + break; + + case 0x0a: + p_indent(level, frm); + printf("TX power level: %d\n", *((uint8_t *) frm->ptr)); + break; + + default: + p_indent(level, frm); + printf("Unknown type 0x%02x with %d bytes data\n", + type, length); + break; + } + + frm->ptr += length; + frm->len -= length; + + length = get_u8(frm); + } + + frm->ptr = ptr + (EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE); + frm->len = len + (EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE); +} + +static inline void bdaddr_command_dump(int level, struct frame *frm) +{ + bdaddr_t *bdaddr = frm->ptr; + char addr[18]; + + frm->ptr += sizeof(bdaddr_t); + frm->len -= sizeof(bdaddr_t); + + p_indent(level, frm); + p_ba2str(bdaddr, addr); + printf("bdaddr %s\n", addr); + + raw_dump(level, frm); +} + +static inline void generic_command_dump(int level, struct frame *frm) +{ + uint16_t handle = btohs(htons(get_u16(frm))); + + p_indent(level, frm); + printf("handle %d\n", handle); + + raw_dump(level, frm); +} + +static inline void generic_write_mode_dump(int level, struct frame *frm) +{ + uint8_t mode = get_u8(frm); + + p_indent(level, frm); + printf("mode 0x%2.2x\n", mode); +} + +static inline void inquiry_dump(int level, struct frame *frm) +{ + inquiry_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("lap 0x%2.2x%2.2x%2.2x len %d num %d\n", + cp->lap[2], cp->lap[1], cp->lap[0], cp->length, cp->num_rsp); +} + +static inline void periodic_inquiry_dump(int level, struct frame *frm) +{ + periodic_inquiry_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("max %d min %d lap 0x%2.2x%2.2x%2.2x len %d num %d\n", + btohs(cp->max_period), btohs(cp->min_period), + cp->lap[2], cp->lap[1], cp->lap[0], cp->length, cp->num_rsp); +} + +static inline void create_conn_dump(int level, struct frame *frm) +{ + create_conn_cp *cp = frm->ptr; + uint16_t ptype = btohs(cp->pkt_type); + uint16_t clkoffset = btohs(cp->clock_offset); + char addr[18], *str; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s ptype 0x%4.4x rswitch 0x%2.2x clkoffset 0x%4.4x%s\n", + addr, ptype, cp->role_switch, + clkoffset & 0x7fff, clkoffset & 0x8000 ? " (valid)" : ""); + + str = hci_ptypetostr(ptype); + if (str) { + p_indent(level, frm); + printf("Packet type: %s\n", str); + free(str); + } +} + +static inline void disconnect_dump(int level, struct frame *frm) +{ + disconnect_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d reason 0x%2.2x\n", btohs(cp->handle), cp->reason); + + p_indent(level, frm); + printf("Reason: %s\n", status2str(cp->reason)); +} + +static inline void add_sco_dump(int level, struct frame *frm) +{ + add_sco_cp *cp = frm->ptr; + uint16_t ptype = btohs(cp->pkt_type); + char *str; + + p_indent(level, frm); + printf("handle %d ptype 0x%4.4x\n", btohs(cp->handle), ptype); + + str = hci_ptypetostr(ptype); + if (str) { + p_indent(level, frm); + printf("Packet type: %s\n", str); + free(str); + } +} + +static inline void accept_conn_req_dump(int level, struct frame *frm) +{ + accept_conn_req_cp *cp = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s role 0x%2.2x\n", addr, cp->role); + + p_indent(level, frm); + printf("Role: %s\n", role2str(cp->role)); +} + +static inline void reject_conn_req_dump(int level, struct frame *frm) +{ + reject_conn_req_cp *cp = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s reason 0x%2.2x\n", addr, cp->reason); + + p_indent(level, frm); + printf("Reason: %s\n", status2str(cp->reason)); +} + +static inline void pin_code_reply_dump(int level, struct frame *frm) +{ + pin_code_reply_cp *cp = frm->ptr; + char addr[18], pin[17]; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + memset(pin, 0, sizeof(pin)); + if (parser.flags & DUMP_NOVENDOR) + memset(pin, '*', cp->pin_len); + else + memcpy(pin, cp->pin_code, cp->pin_len); + printf("bdaddr %s len %d pin \'%s\'\n", addr, cp->pin_len, pin); +} + +static inline void link_key_reply_dump(int level, struct frame *frm) +{ + link_key_reply_cp *cp = frm->ptr; + char addr[18]; + int i; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s key ", addr); + for (i = 0; i < 16; i++) + if (parser.flags & DUMP_NOVENDOR) + printf("**"); + else + printf("%2.2X", cp->link_key[i]); + printf("\n"); +} + +static inline void pin_code_neg_reply_dump(int level, struct frame *frm) +{ + bdaddr_t *bdaddr = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(bdaddr, addr); + printf("bdaddr %s\n", addr); +} + +static inline void user_passkey_reply_dump(int level, struct frame *frm) +{ + user_passkey_reply_cp *cp = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s passkey %d\n", addr, btohl(cp->passkey)); +} + +static inline void remote_oob_data_reply_dump(int level, struct frame *frm) +{ + remote_oob_data_reply_cp *cp = frm->ptr; + char addr[18]; + int i; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s\n", addr); + + p_indent(level, frm); + printf("hash 0x"); + for (i = 0; i < 16; i++) + printf("%02x", cp->hash[i]); + printf("\n"); + + p_indent(level, frm); + printf("randomizer 0x"); + for (i = 0; i < 16; i++) + printf("%02x", cp->randomizer[i]); + printf("\n"); +} + +static inline void io_capability_reply_dump(int level, struct frame *frm) +{ + io_capability_reply_cp *cp = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s capability 0x%2.2x oob 0x%2.2x auth 0x%2.2x\n", + addr, cp->capability, cp->oob_data, + cp->authentication); + + p_indent(level, frm); + printf("Capability: %s (OOB data %s)\n", + capability2str(cp->capability), + cp->oob_data == 0x00 ? "not present" : "available"); + + p_indent(level, frm); + printf("Authentication: %s\n", authentication2str(cp->authentication)); +} + +static inline void set_conn_encrypt_dump(int level, struct frame *frm) +{ + set_conn_encrypt_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d encrypt 0x%2.2x\n", btohs(cp->handle), cp->encrypt); +} + +static inline void remote_name_req_dump(int level, struct frame *frm) +{ + remote_name_req_cp *cp = frm->ptr; + uint16_t clkoffset = btohs(cp->clock_offset); + char addr[18]; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s mode %d clkoffset 0x%4.4x%s\n", + addr, cp->pscan_rep_mode, + clkoffset & 0x7fff, clkoffset & 0x8000 ? " (valid)" : ""); +} + +static inline void master_link_key_dump(int level, struct frame *frm) +{ + master_link_key_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("flag %d\n", cp->key_flag); +} + +static inline void read_remote_ext_features_dump(int level, struct frame *frm) +{ + read_remote_ext_features_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d page %d\n", btohs(cp->handle), cp->page_num); +} + +static inline void setup_sync_conn_dump(int level, struct frame *frm) +{ + setup_sync_conn_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d voice setting 0x%4.4x\n", btohs(cp->handle), + btohs(cp->voice_setting)); +} + +static inline void hold_mode_dump(int level, struct frame *frm) +{ + hold_mode_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d max %d min %d\n", btohs(cp->handle), + btohs(cp->max_interval), btohs(cp->min_interval)); +} + +static inline void sniff_mode_dump(int level, struct frame *frm) +{ + sniff_mode_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d max %d min %d attempt %d timeout %d\n", + btohs(cp->handle), btohs(cp->max_interval), + btohs(cp->min_interval), btohs(cp->attempt), btohs(cp->timeout)); +} + +static inline void qos_setup_dump(int level, struct frame *frm) +{ + qos_setup_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d flags 0x%2.2x\n", btohs(cp->handle), cp->flags); + + p_indent(level, frm); + printf("Service type: %d\n", cp->qos.service_type); + p_indent(level, frm); + printf("Token rate: %d\n", btohl(cp->qos.token_rate)); + p_indent(level, frm); + printf("Peak bandwith: %d\n", btohl(cp->qos.peak_bandwidth)); + p_indent(level, frm); + printf("Latency: %d\n", btohl(cp->qos.latency)); + p_indent(level, frm); + printf("Delay variation: %d\n", btohl(cp->qos.delay_variation)); +} + +static inline void write_link_policy_dump(int level, struct frame *frm) +{ + write_link_policy_cp *cp = frm->ptr; + uint16_t policy = btohs(cp->policy); + char *str; + + p_indent(level, frm); + printf("handle %d policy 0x%2.2x\n", btohs(cp->handle), policy); + + str = hci_lptostr(policy); + if (str) { + p_indent(level, frm); + printf("Link policy: %s\n", str); + free(str); + } +} + +static inline void sniff_subrating_dump(int level, struct frame *frm) +{ + sniff_subrating_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d\n", btohs(cp->handle)); + + p_indent(level, frm); + printf("max latency %d\n", btohs(cp->max_latency)); + + p_indent(level, frm); + printf("min timeout remote %d local %d\n", + btohs(cp->min_remote_timeout), btohs(cp->min_local_timeout)); +} + +static inline void set_event_mask_dump(int level, struct frame *frm) +{ + set_event_mask_cp *cp = frm->ptr; + int i; + + p_indent(level, frm); + printf("Mask: 0x"); + for (i = 0; i < 8; i++) + printf("%2.2x", cp->mask[i]); + printf("\n"); +} + +static inline void set_event_flt_dump(int level, struct frame *frm) +{ + set_event_flt_cp *cp = frm->ptr; + uint8_t dev_class[3], dev_mask[3]; + char addr[18]; + + p_indent(level, frm); + printf("type %d condition %d\n", cp->flt_type, + (cp->flt_type == 0) ? 0 : cp->cond_type); + + switch (cp->flt_type) { + case FLT_CLEAR_ALL: + p_indent(level, frm); + printf("Clear all filters\n"); + break; + case FLT_INQ_RESULT: + p_indent(level, frm); + printf("Inquiry result"); + switch (cp->cond_type) { + case INQ_RESULT_RETURN_ALL: + printf(" for all devices\n"); + break; + case INQ_RESULT_RETURN_CLASS: + memcpy(dev_class, cp->condition, 3); + memcpy(dev_mask, cp->condition + 3, 3); + printf(" with class 0x%2.2x%2.2x%2.2x mask 0x%2.2x%2.2x%2.2x\n", + dev_class[2], dev_class[1], dev_class[0], + dev_mask[2], dev_mask[1], dev_mask[0]); + break; + case INQ_RESULT_RETURN_BDADDR: + p_ba2str((bdaddr_t *) cp->condition, addr); + printf(" with bdaddr %s\n", addr); + break; + default: + printf("\n"); + break; + } + break; + case FLT_CONN_SETUP: + p_indent(level, frm); + printf("Connection setup"); + switch (cp->cond_type) { + case CONN_SETUP_ALLOW_ALL: + case CONN_SETUP_ALLOW_CLASS: + case CONN_SETUP_ALLOW_BDADDR: + default: + printf("\n"); + break; + } + break; + } +} + +static inline void write_pin_type_dump(int level, struct frame *frm) +{ + write_pin_type_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("type %d\n", cp->pin_type); +} + +static inline void request_stored_link_key_dump(int level, struct frame *frm) +{ + read_stored_link_key_cp *cp = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s all %d\n", addr, cp->read_all); +} + +static inline void return_link_keys_dump(int level, struct frame *frm) +{ + uint8_t num = get_u8(frm); + uint8_t key[16]; + char addr[18]; + int i, n; + + for (n = 0; n < num; n++) { + p_ba2str(frm->ptr, addr); + memcpy(key, frm->ptr + 6, 16); + + p_indent(level, frm); + printf("bdaddr %s key ", addr); + for (i = 0; i < 16; i++) + if (parser.flags & DUMP_NOVENDOR) + printf("**"); + else + printf("%2.2X", key[i]); + printf("\n"); + + frm->ptr += 2; + frm->len -= 2; + } +} + +static inline void change_local_name_dump(int level, struct frame *frm) +{ + change_local_name_cp *cp = frm->ptr; + char name[249]; + int i; + + memset(name, 0, sizeof(name)); + for (i = 0; i < 248 && cp->name[i]; i++) + if (isprint(cp->name[i])) + name[i] = cp->name[i]; + else + name[i] = '.'; + + p_indent(level, frm); + printf("name \'%s\'\n", name); +} + +static inline void write_class_of_dev_dump(int level, struct frame *frm) +{ + write_class_of_dev_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("class 0x%2.2x%2.2x%2.2x\n", + cp->dev_class[2], cp->dev_class[1], cp->dev_class[0]); +} + +static inline void write_voice_setting_dump(int level, struct frame *frm) +{ + write_voice_setting_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("voice setting 0x%4.4x\n", btohs(cp->voice_setting)); +} + +static inline void write_current_iac_lap_dump(int level, struct frame *frm) +{ + write_current_iac_lap_cp *cp = frm->ptr; + int i; + + for (i = 0; i < cp->num_current_iac; i++) { + p_indent(level, frm); + printf("IAC 0x%2.2x%2.2x%2.2x", cp->lap[i][2], cp->lap[i][1], cp->lap[i][0]); + if (cp->lap[i][2] == 0x9e && cp->lap[i][1] == 0x8b) { + switch (cp->lap[i][0]) { + case 0x00: + printf(" (Limited Inquiry Access Code)"); + break; + case 0x33: + printf(" (General Inquiry Access Code)"); + break; + } + } + printf("\n"); + } +} + +static inline void write_scan_enable_dump(int level, struct frame *frm) +{ + uint8_t enable = get_u8(frm); + + p_indent(level, frm); + printf("enable %d\n", enable); +} + +static inline void write_page_timeout_dump(int level, struct frame *frm) +{ + write_page_timeout_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("timeout %d\n", btohs(cp->timeout)); +} + +static inline void write_page_activity_dump(int level, struct frame *frm) +{ + write_page_activity_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("interval %d window %d\n", btohs(cp->interval), btohs(cp->window)); +} + +static inline void write_inquiry_scan_type_dump(int level, struct frame *frm) +{ + write_inquiry_scan_type_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("type %d\n", cp->type); +} + +static inline void write_inquiry_mode_dump(int level, struct frame *frm) +{ + write_inquiry_mode_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("mode %d\n", cp->mode); +} + +static inline void set_afh_classification_dump(int level, struct frame *frm) +{ + set_afh_classification_cp *cp = frm->ptr; + int i; + + p_indent(level, frm); + printf("map 0x"); + for (i = 0; i < 10; i++) + printf("%02x", cp->map[i]); + printf("\n"); +} + +static inline void write_link_supervision_timeout_dump(int level, struct frame *frm) +{ + write_link_supervision_timeout_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d timeout %d\n", + btohs(cp->handle), btohs(cp->timeout)); +} + +static inline void write_ext_inquiry_response_dump(int level, struct frame *frm) +{ + write_ext_inquiry_response_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("fec 0x%2.2x\n", cp->fec); + + frm->ptr++; + frm->len--; + + ext_inquiry_response_dump(level, frm); +} + +static inline void write_inquiry_transmit_power_level_dump(int level, struct frame *frm) +{ + write_inquiry_transmit_power_level_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("level %d\n", cp->level); +} + +static inline void write_default_error_data_reporting_dump(int level, struct frame *frm) +{ + write_default_error_data_reporting_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("reporting %d\n", cp->reporting); +} + +static inline void enhanced_flush_dump(int level, struct frame *frm) +{ + enhanced_flush_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d type %d\n", btohs(cp->handle), cp->type); +} + +static inline void send_keypress_notify_dump(int level, struct frame *frm) +{ + send_keypress_notify_cp *cp = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&cp->bdaddr, addr); + printf("bdaddr %s type %d\n", addr, cp->type); +} + +static inline void request_transmit_power_level_dump(int level, struct frame *frm) +{ + read_transmit_power_level_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d type %d (%s)\n", + btohs(cp->handle), cp->type, + cp->type ? "maximum" : "current"); +} + +static inline void request_local_ext_features_dump(int level, struct frame *frm) +{ + read_local_ext_features_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("page %d\n", cp->page_num); +} + +static inline void request_clock_dump(int level, struct frame *frm) +{ + read_clock_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("handle %d which %d (%s)\n", + btohs(cp->handle), cp->which_clock, + cp->which_clock ? "piconet" : "local"); +} + +static inline void host_buffer_size_dump(int level, struct frame *frm) +{ + host_buffer_size_cp *cp = frm->ptr; + + p_indent(level, frm); + printf("ACL MTU %d:%d SCO MTU %d:%d\n", + btohs(cp->acl_mtu), btohs(cp->acl_max_pkt), + cp->sco_mtu, btohs(cp->sco_max_pkt)); +} + +static inline void num_comp_pkts_dump(int level, struct frame *frm) +{ + uint8_t num = get_u8(frm); + uint16_t handle, packets; + int i; + + for (i = 0; i < num; i++) { + handle = btohs(htons(get_u16(frm))); + packets = btohs(htons(get_u16(frm))); + + p_indent(level, frm); + printf("handle %d packets %d\n", handle, packets); + } +} + +static inline void command_dump(int level, struct frame *frm) +{ + hci_command_hdr *hdr = frm->ptr; + uint16_t opcode = btohs(hdr->opcode); + uint16_t ogf = cmd_opcode_ogf(opcode); + uint16_t ocf = cmd_opcode_ocf(opcode); + + if (p_filter(FILT_HCI)) + return; + + if (ogf == OGF_VENDOR_CMD && (parser.flags & DUMP_NOVENDOR)) + return; + + p_indent(level, frm); + printf("HCI Command: %s (0x%2.2x|0x%4.4x) plen %d\n", + opcode2str(opcode), ogf, ocf, hdr->plen); + + frm->ptr += HCI_COMMAND_HDR_SIZE; + frm->len -= HCI_COMMAND_HDR_SIZE; + + if (ogf == OGF_VENDOR_CMD) { + if (ocf == 0 && get_manufacturer() == 10) { + csr_dump(level + 1, frm); + return; + } + } + + if (!(parser.flags & DUMP_VERBOSE)) { + raw_dump(level, frm); + return; + } + + switch (ogf) { + case OGF_LINK_CTL: + switch (ocf) { + case OCF_INQUIRY: + inquiry_dump(level + 1, frm); + return; + case OCF_PERIODIC_INQUIRY: + periodic_inquiry_dump(level + 1, frm); + return; + case OCF_INQUIRY_CANCEL: + case OCF_EXIT_PERIODIC_INQUIRY: + return; + case OCF_CREATE_CONN: + create_conn_dump(level + 1, frm); + return; + case OCF_DISCONNECT: + disconnect_dump(level + 1, frm); + return; + case OCF_CREATE_CONN_CANCEL: + case OCF_REMOTE_NAME_REQ_CANCEL: + case OCF_ACCEPT_SYNC_CONN_REQ: + bdaddr_command_dump(level + 1, frm); + return; + case OCF_ADD_SCO: + case OCF_SET_CONN_PTYPE: + add_sco_dump(level + 1, frm); + return; + case OCF_ACCEPT_CONN_REQ: + accept_conn_req_dump(level + 1, frm); + return; + case OCF_REJECT_CONN_REQ: + case OCF_REJECT_SYNC_CONN_REQ: + case OCF_IO_CAPABILITY_NEG_REPLY: + reject_conn_req_dump(level + 1, frm); + return; + case OCF_PIN_CODE_REPLY: + pin_code_reply_dump(level + 1, frm); + return; + case OCF_LINK_KEY_REPLY: + link_key_reply_dump(level + 1, frm); + return; + case OCF_PIN_CODE_NEG_REPLY: + case OCF_LINK_KEY_NEG_REPLY: + case OCF_USER_CONFIRM_REPLY: + case OCF_USER_CONFIRM_NEG_REPLY: + case OCF_USER_PASSKEY_NEG_REPLY: + case OCF_REMOTE_OOB_DATA_NEG_REPLY: + pin_code_neg_reply_dump(level + 1, frm); + return; + case OCF_USER_PASSKEY_REPLY: + user_passkey_reply_dump(level + 1, frm); + return; + case OCF_REMOTE_OOB_DATA_REPLY: + remote_oob_data_reply_dump(level + 1, frm); + return; + case OCF_IO_CAPABILITY_REPLY: + io_capability_reply_dump(level + 1, frm); + return; + case OCF_SET_CONN_ENCRYPT: + set_conn_encrypt_dump(level + 1, frm); + return; + case OCF_AUTH_REQUESTED: + case OCF_CHANGE_CONN_LINK_KEY: + case OCF_READ_REMOTE_FEATURES: + case OCF_READ_REMOTE_VERSION: + case OCF_READ_CLOCK_OFFSET: + case OCF_READ_LMP_HANDLE: + generic_command_dump(level + 1, frm); + return; + case OCF_MASTER_LINK_KEY: + master_link_key_dump(level + 1, frm); + return; + case OCF_READ_REMOTE_EXT_FEATURES: + read_remote_ext_features_dump(level + 1, frm); + return; + case OCF_REMOTE_NAME_REQ: + remote_name_req_dump(level + 1, frm); + return; + case OCF_SETUP_SYNC_CONN: + setup_sync_conn_dump(level + 1, frm); + return; + } + break; + + case OGF_LINK_POLICY: + switch (ocf) { + case OCF_HOLD_MODE: + case OCF_PARK_MODE: + hold_mode_dump(level + 1, frm); + return; + case OCF_SNIFF_MODE: + sniff_mode_dump(level + 1, frm); + return; + case OCF_EXIT_SNIFF_MODE: + case OCF_EXIT_PARK_MODE: + case OCF_ROLE_DISCOVERY: + case OCF_READ_LINK_POLICY: + generic_command_dump(level + 1, frm); + return; + case OCF_SWITCH_ROLE: + accept_conn_req_dump(level + 1, frm); + return; + case OCF_QOS_SETUP: + qos_setup_dump(level + 1, frm); + return; + case OCF_WRITE_LINK_POLICY: + write_link_policy_dump(level + 1, frm); + return; + case OCF_SNIFF_SUBRATING: + sniff_subrating_dump(level + 1, frm); + return; + } + break; + + case OGF_HOST_CTL: + switch (ocf) { + case OCF_RESET: + case OCF_CREATE_NEW_UNIT_KEY: + return; + case OCF_SET_EVENT_MASK: + set_event_mask_dump(level + 1, frm); + return; + case OCF_SET_EVENT_FLT: + set_event_flt_dump(level + 1, frm); + return; + case OCF_WRITE_PIN_TYPE: + write_pin_type_dump(level + 1, frm); + return; + case OCF_READ_STORED_LINK_KEY: + case OCF_DELETE_STORED_LINK_KEY: + request_stored_link_key_dump(level + 1, frm); + return; + case OCF_WRITE_STORED_LINK_KEY: + return_link_keys_dump(level + 1, frm); + return; + case OCF_CHANGE_LOCAL_NAME: + change_local_name_dump(level + 1, frm); + return; + case OCF_WRITE_CLASS_OF_DEV: + write_class_of_dev_dump(level + 1, frm); + return; + case OCF_WRITE_VOICE_SETTING: + write_voice_setting_dump(level + 1, frm); + return; + case OCF_WRITE_CURRENT_IAC_LAP: + write_current_iac_lap_dump(level + 1, frm); + return; + case OCF_WRITE_SCAN_ENABLE: + case OCF_WRITE_AUTH_ENABLE: + case OCF_SET_CONTROLLER_TO_HOST_FC: + write_scan_enable_dump(level + 1, frm); + return; + case OCF_WRITE_CONN_ACCEPT_TIMEOUT: + case OCF_WRITE_PAGE_TIMEOUT: + write_page_timeout_dump(level + 1, frm); + return; + case OCF_WRITE_PAGE_ACTIVITY: + case OCF_WRITE_INQ_ACTIVITY: + write_page_activity_dump(level + 1, frm); + return; + case OCF_WRITE_INQUIRY_SCAN_TYPE: + write_inquiry_scan_type_dump(level + 1, frm); + return; + case OCF_WRITE_ENCRYPT_MODE: + case OCF_WRITE_INQUIRY_MODE: + case OCF_WRITE_AFH_MODE: + write_inquiry_mode_dump(level + 1, frm); + return; + case OCF_SET_AFH_CLASSIFICATION: + set_afh_classification_dump(level + 1, frm); + return; + case OCF_READ_TRANSMIT_POWER_LEVEL: + request_transmit_power_level_dump(level + 1, frm); + return; + case OCF_HOST_BUFFER_SIZE: + host_buffer_size_dump(level + 1, frm); + return; + case OCF_HOST_NUM_COMP_PKTS: + num_comp_pkts_dump(level + 1, frm); + return; + case OCF_FLUSH: + case OCF_READ_LINK_SUPERVISION_TIMEOUT: + case OCF_REFRESH_ENCRYPTION_KEY: + generic_command_dump(level + 1, frm); + return; + case OCF_WRITE_LINK_SUPERVISION_TIMEOUT: + write_link_supervision_timeout_dump(level + 1, frm); + return; + case OCF_WRITE_EXT_INQUIRY_RESPONSE: + write_ext_inquiry_response_dump(level + 1, frm); + return; + case OCF_WRITE_SIMPLE_PAIRING_MODE: + generic_write_mode_dump(level + 1, frm); + return; + case OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL: + write_inquiry_transmit_power_level_dump(level + 1, frm); + return; + case OCF_WRITE_DEFAULT_ERROR_DATA_REPORTING: + write_default_error_data_reporting_dump(level + 1, frm); + return; + case OCF_ENHANCED_FLUSH: + enhanced_flush_dump(level + 1, frm); + return; + case OCF_SEND_KEYPRESS_NOTIFY: + send_keypress_notify_dump(level + 1, frm); + return; + } + break; + + case OGF_INFO_PARAM: + switch (ocf) { + case OCF_READ_LOCAL_EXT_FEATURES: + request_local_ext_features_dump(level + 1, frm); + return; + } + break; + + case OGF_STATUS_PARAM: + switch (ocf) { + case OCF_READ_LINK_QUALITY: + case OCF_READ_RSSI: + case OCF_READ_AFH_MAP: + generic_command_dump(level + 1, frm); + return; + case OCF_READ_CLOCK: + request_clock_dump(level + 1, frm); + return; + } + break; + + case OGF_TESTING_CMD: + switch (ocf) { + case OCF_WRITE_LOOPBACK_MODE: + case OCF_WRITE_SIMPLE_PAIRING_DEBUG_MODE: + generic_write_mode_dump(level + 1, frm); + return; + } + break; + } + + raw_dump(level, frm); +} + +static inline void status_response_dump(int level, struct frame *frm) +{ + uint8_t status = get_u8(frm); + + p_indent(level, frm); + printf("status 0x%2.2x\n", status); + + if (status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(status)); + } + + raw_dump(level, frm); +} + +static inline void handle_response_dump(int level, struct frame *frm) +{ + uint16_t handle = btohs(htons(get_u16(frm))); + + p_indent(level, frm); + printf("handle %d\n", handle); + + raw_dump(level, frm); +} + +static inline void bdaddr_response_dump(int level, struct frame *frm) +{ + uint8_t status = get_u8(frm); + bdaddr_t *bdaddr = frm->ptr; + char addr[18]; + + frm->ptr += sizeof(bdaddr_t); + frm->len -= sizeof(bdaddr_t); + + p_indent(level, frm); + p_ba2str(bdaddr, addr); + printf("status 0x%2.2x bdaddr %s\n", status, addr); + + if (status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(status)); + } + + raw_dump(level, frm); +} + +static inline void generic_response_dump(int level, struct frame *frm) +{ + uint8_t status = get_u8(frm); + uint16_t handle = btohs(htons(get_u16(frm))); + + p_indent(level, frm); + printf("status 0x%2.2x handle %d\n", status, handle); + + if (status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(status)); + } + + raw_dump(level, frm); +} + +static inline void status_mode_dump(int level, struct frame *frm) +{ + uint8_t status = get_u8(frm); + uint8_t mode = get_u8(frm); + + p_indent(level, frm); + printf("status 0x%2.2x mode 0x%2.2x\n", status, mode); + + if (status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(status)); + } +} + +static inline void read_pin_type_dump(int level, struct frame *frm) +{ + read_pin_type_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x type %d\n", rp->status, rp->pin_type); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_stored_link_key_dump(int level, struct frame *frm) +{ + read_stored_link_key_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x max %d num %d\n", + rp->status, rp->max_keys, rp->num_keys); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void write_stored_link_key_dump(int level, struct frame *frm) +{ + write_stored_link_key_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x written %d\n", rp->status, rp->num_keys); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void delete_stored_link_key_dump(int level, struct frame *frm) +{ + delete_stored_link_key_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x deleted %d\n", rp->status, btohs(rp->num_keys)); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_local_name_dump(int level, struct frame *frm) +{ + read_local_name_rp *rp = frm->ptr; + char name[249]; + int i; + + memset(name, 0, sizeof(name)); + for (i = 0; i < 248 && rp->name[i]; i++) + if (isprint(rp->name[i])) + name[i] = rp->name[i]; + else + name[i] = '.'; + + p_indent(level, frm); + printf("status 0x%2.2x name \'%s\'\n", rp->status, name); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_class_of_dev_dump(int level, struct frame *frm) +{ + read_class_of_dev_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x class 0x%2.2x%2.2x%2.2x\n", rp->status, + rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_voice_setting_dump(int level, struct frame *frm) +{ + read_voice_setting_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x voice setting 0x%4.4x\n", + rp->status, btohs(rp->voice_setting)); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_current_iac_lap_dump(int level, struct frame *frm) +{ + read_current_iac_lap_rp *rp = frm->ptr; + int i; + + for (i = 0; i < rp->num_current_iac; i++) { + p_indent(level, frm); + printf("IAC 0x%2.2x%2.2x%2.2x", rp->lap[i][2], rp->lap[i][1], rp->lap[i][0]); + if (rp->lap[i][2] == 0x9e && rp->lap[i][1] == 0x8b) { + switch (rp->lap[i][0]) { + case 0x00: + printf(" (Limited Inquiry Access Code)"); + break; + case 0x33: + printf(" (General Inquiry Access Code)"); + break; + } + } + printf("\n"); + } +} + +static inline void read_scan_enable_dump(int level, struct frame *frm) +{ + uint8_t status = get_u8(frm); + uint8_t enable = get_u8(frm); + + p_indent(level, frm); + printf("status 0x%2.2x enable %d\n", status, enable); + + if (status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(status)); + } +} + +static inline void read_page_timeout_dump(int level, struct frame *frm) +{ + read_page_timeout_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x timeout %d\n", rp->status, btohs(rp->timeout)); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_page_activity_dump(int level, struct frame *frm) +{ + read_page_activity_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x interval %d window %d\n", + rp->status, btohs(rp->interval), btohs(rp->window)); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_inquiry_scan_type_dump(int level, struct frame *frm) +{ + read_inquiry_scan_type_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x type %d\n", rp->status, rp->type); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_inquiry_mode_dump(int level, struct frame *frm) +{ + read_inquiry_mode_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x mode %d\n", rp->status, rp->mode); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_link_supervision_timeout_dump(int level, struct frame *frm) +{ + read_link_supervision_timeout_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d timeout %d\n", + rp->status, btohs(rp->handle), btohs(rp->timeout)); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_transmit_power_level_dump(int level, struct frame *frm) +{ + read_transmit_power_level_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d level %d\n", + rp->status, btohs(rp->handle), rp->level); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_ext_inquiry_response_dump(int level, struct frame *frm) +{ + read_ext_inquiry_response_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x fec 0x%2.2x\n", rp->status, rp->fec); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } else { + frm->ptr += 2; + frm->len -= 2; + + ext_inquiry_response_dump(level, frm); + } +} + +static inline void read_inquiry_transmit_power_level_dump(int level, struct frame *frm) +{ + read_inquiry_transmit_power_level_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x level %d\n", rp->status, rp->level); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_default_error_data_reporting_dump(int level, struct frame *frm) +{ + read_default_error_data_reporting_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x reporting %d\n", rp->status, rp->reporting); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_local_oob_data_dump(int level, struct frame *frm) +{ + read_local_oob_data_rp *rp = frm->ptr; + int i; + + p_indent(level, frm); + printf("status 0x%2.2x\n", rp->status); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } else { + p_indent(level, frm); + printf("hash 0x"); + for (i = 0; i < 16; i++) + printf("%02x", rp->hash[i]); + printf("\n"); + + p_indent(level, frm); + printf("randomizer 0x"); + for (i = 0; i < 16; i++) + printf("%02x", rp->randomizer[i]); + printf("\n"); + } +} + +static inline void read_local_version_dump(int level, struct frame *frm) +{ + read_local_version_rp *rp = frm->ptr; + uint16_t manufacturer = btohs(rp->manufacturer); + + p_indent(level, frm); + printf("status 0x%2.2x\n", rp->status); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } else { + p_indent(level, frm); + printf("HCI Version: %s (0x%x) HCI Revision: 0x%x\n", + hci_vertostr(rp->hci_ver), + rp->hci_ver, btohs(rp->hci_rev)); + p_indent(level, frm); + printf("LMP Version: %s (0x%x) LMP Subversion: 0x%x\n", + lmp_vertostr(rp->lmp_ver), + rp->lmp_ver, btohs(rp->lmp_subver)); + p_indent(level, frm); + printf("Manufacturer: %s (%d)\n", + bt_compidtostr(manufacturer), manufacturer); + } +} + +static inline void read_local_commands_dump(int level, struct frame *frm) +{ + read_local_commands_rp *rp = frm->ptr; + int i, max = 0; + + p_indent(level, frm); + printf("status 0x%2.2x\n", rp->status); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } else { + for (i = 0; i < 64; i++) + if (rp->commands[i]) + max = i + 1; + p_indent(level, frm); + printf("Commands: "); + for (i = 0; i < (max > 32 ? 32 : max); i++) + printf("%2.2x", rp->commands[i]); + printf("\n"); + if (max > 32) { + p_indent(level, frm); + printf(" "); + for (i = 32; i < max; i++) + printf("%2.2x", rp->commands[i]); + printf("\n"); + } + } +} + +static inline void read_local_features_dump(int level, struct frame *frm) +{ + read_local_features_rp *rp = frm->ptr; + int i; + + p_indent(level, frm); + printf("status 0x%2.2x\n", rp->status); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } else { + p_indent(level, frm); + printf("Features:"); + for (i = 0; i < 8; i++) + printf(" 0x%2.2x", rp->features[i]); + printf("\n"); + } +} + +static inline void read_local_ext_features_dump(int level, struct frame *frm) +{ + read_local_ext_features_rp *rp = frm->ptr; + int i; + + p_indent(level, frm); + printf("status 0x%2.2x page %d max %d\n", + rp->status, rp->page_num, rp->max_page_num); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } else { + p_indent(level, frm); + printf("Features:"); + for (i = 0; i < 8; i++) + printf(" 0x%2.2x", rp->features[i]); + printf("\n"); + } +} + +static inline void read_buffer_size_dump(int level, struct frame *frm) +{ + read_buffer_size_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x\n", rp->status); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } else { + p_indent(level, frm); + printf("ACL MTU %d:%d SCO MTU %d:%d\n", + btohs(rp->acl_mtu), btohs(rp->acl_max_pkt), + rp->sco_mtu, btohs(rp->sco_max_pkt)); + } +} + +static inline void read_link_quality_dump(int level, struct frame *frm) +{ + read_link_quality_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d lq %d\n", + rp->status, btohs(rp->handle), rp->link_quality); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_rssi_dump(int level, struct frame *frm) +{ + read_rssi_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d rssi %d\n", + rp->status, btohs(rp->handle), rp->rssi); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void read_afh_map_dump(int level, struct frame *frm) +{ + read_afh_map_rp *rp = frm->ptr; + int i; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d mode %d\n", + rp->status, btohs(rp->handle), rp->mode); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } else { + p_indent(level, frm); + printf("AFH map: 0x"); + for (i = 0; i < 10; i++) + printf("%2.2x", rp->map[i]); + printf("\n"); + } +} + +static inline void read_clock_dump(int level, struct frame *frm) +{ + read_clock_rp *rp = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d clock 0x%4.4x accuracy %d\n", + rp->status, btohs(rp->handle), + btohl(rp->clock), btohs(rp->accuracy)); + + if (rp->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(rp->status)); + } +} + +static inline void cmd_complete_dump(int level, struct frame *frm) +{ + evt_cmd_complete *evt = frm->ptr; + uint16_t opcode = btohs(evt->opcode); + uint16_t ogf = cmd_opcode_ogf(opcode); + uint16_t ocf = cmd_opcode_ocf(opcode); + + if (ogf == OGF_VENDOR_CMD && (parser.flags & DUMP_NOVENDOR)) + return; + + p_indent(level, frm); + printf("%s (0x%2.2x|0x%4.4x) ncmd %d\n", + opcode2str(opcode), ogf, ocf, evt->ncmd); + + frm->ptr += EVT_CMD_COMPLETE_SIZE; + frm->len -= EVT_CMD_COMPLETE_SIZE; + + if (!(parser.flags & DUMP_VERBOSE)) { + raw_dump(level, frm); + return; + } + + switch (ogf) { + case OGF_LINK_CTL: + switch (ocf) { + case OCF_INQUIRY_CANCEL: + case OCF_PERIODIC_INQUIRY: + case OCF_EXIT_PERIODIC_INQUIRY: + case OCF_READ_REMOTE_EXT_FEATURES: + status_response_dump(level, frm); + return; + case OCF_CREATE_CONN_CANCEL: + case OCF_REMOTE_NAME_REQ_CANCEL: + case OCF_PIN_CODE_REPLY: + case OCF_LINK_KEY_REPLY: + case OCF_PIN_CODE_NEG_REPLY: + case OCF_LINK_KEY_NEG_REPLY: + case OCF_USER_CONFIRM_REPLY: + case OCF_USER_CONFIRM_NEG_REPLY: + case OCF_USER_PASSKEY_REPLY: + case OCF_USER_PASSKEY_NEG_REPLY: + case OCF_REMOTE_OOB_DATA_REPLY: + case OCF_REMOTE_OOB_DATA_NEG_REPLY: + case OCF_IO_CAPABILITY_REPLY: + case OCF_IO_CAPABILITY_NEG_REPLY: + bdaddr_response_dump(level, frm); + return; + } + break; + + case OGF_LINK_POLICY: + switch (ocf) { + case OCF_WRITE_LINK_POLICY: + case OCF_SNIFF_SUBRATING: + generic_response_dump(level, frm); + return; + } + break; + + case OGF_HOST_CTL: + switch (ocf) { + case OCF_READ_PIN_TYPE: + read_pin_type_dump(level, frm); + return; + case OCF_READ_STORED_LINK_KEY: + read_stored_link_key_dump(level, frm); + return; + case OCF_WRITE_STORED_LINK_KEY: + write_stored_link_key_dump(level, frm); + return; + case OCF_DELETE_STORED_LINK_KEY: + delete_stored_link_key_dump(level, frm); + return; + case OCF_READ_LOCAL_NAME: + read_local_name_dump(level, frm); + return; + case OCF_READ_CLASS_OF_DEV: + read_class_of_dev_dump(level, frm); + return; + case OCF_READ_VOICE_SETTING: + read_voice_setting_dump(level, frm); + return; + case OCF_READ_CURRENT_IAC_LAP: + read_current_iac_lap_dump(level, frm); + return; + case OCF_READ_SCAN_ENABLE: + case OCF_READ_AUTH_ENABLE: + read_scan_enable_dump(level, frm); + return; + case OCF_READ_CONN_ACCEPT_TIMEOUT: + case OCF_READ_PAGE_TIMEOUT: + read_page_timeout_dump(level, frm); + return; + case OCF_READ_PAGE_ACTIVITY: + case OCF_READ_INQ_ACTIVITY: + read_page_activity_dump(level, frm); + return; + case OCF_READ_INQUIRY_SCAN_TYPE: + read_inquiry_scan_type_dump(level, frm); + return; + case OCF_READ_ENCRYPT_MODE: + case OCF_READ_INQUIRY_MODE: + case OCF_READ_AFH_MODE: + read_inquiry_mode_dump(level, frm); + return; + case OCF_READ_LINK_SUPERVISION_TIMEOUT: + read_link_supervision_timeout_dump(level, frm); + return; + case OCF_READ_TRANSMIT_POWER_LEVEL: + read_transmit_power_level_dump(level, frm); + return; + case OCF_READ_EXT_INQUIRY_RESPONSE: + read_ext_inquiry_response_dump(level, frm); + return; + case OCF_READ_INQUIRY_TRANSMIT_POWER_LEVEL: + read_inquiry_transmit_power_level_dump(level, frm); + return; + case OCF_READ_DEFAULT_ERROR_DATA_REPORTING: + read_default_error_data_reporting_dump(level, frm); + return; + case OCF_READ_LOCAL_OOB_DATA: + read_local_oob_data_dump(level, frm); + return; + case OCF_READ_SIMPLE_PAIRING_MODE: + status_mode_dump(level, frm); + return; + case OCF_FLUSH: + case OCF_WRITE_LINK_SUPERVISION_TIMEOUT: + generic_response_dump(level, frm); + return; + case OCF_RESET: + case OCF_SET_EVENT_MASK: + case OCF_SET_EVENT_FLT: + case OCF_WRITE_PIN_TYPE: + case OCF_CREATE_NEW_UNIT_KEY: + case OCF_CHANGE_LOCAL_NAME: + case OCF_WRITE_CLASS_OF_DEV: + case OCF_WRITE_VOICE_SETTING: + case OCF_WRITE_CURRENT_IAC_LAP: + case OCF_WRITE_SCAN_ENABLE: + case OCF_WRITE_AUTH_ENABLE: + case OCF_WRITE_ENCRYPT_MODE: + case OCF_WRITE_CONN_ACCEPT_TIMEOUT: + case OCF_WRITE_PAGE_TIMEOUT: + case OCF_WRITE_PAGE_ACTIVITY: + case OCF_WRITE_INQ_ACTIVITY: + case OCF_WRITE_INQUIRY_SCAN_TYPE: + case OCF_WRITE_INQUIRY_MODE: + case OCF_WRITE_AFH_MODE: + case OCF_SET_AFH_CLASSIFICATION: + case OCF_WRITE_EXT_INQUIRY_RESPONSE: + case OCF_WRITE_SIMPLE_PAIRING_MODE: + case OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL: + case OCF_WRITE_DEFAULT_ERROR_DATA_REPORTING: + case OCF_SET_CONTROLLER_TO_HOST_FC: + case OCF_HOST_BUFFER_SIZE: + case OCF_REFRESH_ENCRYPTION_KEY: + case OCF_SEND_KEYPRESS_NOTIFY: + status_response_dump(level, frm); + return; + } + break; + + case OGF_INFO_PARAM: + switch (ocf) { + case OCF_READ_LOCAL_VERSION: + read_local_version_dump(level, frm); + return; + case OCF_READ_LOCAL_COMMANDS: + read_local_commands_dump(level, frm); + return; + case OCF_READ_LOCAL_FEATURES: + read_local_features_dump(level, frm); + return; + case OCF_READ_LOCAL_EXT_FEATURES: + read_local_ext_features_dump(level, frm); + return; + case OCF_READ_BUFFER_SIZE: + read_buffer_size_dump(level, frm); + return; + case OCF_READ_BD_ADDR: + bdaddr_response_dump(level, frm); + return; + } + break; + + case OGF_STATUS_PARAM: + switch (ocf) { + case OCF_READ_FAILED_CONTACT_COUNTER: + case OCF_RESET_FAILED_CONTACT_COUNTER: + status_response_dump(level, frm); + return; + case OCF_READ_LINK_QUALITY: + read_link_quality_dump(level, frm); + return; + case OCF_READ_RSSI: + read_rssi_dump(level, frm); + return; + case OCF_READ_AFH_MAP: + read_afh_map_dump(level, frm); + return; + case OCF_READ_CLOCK: + read_clock_dump(level, frm); + return; + } + break; + + case OGF_TESTING_CMD: + switch (ocf) { + case OCF_READ_LOOPBACK_MODE: + status_mode_dump(level, frm); + return; + case OCF_WRITE_LOOPBACK_MODE: + case OCF_ENABLE_DEVICE_UNDER_TEST_MODE: + case OCF_WRITE_SIMPLE_PAIRING_DEBUG_MODE: + status_response_dump(level, frm); + return; + } + break; + } + + raw_dump(level, frm); +} + +static inline void cmd_status_dump(int level, struct frame *frm) +{ + evt_cmd_status *evt = frm->ptr; + uint16_t opcode = btohs(evt->opcode); + uint16_t ogf = cmd_opcode_ogf(opcode); + uint16_t ocf = cmd_opcode_ocf(opcode); + + if (ogf == OGF_VENDOR_CMD && (parser.flags & DUMP_NOVENDOR)) + return; + + p_indent(level, frm); + printf("%s (0x%2.2x|0x%4.4x) status 0x%2.2x ncmd %d\n", + opcode2str(opcode), ogf, ocf, evt->status, evt->ncmd); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } +} + +static inline void hardware_error_dump(int level, struct frame *frm) +{ + evt_hardware_error *evt = frm->ptr; + + p_indent(level, frm); + printf("code %d\n", evt->code); +} + +static inline void inq_result_dump(int level, struct frame *frm) +{ + uint8_t num = get_u8(frm); + char addr[18]; + int i; + + for (i = 0; i < num; i++) { + inquiry_info *info = frm->ptr; + + p_ba2str(&info->bdaddr, addr); + + p_indent(level, frm); + printf("bdaddr %s mode %d clkoffset 0x%4.4x class 0x%2.2x%2.2x%2.2x\n", + addr, info->pscan_rep_mode, btohs(info->clock_offset), + info->dev_class[2], info->dev_class[1], info->dev_class[0]); + + frm->ptr += INQUIRY_INFO_SIZE; + frm->len -= INQUIRY_INFO_SIZE; + } +} + +static inline void conn_complete_dump(int level, struct frame *frm) +{ + evt_conn_complete *evt = frm->ptr; + char addr[18]; + + p_ba2str(&evt->bdaddr, addr); + + p_indent(level, frm); + printf("status 0x%2.2x handle %d bdaddr %s type %s encrypt 0x%2.2x\n", + evt->status, btohs(evt->handle), addr, + linktype2str(evt->link_type), evt->encr_mode); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } +} + +static inline void conn_request_dump(int level, struct frame *frm) +{ + evt_conn_request *evt = frm->ptr; + char addr[18]; + + p_ba2str(&evt->bdaddr, addr); + + p_indent(level, frm); + printf("bdaddr %s class 0x%2.2x%2.2x%2.2x type %s\n", + addr, evt->dev_class[2], evt->dev_class[1], + evt->dev_class[0], linktype2str(evt->link_type)); +} + +static inline void disconn_complete_dump(int level, struct frame *frm) +{ + evt_disconn_complete *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d reason 0x%2.2x\n", + evt->status, btohs(evt->handle), evt->reason); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else if (evt->reason > 0) { + p_indent(level, frm); + printf("Reason: %s\n", status2str(evt->reason)); + } +} + +static inline void remote_name_req_complete_dump(int level, struct frame *frm) +{ + evt_remote_name_req_complete *evt = frm->ptr; + char addr[18], name[249]; + int i; + + p_ba2str(&evt->bdaddr, addr); + + memset(name, 0, sizeof(name)); + for (i = 0; i < 248 && evt->name[i]; i++) + if (isprint(evt->name[i])) + name[i] = evt->name[i]; + else + name[i] = '.'; + + p_indent(level, frm); + printf("status 0x%2.2x bdaddr %s name '%s'\n", evt->status, addr, name); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } +} + +static inline void master_link_key_complete_dump(int level, struct frame *frm) +{ + evt_master_link_key_complete *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d flag %d\n", + evt->status, btohs(evt->handle), evt->key_flag); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } +} + +static inline void encrypt_change_dump(int level, struct frame *frm) +{ + evt_encrypt_change *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d encrypt 0x%2.2x\n", + evt->status, btohs(evt->handle), evt->encrypt); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } +} + +static inline void read_remote_features_complete_dump(int level, struct frame *frm) +{ + evt_read_remote_features_complete *evt = frm->ptr; + int i; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d\n", evt->status, btohs(evt->handle)); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("Features:"); + for (i = 0; i < 8; i++) + printf(" 0x%2.2x", evt->features[i]); + printf("\n"); + } +} + +static inline void read_remote_version_complete_dump(int level, struct frame *frm) +{ + evt_read_remote_version_complete *evt = frm->ptr; + uint16_t manufacturer = btohs(evt->manufacturer); + + p_indent(level, frm); + printf("status 0x%2.2x handle %d\n", evt->status, btohs(evt->handle)); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("LMP Version: %s (0x%x) LMP Subversion: 0x%x\n", + lmp_vertostr(evt->lmp_ver), evt->lmp_ver, + btohs(evt->lmp_subver)); + p_indent(level, frm); + printf("Manufacturer: %s (%d)\n", + bt_compidtostr(manufacturer), manufacturer); + } +} + +static inline void qos_setup_complete_dump(int level, struct frame *frm) +{ + evt_qos_setup_complete *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d flags %d\n", + evt->status, btohs(evt->handle), evt->flags); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("Service type: %d\n", evt->qos.service_type); + p_indent(level, frm); + printf("Token rate: %d\n", btohl(evt->qos.token_rate)); + p_indent(level, frm); + printf("Peak bandwith: %d\n", btohl(evt->qos.peak_bandwidth)); + p_indent(level, frm); + printf("Latency: %d\n", btohl(evt->qos.latency)); + p_indent(level, frm); + printf("Delay variation: %d\n", btohl(evt->qos.delay_variation)); + } +} + +static inline void role_change_dump(int level, struct frame *frm) +{ + evt_role_change *evt = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&evt->bdaddr, addr); + printf("status 0x%2.2x bdaddr %s role 0x%2.2x\n", + evt->status, addr, evt->role); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("Role: %s\n", role2str(evt->role)); + } +} + +static inline void mode_change_dump(int level, struct frame *frm) +{ + evt_mode_change *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d mode 0x%2.2x interval %d\n", + evt->status, btohs(evt->handle), evt->mode, btohs(evt->interval)); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("Mode: %s\n", mode2str(evt->mode)); + } +} + +static inline void pin_code_req_dump(int level, struct frame *frm) +{ + evt_pin_code_req *evt = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&evt->bdaddr, addr); + printf("bdaddr %s\n", addr); +} + +static inline void link_key_notify_dump(int level, struct frame *frm) +{ + evt_link_key_notify *evt = frm->ptr; + char addr[18]; + int i; + + p_indent(level, frm); + p_ba2str(&evt->bdaddr, addr); + printf("bdaddr %s key ", addr); + for (i = 0; i < 16; i++) + if (parser.flags & DUMP_NOVENDOR) + printf("**"); + else + printf("%2.2X", evt->link_key[i]); + printf(" type %d\n", evt->key_type); + + p_indent(level, frm); + printf("Type: %s\n", keytype2str(evt->key_type)); +} + +static inline void max_slots_change_dump(int level, struct frame *frm) +{ + evt_max_slots_change *evt = frm->ptr; + + p_indent(level, frm); + printf("handle %d slots %d\n", btohs(evt->handle), evt->max_slots); +} + +static inline void data_buffer_overflow_dump(int level, struct frame *frm) +{ + evt_data_buffer_overflow *evt = frm->ptr; + + p_indent(level, frm); + printf("type %s\n", linktype2str(evt->link_type)); +} + +static inline void read_clock_offset_complete_dump(int level, struct frame *frm) +{ + evt_read_clock_offset_complete *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d clkoffset 0x%4.4x\n", + evt->status, btohs(evt->handle), btohs(evt->clock_offset)); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } +} + +static inline void conn_ptype_changed_dump(int level, struct frame *frm) +{ + evt_conn_ptype_changed *evt = frm->ptr; + uint16_t ptype = btohs(evt->ptype); + char *str; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d ptype 0x%4.4x\n", + evt->status, btohs(evt->handle), ptype); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + str = hci_ptypetostr(ptype); + if (str) { + p_indent(level, frm); + printf("Packet type: %s\n", str); + free(str); + } + } +} + +static inline void pscan_rep_mode_change_dump(int level, struct frame *frm) +{ + evt_pscan_rep_mode_change *evt = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&evt->bdaddr, addr); + printf("bdaddr %s mode %d\n", addr, evt->pscan_rep_mode); +} + +static inline void flow_spec_complete_dump(int level, struct frame *frm) +{ + evt_flow_spec_complete *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d flags %d %s\n", + evt->status, btohs(evt->handle), evt->flags, + evt->direction == 0 ? "outgoing" : "incoming"); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("Service type: %d\n", evt->qos.service_type); + p_indent(level, frm); + printf("Token rate: %d\n", btohl(evt->qos.token_rate)); + p_indent(level, frm); + printf("Peak bandwith: %d\n", btohl(evt->qos.peak_bandwidth)); + p_indent(level, frm); + printf("Latency: %d\n", btohl(evt->qos.latency)); + p_indent(level, frm); + printf("Delay variation: %d\n", btohl(evt->qos.delay_variation)); + } +} + +static inline void inq_result_with_rssi_dump(int level, struct frame *frm) +{ + uint8_t num = get_u8(frm); + char addr[18]; + int i; + + if (!num) + return; + + if (frm->len / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { + for (i = 0; i < num; i++) { + inquiry_info_with_rssi_and_pscan_mode *info = frm->ptr; + + p_indent(level, frm); + + p_ba2str(&info->bdaddr, addr); + printf("bdaddr %s mode %d clkoffset 0x%4.4x class 0x%2.2x%2.2x%2.2x rssi %d\n", + addr, info->pscan_rep_mode, btohs(info->clock_offset), + info->dev_class[2], info->dev_class[1], info->dev_class[0], info->rssi); + + frm->ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; + frm->len -= INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; + } + } else { + for (i = 0; i < num; i++) { + inquiry_info_with_rssi *info = frm->ptr; + + p_indent(level, frm); + + p_ba2str(&info->bdaddr, addr); + printf("bdaddr %s mode %d clkoffset 0x%4.4x class 0x%2.2x%2.2x%2.2x rssi %d\n", + addr, info->pscan_rep_mode, btohs(info->clock_offset), + info->dev_class[2], info->dev_class[1], info->dev_class[0], info->rssi); + + frm->ptr += INQUIRY_INFO_WITH_RSSI_SIZE; + frm->len -= INQUIRY_INFO_WITH_RSSI_SIZE; + } + } +} + +static inline void read_remote_ext_features_complete_dump(int level, struct frame *frm) +{ + evt_read_remote_ext_features_complete *evt = frm->ptr; + int i; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d page %d max %d\n", + evt->status, btohs(evt->handle), + evt->page_num, evt->max_page_num); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("Features:"); + for (i = 0; i < 8; i++) + printf(" 0x%2.2x", evt->features[i]); + printf("\n"); + } +} + +static inline void sync_conn_complete_dump(int level, struct frame *frm) +{ + evt_sync_conn_complete *evt = frm->ptr; + char addr[18]; + + p_ba2str(&evt->bdaddr, addr); + + p_indent(level, frm); + printf("status 0x%2.2x handle %d bdaddr %s type %s\n", + evt->status, btohs(evt->handle), addr, + evt->link_type == 0 ? "SCO" : "eSCO"); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("Air mode: %s\n", airmode2str(evt->air_mode)); + } +} + +static inline void sync_conn_changed_dump(int level, struct frame *frm) +{ + evt_sync_conn_changed *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d\n", evt->status, btohs(evt->handle)); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } +} + +static inline void sniff_subrating_event_dump(int level, struct frame *frm) +{ + evt_sniff_subrating *evt = frm->ptr; + + p_indent(level, frm); + printf("status 0x%2.2x handle %d\n", evt->status, btohs(evt->handle)); + + if (evt->status > 0) { + p_indent(level, frm); + printf("Error: %s\n", status2str(evt->status)); + } else { + p_indent(level, frm); + printf("max latency transmit %d receive %d\n", + btohs(evt->max_tx_latency), + btohs(evt->max_rx_latency)); + + p_indent(level, frm); + printf("min timeout remote %d local %d\n", + btohs(evt->min_remote_timeout), + btohs(evt->min_local_timeout)); + } +} + +static inline void extended_inq_result_dump(int level, struct frame *frm) +{ + uint8_t num = get_u8(frm); + char addr[18]; + int i; + + for (i = 0; i < num; i++) { + extended_inquiry_info *info = frm->ptr; + + p_ba2str(&info->bdaddr, addr); + + p_indent(level, frm); + printf("bdaddr %s mode %d clkoffset 0x%4.4x class 0x%2.2x%2.2x%2.2x rssi %d\n", + addr, info->pscan_rep_mode, btohs(info->clock_offset), + info->dev_class[2], info->dev_class[1], info->dev_class[0], info->rssi); + + frm->ptr += INQUIRY_INFO_WITH_RSSI_SIZE; + frm->len -= INQUIRY_INFO_WITH_RSSI_SIZE; + + ext_inquiry_response_dump(level, frm); + } +} + +static inline void link_supervision_timeout_changed_dump(int level, struct frame *frm) +{ + evt_link_supervision_timeout_changed *evt = frm->ptr; + + p_indent(level, frm); + printf("handle %d timeout %d\n", + btohs(evt->handle), btohs(evt->timeout)); +} + +static inline void user_passkey_notify_dump(int level, struct frame *frm) +{ + evt_user_passkey_notify *evt = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&evt->bdaddr, addr); + printf("bdaddr %s passkey %d\n", addr, btohl(evt->passkey)); +} + +static inline void keypress_notify_dump(int level, struct frame *frm) +{ + evt_keypress_notify *evt = frm->ptr; + char addr[18]; + + p_indent(level, frm); + p_ba2str(&evt->bdaddr, addr); + printf("bdaddr %s type %d\n", addr, evt->type); +} + +static inline void remote_host_features_notify_dump(int level, struct frame *frm) +{ + evt_remote_host_features_notify *evt = frm->ptr; + char addr[18]; + int i; + + p_indent(level, frm); + p_ba2str(&evt->bdaddr, addr); + printf("bdaddr %s\n", addr); + + p_indent(level, frm); + printf("Features:"); + for (i = 0; i < 8; i++) + printf(" 0x%2.2x", evt->features[i]); + printf("\n"); +} + +static inline void event_dump(int level, struct frame *frm) +{ + hci_event_hdr *hdr = frm->ptr; + uint8_t event = hdr->evt; + + if (p_filter(FILT_HCI)) + return; + + if (event <= EVENT_NUM) { + p_indent(level, frm); + printf("HCI Event: %s (0x%2.2x) plen %d\n", + event_str[hdr->evt], hdr->evt, hdr->plen); + } else if (hdr->evt == EVT_TESTING) { + p_indent(level, frm); + printf("HCI Event: Testing (0x%2.2x) plen %d\n", hdr->evt, hdr->plen); + } else if (hdr->evt == EVT_VENDOR) { + uint16_t manufacturer; + + if (parser.flags & DUMP_NOVENDOR) + return; + + p_indent(level, frm); + printf("HCI Event: Vendor (0x%2.2x) plen %d\n", hdr->evt, hdr->plen); + + manufacturer = get_manufacturer(); + + switch (manufacturer) { + case 0: + case 37: + case 48: + frm->ptr += HCI_EVENT_HDR_SIZE; + frm->len -= HCI_EVENT_HDR_SIZE; + ericsson_dump(level + 1, frm); + return; + case 10: + frm->ptr += HCI_EVENT_HDR_SIZE; + frm->len -= HCI_EVENT_HDR_SIZE; + csr_dump(level + 1, frm); + return; + } + } else { + p_indent(level, frm); + printf("HCI Event: code 0x%2.2x plen %d\n", hdr->evt, hdr->plen); + } + + frm->ptr += HCI_EVENT_HDR_SIZE; + frm->len -= HCI_EVENT_HDR_SIZE; + + if (event == EVT_CMD_COMPLETE) { + evt_cmd_complete *cc = frm->ptr; + if (cc->opcode == cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION)) { + read_local_version_rp *rp = frm->ptr + EVT_CMD_COMPLETE_SIZE; + manufacturer = rp->manufacturer; + } + } + + if (event == EVT_DISCONN_COMPLETE) { + evt_disconn_complete *evt = frm->ptr; + l2cap_clear(btohs(evt->handle)); + } + + if (!(parser.flags & DUMP_VERBOSE)) { + raw_dump(level, frm); + return; + } + + switch (event) { + case EVT_LOOPBACK_COMMAND: + command_dump(level + 1, frm); + break; + case EVT_CMD_COMPLETE: + cmd_complete_dump(level + 1, frm); + break; + case EVT_CMD_STATUS: + cmd_status_dump(level + 1, frm); + break; + case EVT_HARDWARE_ERROR: + hardware_error_dump(level + 1, frm); + break; + case EVT_FLUSH_OCCURRED: + case EVT_QOS_VIOLATION: + handle_response_dump(level + 1, frm); + break; + case EVT_INQUIRY_COMPLETE: + status_response_dump(level + 1, frm); + break; + case EVT_INQUIRY_RESULT: + inq_result_dump(level + 1, frm); + break; + case EVT_CONN_COMPLETE: + conn_complete_dump(level + 1, frm); + break; + case EVT_CONN_REQUEST: + conn_request_dump(level + 1, frm); + break; + case EVT_DISCONN_COMPLETE: + disconn_complete_dump(level + 1, frm); + break; + case EVT_AUTH_COMPLETE: + case EVT_CHANGE_CONN_LINK_KEY_COMPLETE: + generic_response_dump(level + 1, frm); + break; + case EVT_MASTER_LINK_KEY_COMPLETE: + master_link_key_complete_dump(level + 1, frm); + break; + case EVT_REMOTE_NAME_REQ_COMPLETE: + remote_name_req_complete_dump(level + 1, frm); + break; + case EVT_ENCRYPT_CHANGE: + encrypt_change_dump(level + 1, frm); + break; + case EVT_READ_REMOTE_FEATURES_COMPLETE: + read_remote_features_complete_dump(level + 1, frm); + break; + case EVT_READ_REMOTE_VERSION_COMPLETE: + read_remote_version_complete_dump(level + 1, frm); + break; + case EVT_QOS_SETUP_COMPLETE: + qos_setup_complete_dump(level + 1, frm); + break; + case EVT_ROLE_CHANGE: + role_change_dump(level + 1, frm); + break; + case EVT_NUM_COMP_PKTS: + num_comp_pkts_dump(level + 1, frm); + break; + case EVT_MODE_CHANGE: + mode_change_dump(level + 1, frm); + break; + case EVT_RETURN_LINK_KEYS: + return_link_keys_dump(level + 1, frm); + break; + case EVT_PIN_CODE_REQ: + case EVT_LINK_KEY_REQ: + case EVT_IO_CAPABILITY_REQUEST: + case EVT_USER_PASSKEY_REQUEST: + case EVT_REMOTE_OOB_DATA_REQUEST: + pin_code_req_dump(level + 1, frm); + break; + case EVT_LINK_KEY_NOTIFY: + link_key_notify_dump(level + 1, frm); + break; + case EVT_DATA_BUFFER_OVERFLOW: + data_buffer_overflow_dump(level + 1, frm); + break; + case EVT_MAX_SLOTS_CHANGE: + max_slots_change_dump(level + 1, frm); + break; + case EVT_READ_CLOCK_OFFSET_COMPLETE: + read_clock_offset_complete_dump(level + 1, frm); + break; + case EVT_CONN_PTYPE_CHANGED: + conn_ptype_changed_dump(level + 1, frm); + break; + case EVT_PSCAN_REP_MODE_CHANGE: + pscan_rep_mode_change_dump(level + 1, frm); + break; + case EVT_FLOW_SPEC_COMPLETE: + flow_spec_complete_dump(level + 1, frm); + break; + case EVT_INQUIRY_RESULT_WITH_RSSI: + inq_result_with_rssi_dump(level + 1, frm); + break; + case EVT_READ_REMOTE_EXT_FEATURES_COMPLETE: + read_remote_ext_features_complete_dump(level + 1, frm); + break; + case EVT_SYNC_CONN_COMPLETE: + sync_conn_complete_dump(level + 1, frm); + break; + case EVT_SYNC_CONN_CHANGED: + sync_conn_changed_dump(level + 1, frm); + break; + case EVT_SNIFF_SUBRATING: + sniff_subrating_event_dump(level + 1, frm); + break; + case EVT_EXTENDED_INQUIRY_RESULT: + extended_inq_result_dump(level + 1, frm); + break; + case EVT_ENCRYPTION_KEY_REFRESH_COMPLETE: + generic_response_dump(level + 1, frm); + break; + case EVT_SIMPLE_PAIRING_COMPLETE: + bdaddr_response_dump(level + 1, frm); + break; + case EVT_LINK_SUPERVISION_TIMEOUT_CHANGED: + link_supervision_timeout_changed_dump(level + 1, frm); + break; + case EVT_ENHANCED_FLUSH_COMPLETE: + generic_command_dump(level + 1, frm); + break; + case EVT_IO_CAPABILITY_RESPONSE: + io_capability_reply_dump(level + 1, frm); + break; + case EVT_USER_CONFIRM_REQUEST: + case EVT_USER_PASSKEY_NOTIFY: + user_passkey_notify_dump(level + 1, frm); + break; + case EVT_KEYPRESS_NOTIFY: + keypress_notify_dump(level + 1, frm); + break; + case EVT_REMOTE_HOST_FEATURES_NOTIFY: + remote_host_features_notify_dump(level + 1, frm); + break; + default: + raw_dump(level, frm); + break; + } +} + +static inline void acl_dump(int level, struct frame *frm) +{ + hci_acl_hdr *hdr = (void *) frm->ptr; + uint16_t handle = btohs(hdr->handle); + uint16_t dlen = btohs(hdr->dlen); + uint8_t flags = acl_flags(handle); + + if (!p_filter(FILT_HCI)) { + p_indent(level, frm); + printf("ACL data: handle %d flags 0x%2.2x dlen %d\n", + acl_handle(handle), flags, dlen); + level++; + } + + frm->ptr += HCI_ACL_HDR_SIZE; + frm->len -= HCI_ACL_HDR_SIZE; + frm->flags = flags; + frm->handle = acl_handle(handle); + + if (parser.filter & ~FILT_HCI) + l2cap_dump(level, frm); + else + raw_dump(level, frm); +} + +static inline void sco_dump(int level, struct frame *frm) +{ + hci_sco_hdr *hdr = (void *) frm->ptr; + uint16_t handle = btohs(hdr->handle); + uint8_t flags = acl_flags(handle); + int len; + + if (frm->audio_fd > fileno(stderr)) + len = write(frm->audio_fd, frm->ptr + HCI_SCO_HDR_SIZE, hdr->dlen); + + if (!p_filter(FILT_SCO)) { + p_indent(level, frm); + printf("SCO data: handle %d flags 0x%2.2x dlen %d\n", + acl_handle(handle), flags, hdr->dlen); + level++; + + frm->ptr += HCI_SCO_HDR_SIZE; + frm->len -= HCI_SCO_HDR_SIZE; + raw_dump(level, frm); + } +} + +static inline void vendor_dump(int level, struct frame *frm) +{ + if (p_filter(FILT_HCI)) + return; + + if (frm->dev_id == HCI_DEV_NONE) { + uint16_t device = btohs(htons(get_u16(frm))); + uint16_t proto = btohs(htons(get_u16(frm))); + uint16_t type = btohs(htons(get_u16(frm))); + uint16_t plen = btohs(htons(get_u16(frm))); + + p_indent(level, frm); + + printf("System %s: device hci%d proto 0x%2.2x type 0x%2.2x plen %d\n", + frm->in ? "event" : "command", device, proto, type, plen); + + raw_dump(level, frm); + return; + } + + if (parser.flags & DUMP_NOVENDOR) + return; + + if (get_manufacturer() == 12) { + bpa_dump(level, frm); + return; + } + + p_indent(level, frm); + printf("Vendor data: len %d\n", frm->len); + raw_dump(level, frm); +} + +void hci_dump(int level, struct frame *frm) +{ + uint8_t type = *(uint8_t *)frm->ptr; + + frm->ptr++; frm->len--; + + switch (type) { + case HCI_COMMAND_PKT: + command_dump(level, frm); + break; + + case HCI_EVENT_PKT: + event_dump(level, frm); + break; + + case HCI_ACLDATA_PKT: + acl_dump(level, frm); + break; + + case HCI_SCODATA_PKT: + sco_dump(level, frm); + break; + + case HCI_VENDOR_PKT: + vendor_dump(level, frm); + break; + + default: + if (p_filter(FILT_HCI)) + break; + + p_indent(level, frm); + printf("Unknown: type 0x%2.2x len %d\n", type, frm->len); + raw_dump(level, frm); + break; + } +} diff --git a/hcidump/parser/hcrp.c b/hcidump/parser/hcrp.c new file mode 100644 index 000000000..e7ada6947 --- /dev/null +++ b/hcidump/parser/hcrp.c @@ -0,0 +1,116 @@ +/* + * + * 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 + +#include "parser.h" + +static char *pid2str(uint16_t pid) +{ + switch (pid) { + case 0x0001: + return "CreditGrant"; + case 0x0002: + return "CreditRequest"; + case 0x0003: + return "CreditReturn"; + case 0x0004: + return "CreditQuery"; + case 0x0005: + return "GetLPTStatus"; + case 0x0006: + return "Get1284ID"; + case 0x0007: + return "SoftReset"; + case 0x0008: + return "HardRest"; + case 0x0009: + return "RegisterNotification"; + case 0x000A: + return "NotificationConnectionAlive"; + default: + return "Reserved"; + } +} + +static char *status2str(uint16_t status) +{ + switch (status) { + case 0x0000: + return "Feature unsupported"; + case 0x0001: + return "Success"; + case 0x0002: + return "Credit synchronization error"; + case 0xFFFF: + return "Generic error"; + default: + return "Unknown"; + } +} + +void hcrp_dump(int level, struct frame *frm) +{ + uint16_t pid, tid, plen, status; + uint32_t credits; + + pid = get_u16(frm); + tid = get_u16(frm); + plen = get_u16(frm); + + p_indent(level, frm); + + printf("HCRP %s %s: tid 0x%x plen %d", + pid2str(pid), frm->in ? "rsp" : "cmd", tid, plen); + + if (frm->in) { + status = get_u16(frm); + printf(" status %d (%s)\n", status, status2str(status)); + } else + printf("\n"); + + if (pid == 0x0001 && !frm->in) { + credits = get_u32(frm); + p_indent(level + 1, frm); + printf("credits %d\n", credits); + } + + if (pid == 0x0002 && frm->in) { + credits = get_u32(frm); + p_indent(level + 1, frm); + printf("credits %d\n", credits); + } + + raw_dump(level + 1, frm); +} diff --git a/hcidump/parser/hidp.c b/hcidump/parser/hidp.c new file mode 100644 index 000000000..16aef85e8 --- /dev/null +++ b/hcidump/parser/hidp.c @@ -0,0 +1,171 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "parser.h" + +static char *type2str(uint8_t head) +{ + switch (head & 0xf0) { + case 0x00: + return "Handshake"; + case 0x10: + return "Control"; + case 0x40: + return "Get report"; + case 0x50: + return "Set report"; + case 0x60: + return "Get protocol"; + case 0x70: + return "Set protocol"; + case 0x80: + return "Get idle"; + case 0x90: + return "Set idle"; + case 0xa0: + return "Data"; + case 0xb0: + return "Data continuation"; + default: + return "Reserved"; + } +} + +static char *result2str(uint8_t head) +{ + switch (head & 0x0f) { + case 0x00: + return "Successful"; + case 0x01: + return "Not ready"; + case 0x02: + return "Invalid report ID"; + case 0x03: + return "Unsupported request"; + case 0x04: + return "Invalid parameter"; + case 0x0e: + return "Unknown"; + case 0x0f: + return "Fatal"; + default: + return "Reserved"; + } +} + +static char *operation2str(uint8_t head) +{ + switch (head & 0x0f) { + case 0x00: + return "No operation"; + case 0x01: + return "Hard reset"; + case 0x02: + return "Soft reset"; + case 0x03: + return "Suspend"; + case 0x04: + return "Exit suspend"; + case 0x05: + return "Virtual cable unplug"; + default: + return "Reserved"; + } +} + +static char *report2str(uint8_t head) +{ + switch (head & 0x03) { + case 0x00: + return "Other report"; + case 0x01: + return "Input report"; + case 0x02: + return "Output report"; + case 0x03: + return "Feature report"; + default: + return "Reserved"; + } +} + +static char *protocol2str(uint8_t head) +{ + switch (head & 0x01) { + case 0x00: + return "Boot protocol"; + case 0x01: + return "Report protocol"; + default: + return "Reserved"; + } +} + +void hidp_dump(int level, struct frame *frm) +{ + uint8_t hdr; + char *param; + + hdr = get_u8(frm); + + switch (hdr & 0xf0) { + case 0x00: + param = result2str(hdr); + break; + case 0x10: + param = operation2str(hdr); + break; + case 0x60: + case 0x70: + param = protocol2str(hdr); + break; + case 0x40: + case 0x50: + case 0xa0: + case 0xb0: + param = report2str(hdr); + break; + default: + param = ""; + break; + } + + p_indent(level, frm); + + printf("HIDP: %s: %s\n", type2str(hdr), param); + + raw_dump(level, frm); +} diff --git a/hcidump/parser/l2cap.c b/hcidump/parser/l2cap.c new file mode 100644 index 000000000..a906f4224 --- /dev/null +++ b/hcidump/parser/l2cap.c @@ -0,0 +1,971 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2002 Maxim Krasnyansky + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "parser.h" +#include "sdp.h" + +typedef struct { + uint16_t handle; + struct frame frm; +} handle_info; +#define HANDLE_TABLE_SIZE 10 + +static handle_info handle_table[HANDLE_TABLE_SIZE]; + +typedef struct { + uint16_t handle; + uint16_t cid; + uint16_t psm; + uint16_t num; + uint8_t mode; +} cid_info; +#define CID_TABLE_SIZE 20 + +static cid_info cid_table[2][CID_TABLE_SIZE]; + +#define SCID cid_table[0] +#define DCID cid_table[1] + +static struct frame *add_handle(uint16_t handle) +{ + register handle_info *t = handle_table; + register int i; + + for (i = 0; i < HANDLE_TABLE_SIZE; i++) + if (!t[i].handle) { + t[i].handle = handle; + return &t[i].frm; + } + return NULL; +} + +static struct frame *get_frame(uint16_t handle) +{ + register handle_info *t = handle_table; + register int i; + + for (i = 0; i < HANDLE_TABLE_SIZE; i++) + if (t[i].handle == handle) + return &t[i].frm; + + return add_handle(handle); +} + +static void add_cid(int in, uint16_t handle, uint16_t cid, uint16_t psm) +{ + register cid_info *table = cid_table[in]; + register int i, pos = -1; + uint16_t num = 1; + + for (i = 0; i < CID_TABLE_SIZE; i++) { + if ((pos < 0 && !table[i].cid) || table[i].cid == cid) + pos = i; + if (table[i].psm == psm) + num++; + } + + if (pos >= 0) { + table[pos].handle = handle; + table[pos].cid = cid; + table[pos].psm = psm; + table[pos].num = num; + table[pos].mode = 0; + } +} + +static void del_cid(int in, uint16_t dcid, uint16_t scid) +{ + register int t, i; + uint16_t cid[2]; + + if (!in) { + cid[0] = dcid; + cid[1] = scid; + } else { + cid[0] = scid; + cid[1] = dcid; + } + + for (t = 0; t < 2; t++) { + for (i = 0; i < CID_TABLE_SIZE; i++) + if (cid_table[t][i].cid == cid[t]) { + cid_table[t][i].handle = 0; + cid_table[t][i].cid = 0; + cid_table[t][i].psm = 0; + cid_table[t][i].num = 0; + cid_table[t][i].mode = 0; + break; + } + } +} + +static void del_handle(uint16_t handle) +{ + register int t, i; + + for (t = 0; t < 2; t++) { + for (i = 0; i < CID_TABLE_SIZE; i++) + if (cid_table[t][i].handle == handle) { + cid_table[t][i].handle = 0; + cid_table[t][i].cid = 0; + cid_table[t][i].psm = 0; + cid_table[t][i].num = 0; + cid_table[t][i].mode = 0; + break; + } + } +} +static uint16_t get_psm(int in, uint16_t cid) +{ + register cid_info *table = cid_table[in]; + register int i; + + for (i = 0; i < CID_TABLE_SIZE; i++) + if (table[i].cid == cid) + return table[i].psm; + return parser.defpsm; +} + +static uint16_t get_num(int in, uint16_t cid) +{ + register cid_info *table = cid_table[in]; + register int i; + + for (i = 0; i < CID_TABLE_SIZE; i++) + if (table[i].cid == cid) + return table[i].num; + return 0; +} + +static void set_mode(int in, uint16_t cid, uint8_t mode) +{ + register cid_info *table = cid_table[in]; + register int i; + + for (i = 0; i < CID_TABLE_SIZE; i++) + if (table[i].cid == cid) + table[i].mode = mode; +} + +static uint8_t get_mode(int in, uint16_t cid) +{ + register cid_info *table = cid_table[in]; + register int i; + + for (i = 0; i < CID_TABLE_SIZE; i++) + if (table[i].cid == cid) + return table[i].mode; + return 0; +} + +static uint32_t get_val(uint8_t *ptr, uint8_t len) +{ + switch (len) { + case 1: + return *ptr; + case 2: + return btohs(bt_get_unaligned((uint16_t *) ptr)); + case 4: + return btohl(bt_get_unaligned((uint32_t *) ptr)); + } + return 0; +} + +static char *reason2str(uint16_t reason) +{ + switch (reason) { + case 0x0000: + return "Command not understood"; + case 0x0001: + return "Signalling MTU exceeded"; + case 0x0002: + return "Invalid CID in request"; + default: + return "Reserved"; + } +} + +static char *connresult2str(uint16_t result) +{ + switch (result) { + case 0x0000: + return "Connection successful"; + case 0x0001: + return "Connection pending"; + case 0x0002: + return "Connection refused - PSM not supported"; + case 0x0003: + return "Connection refused - security block"; + case 0x0004: + return "Connection refused - no resources available"; + default: + return "Reserved"; + } +} + +static char *status2str(uint16_t status) +{ + switch (status) { + case 0x0000: + return "No futher information available"; + case 0x0001: + return "Authentication pending"; + case 0x0002: + return "Authorization pending"; + default: + return "Reserved"; + } +} + +static char *confresult2str(uint16_t result) +{ + switch (result) { + case 0x0000: + return "Success"; + case 0x0001: + return "Failure - unacceptable parameters"; + case 0x0002: + return "Failure - rejected (no reason provided)"; + case 0x0003: + return "Failure - unknown options"; + default: + return "Reserved"; + } +} +static char *inforesult2str(uint16_t result) +{ + switch (result) { + case 0x0000: + return "Success"; + case 0x0001: + return "Not supported"; + default: + return "Reserved"; + } +} + +static char *type2str(uint8_t type) +{ + switch (type) { + case 0x00: + return "No traffic"; + case 0x01: + return "Best effort"; + case 0x02: + return "Guaranteed"; + default: + return "Reserved"; + } +} + +static char *mode2str(uint8_t mode) +{ + switch (mode) { + case 0x00: + return "Basic"; + case 0x01: + return "Retransmission"; + case 0x02: + return "Flow control"; + default: + return "Reserved"; + } +} + +static char *sar2str(uint8_t sar) +{ + switch (sar) { + case 0x00: + return "Unsegmented"; + case 0x01: + return "Start"; + case 0x02: + return "End"; + case 0x03: + return "Continuation"; + default: + return "Bad SAR"; + + } +} + +static char *supervisory2str(uint8_t supervisory) +{ + switch (supervisory) { + case 0x00: + return "Receiver Ready (RR)"; + case 0x01: + return "Reject (REJ)"; + case 0x02: + case 0x03: + return "Reserved Supervisory"; + default: + return "Bad Supervisory"; + } +} + +static inline void command_rej(int level, struct frame *frm) +{ + l2cap_cmd_rej *h = frm->ptr; + uint16_t reason = btohs(h->reason); + uint32_t cid; + + printf("Command rej: reason %d", reason); + + switch (reason) { + case 0x0001: + printf(" mtu %d\n", get_val(frm->ptr + L2CAP_CMD_REJ_SIZE, 2)); + break; + case 0x0002: + cid = get_val(frm->ptr + L2CAP_CMD_REJ_SIZE, 4); + printf(" dcid 0x%4.4x scid 0x%4.4x\n", cid & 0xffff, cid >> 16); + break; + default: + printf("\n"); + break; + } + + p_indent(level + 1, frm); + printf("%s\n", reason2str(reason)); +} + +static inline void conn_req(int level, struct frame *frm) +{ + l2cap_conn_req *h = frm->ptr; + uint16_t psm = btohs(h->psm); + uint16_t scid = btohs(h->scid); + + add_cid(frm->in, frm->handle, scid, psm); + + if (p_filter(FILT_L2CAP)) + return; + + printf("Connect req: psm %d scid 0x%4.4x\n", psm, scid); +} + +static inline void conn_rsp(int level, struct frame *frm) +{ + l2cap_conn_rsp *h = frm->ptr; + uint16_t scid = btohs(h->scid); + uint16_t dcid = btohs(h->dcid); + uint16_t result = btohs(h->result); + uint16_t status = btohs(h->status); + uint16_t psm; + + switch (h->result) { + case L2CAP_CR_SUCCESS: + if ((psm = get_psm(!frm->in, scid))) + add_cid(frm->in, frm->handle, dcid, psm); + break; + + case L2CAP_CR_PEND: + break; + + default: + del_cid(frm->in, dcid, scid); + break; + } + + if (p_filter(FILT_L2CAP)) + return; + + printf("Connect rsp: dcid 0x%4.4x scid 0x%4.4x result %d status %d\n", + dcid, scid, result, status); + + p_indent(level + 1, frm); + printf("%s", connresult2str(result)); + + if (result == 0x0001) + printf(" - %s\n", status2str(status)); + else + printf("\n"); +} + +static void conf_rfc(void *ptr, int len, int in, uint16_t cid) +{ + uint8_t mode; + + mode = *((uint8_t *) ptr); + set_mode(in, cid, mode); + + printf("RFC 0x%02x (%s", mode, mode2str(mode)); + if (mode == 0x01 || mode == 0x02) { + uint8_t txwin, maxtrans; + uint16_t rto, mto, mps; + txwin = *((uint8_t *) (ptr + 1)); + maxtrans = *((uint8_t *) (ptr + 2)); + rto = btohs(bt_get_unaligned((uint16_t *) (ptr + 3))); + mto = btohs(bt_get_unaligned((uint16_t *) (ptr + 5))); + mps = btohs(bt_get_unaligned((uint16_t *) (ptr + 7))); + printf(", TxWin %d, MaxTx %d, RTo %d, MTo %d, MPS %d", + txwin, maxtrans, rto, mto, mps); + } + printf(")"); +} + +static void conf_opt(int level, void *ptr, int len, int in, uint16_t cid) +{ + p_indent(level, 0); + while (len > 0) { + l2cap_conf_opt *h = ptr; + + ptr += L2CAP_CONF_OPT_SIZE + h->len; + len -= L2CAP_CONF_OPT_SIZE + h->len; + + if (h->type & 0x80) + printf("["); + + switch (h->type & 0x7f) { + case L2CAP_CONF_MTU: + set_mode(in, cid, 0x00); + printf("MTU"); + if (h->len > 0) + printf(" %d", get_val(h->val, h->len)); + break; + + case L2CAP_CONF_FLUSH_TO: + printf("FlushTO"); + if (h->len > 0) + printf(" %d", get_val(h->val, h->len)); + break; + + case L2CAP_CONF_QOS: + printf("QoS"); + if (h->len > 0) + printf(" 0x%02x (%s)", *(h->val + 1), type2str(*(h->val + 1))); + break; + + case L2CAP_CONF_RFC: + conf_rfc(h->val, h->len, in, cid); + break; + + default: + printf("Unknown (type %2.2x, len %d)", h->type & 0x7f, h->len); + break; + } + + if (h->type & 0x80) + printf("] "); + else + printf(" "); + } + printf("\n"); +} + +static void conf_list(int level, uint8_t *list, int len) +{ + int i; + + p_indent(level, 0); + for (i = 0; i < len; i++) { + switch (list[i] & 0x7f) { + case L2CAP_CONF_MTU: + printf("MTU "); + break; + case L2CAP_CONF_FLUSH_TO: + printf("FlushTo "); + break; + case L2CAP_CONF_QOS: + printf("QoS "); + break; + case L2CAP_CONF_RFC: + printf("RFC "); + break; + default: + printf("%2.2x ", list[i] & 0x7f); + break; + } + } + printf("\n"); +} + +static inline void conf_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_conf_req *h = frm->ptr; + uint16_t dcid = btohs(h->dcid); + int clen = btohs(cmd->len) - L2CAP_CONF_REQ_SIZE; + + if (p_filter(FILT_L2CAP)) + return; + + printf("Config req: dcid 0x%4.4x flags 0x%2.2x clen %d\n", + dcid, btohs(h->flags), clen); + + if (clen > 0) + conf_opt(level + 1, h->data, clen, frm->in, dcid); +} + +static inline void conf_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_conf_rsp *h = frm->ptr; + uint16_t scid = btohs(h->scid); + uint16_t result = btohs(h->result); + int clen = btohs(cmd->len) - L2CAP_CONF_RSP_SIZE; + + if (p_filter(FILT_L2CAP)) + return; + + printf("Config rsp: scid 0x%4.4x flags 0x%2.2x result %d clen %d\n", + scid, btohs(h->flags), result, clen); + + if (clen > 0) { + if (result) { + p_indent(level + 1, frm); + printf("%s\n", confresult2str(result)); + } + if (result == 0x0003) + conf_list(level + 1, h->data, clen); + else + conf_opt(level + 1, h->data, clen, frm->in, scid); + } else { + p_indent(level + 1, frm); + printf("%s\n", confresult2str(result)); + } +} + +static inline void disconn_req(int level, struct frame *frm) +{ + l2cap_disconn_req *h = frm->ptr; + + if (p_filter(FILT_L2CAP)) + return; + + printf("Disconn req: dcid 0x%4.4x scid 0x%4.4x\n", + btohs(h->dcid), btohs(h->scid)); +} + +static inline void disconn_rsp(int level, struct frame *frm) +{ + l2cap_disconn_rsp *h = frm->ptr; + uint16_t dcid = btohs(h->dcid); + uint16_t scid = btohs(h->scid); + + del_cid(frm->in, dcid, scid); + + if (p_filter(FILT_L2CAP)) + return; + + printf("Disconn rsp: dcid 0x%4.4x scid 0x%4.4x\n", + btohs(h->dcid), btohs(h->scid)); +} + +static inline void echo_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + if (p_filter(FILT_L2CAP)) + return; + + printf("Echo req: dlen %d\n", btohs(cmd->len)); + raw_dump(level, frm); +} + +static inline void echo_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + if (p_filter(FILT_L2CAP)) + return; + + printf("Echo rsp: dlen %d\n", btohs(cmd->len)); + raw_dump(level, frm); +} + +static void info_opt(int level, int type, void *ptr, int len) +{ + uint32_t mask; + + p_indent(level, 0); + + switch (type) { + case 0x0001: + printf("Connectionless MTU %d\n", get_val(ptr, len)); + break; + case 0x0002: + mask = get_val(ptr, len); + printf("Extended feature mask 0x%4.4x\n", mask); + if (parser.flags & DUMP_VERBOSE) { + if (mask & 0x01) { + p_indent(level + 1, 0); + printf("Flow control mode\n"); + } + if (mask & 0x02) { + p_indent(level + 1, 0); + printf("Retransmission mode\n"); + } + if (mask & 0x04) { + p_indent(level + 1, 0); + printf("Bi-directional QoS\n"); + } + } + break; + default: + printf("Unknown (len %d)\n", len); + break; + } +} + +static inline void info_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_info_req *h = frm->ptr; + + if (p_filter(FILT_L2CAP)) + return; + + printf("Info req: type %d\n", btohs(h->type)); +} + +static inline void info_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_info_rsp *h = frm->ptr; + uint16_t type = btohs(h->type); + uint16_t result = btohs(h->result); + int ilen = btohs(cmd->len) - L2CAP_INFO_RSP_SIZE; + + if (p_filter(FILT_L2CAP)) + return; + + printf("Info rsp: type %d result %d\n", type, result); + + if (ilen > 0) { + info_opt(level + 1, type, h->data, ilen); + } else { + p_indent(level + 1, frm); + printf("%s\n", inforesult2str(result)); + } +} + +static void l2cap_parse(int level, struct frame *frm) +{ + l2cap_hdr *hdr = (void *)frm->ptr; + uint16_t dlen = btohs(hdr->len); + uint16_t cid = btohs(hdr->cid); + uint16_t psm; + + frm->ptr += L2CAP_HDR_SIZE; + frm->len -= L2CAP_HDR_SIZE; + + if (cid == 0x1) { + /* Signaling channel */ + + while (frm->len >= L2CAP_CMD_HDR_SIZE) { + l2cap_cmd_hdr *hdr = frm->ptr; + + frm->ptr += L2CAP_CMD_HDR_SIZE; + frm->len -= L2CAP_CMD_HDR_SIZE; + + if (!p_filter(FILT_L2CAP)) { + p_indent(level, frm); + printf("L2CAP(s): "); + } + + switch (hdr->code) { + case L2CAP_COMMAND_REJ: + command_rej(level, frm); + break; + + case L2CAP_CONN_REQ: + conn_req(level, frm); + break; + + case L2CAP_CONN_RSP: + conn_rsp(level, frm); + break; + + case L2CAP_CONF_REQ: + conf_req(level, hdr, frm); + break; + + case L2CAP_CONF_RSP: + conf_rsp(level, hdr, frm); + break; + + case L2CAP_DISCONN_REQ: + disconn_req(level, frm); + break; + + case L2CAP_DISCONN_RSP: + disconn_rsp(level, frm); + break; + + case L2CAP_ECHO_REQ: + echo_req(level, hdr, frm); + break; + + case L2CAP_ECHO_RSP: + echo_rsp(level, hdr, frm); + break; + + case L2CAP_INFO_REQ: + info_req(level, hdr, frm); + break; + + case L2CAP_INFO_RSP: + info_rsp(level, hdr, frm); + break; + + default: + if (p_filter(FILT_L2CAP)) + break; + printf("code 0x%2.2x ident %d len %d\n", + hdr->code, hdr->ident, btohs(hdr->len)); + raw_dump(level, frm); + } + + if (frm->len > btohs(hdr->len)) { + frm->len -= btohs(hdr->len); + frm->ptr += btohs(hdr->len); + } else + frm->len = 0; + } + } else if (cid == 0x2) { + /* Connectionless channel */ + + if (p_filter(FILT_L2CAP)) + return; + + psm = btohs(bt_get_unaligned((uint16_t *) frm->ptr)); + frm->ptr += 2; + frm->len -= 2; + + p_indent(level, frm); + printf("L2CAP(c): len %d psm %d\n", dlen, psm); + raw_dump(level, frm); + } else { + /* Connection oriented channel */ + + uint8_t mode = get_mode(!frm->in, cid); + uint16_t psm = get_psm(!frm->in, cid); + uint16_t ctrl = 0, fcs = 0; + uint32_t proto; + + frm->cid = cid; + frm->num = get_num(!frm->in, cid); + + if (mode > 0) { + ctrl = btohs(bt_get_unaligned((uint16_t *) frm->ptr)); + frm->ptr += 2; + frm->len -= 4; + fcs = btohs(bt_get_unaligned((uint16_t *) (frm->ptr + frm->len))); + } + + if (!p_filter(FILT_L2CAP)) { + p_indent(level, frm); + printf("L2CAP(d): cid 0x%4.4x len %d", cid, dlen); + if (mode > 0) + printf(" ctrl 0x%4.4x fcs 0x%4.4x", ctrl, fcs); + printf(" [psm %d]\n", psm); + level++; + if (mode > 0) { + p_indent(level, frm); + printf("%s:", ctrl & 0x01 ? "S-frame" : "I-frame"); + if (ctrl & 0x01) { + printf(" %s", supervisory2str((ctrl & 0x0c) >> 2)); + } else { + uint8_t sar = (ctrl & 0xc000) >> 14; + printf(" %s", sar2str(sar)); + if (sar == 1) { + uint16_t len; + len = btohs(bt_get_unaligned((uint16_t *) frm->ptr)); + frm->ptr += 2; + frm->len -= 2; + printf(" (len %d)", len); + } + printf(" TxSeq %d", (ctrl & 0x7e) >> 1); + } + printf(" ReqSeq %d", (ctrl & 0x3f00) >> 8); + if (ctrl & 0x80) + printf(" Retransmission Disable"); + printf("\n"); + } + } + + switch (psm) { + case 0x01: + if (!p_filter(FILT_SDP)) + sdp_dump(level + 1, frm); + else + raw_dump(level + 1, frm); + break; + + case 0x03: + if (!p_filter(FILT_RFCOMM)) + rfcomm_dump(level, frm); + else + raw_dump(level + 1, frm); + break; + + case 0x0f: + if (!p_filter(FILT_BNEP)) + bnep_dump(level, frm); + else + raw_dump(level + 1, frm); + break; + + case 0x11: + case 0x13: + if (!p_filter(FILT_HIDP)) + hidp_dump(level, frm); + else + raw_dump(level + 1, frm); + break; + + case 0x17: + if (!p_filter(FILT_AVCTP)) + avctp_dump(level, frm); + else + raw_dump(level + 1, frm); + break; + + case 0x19: + if (!p_filter(FILT_AVDTP)) + avdtp_dump(level, frm); + else + raw_dump(level + 1, frm); + break; + + default: + proto = get_proto(frm->handle, psm, 0); + + switch (proto) { + case SDP_UUID_CMTP: + if (!p_filter(FILT_CMTP)) + cmtp_dump(level, frm); + else + raw_dump(level + 1, frm); + break; + + case SDP_UUID_HARDCOPY_CONTROL_CHANNEL: + if (!p_filter(FILT_HCRP)) + hcrp_dump(level, frm); + else + raw_dump(level + 1, frm); + break; + + default: + if (p_filter(FILT_L2CAP)) + break; + + raw_dump(level, frm); + break; + } + break; + } + } +} + +void l2cap_dump(int level, struct frame *frm) +{ + struct frame *fr; + l2cap_hdr *hdr; + uint16_t dlen; + + if (frm->flags & ACL_START) { + hdr = frm->ptr; + dlen = btohs(hdr->len); + + if (frm->len == (dlen + L2CAP_HDR_SIZE)) { + /* Complete frame */ + l2cap_parse(level, frm); + return; + } + + if (!(fr = get_frame(frm->handle))) { + fprintf(stderr, "Not enough connection handles\n"); + raw_dump(level, frm); + return; + } + + if (fr->data) + free(fr->data); + + if (!(fr->data = malloc(dlen + L2CAP_HDR_SIZE))) { + perror("Can't allocate L2CAP reassembly buffer"); + return; + } + memcpy(fr->data, frm->ptr, frm->len); + fr->data_len = dlen + L2CAP_HDR_SIZE; + fr->len = frm->len; + fr->ptr = fr->data; + fr->dev_id = frm->dev_id; + fr->in = frm->in; + fr->ts = frm->ts; + fr->handle = frm->handle; + fr->cid = frm->cid; + fr->num = frm->num; + fr->dlci = frm->dlci; + fr->channel = frm->channel; + fr->pppdump_fd = frm->pppdump_fd; + fr->audio_fd = frm->audio_fd; + } else { + if (!(fr = get_frame(frm->handle))) { + fprintf(stderr, "Not enough connection handles\n"); + raw_dump(level, frm); + return; + } + + if (!fr->data) { + /* Unexpected fragment */ + raw_dump(level, frm); + return; + } + + if (frm->len > (fr->data_len - fr->len)) { + /* Bad fragment */ + raw_dump(level, frm); + free(fr->data); fr->data = NULL; + return; + } + + memcpy(fr->data + fr->len, frm->ptr, frm->len); + fr->len += frm->len; + + if (fr->len == fr->data_len) { + /* Complete frame */ + l2cap_parse(level, fr); + + free(fr->data); fr->data = NULL; + return; + } + } +} + +void l2cap_clear(uint16_t handle) +{ + del_handle(handle); +} diff --git a/hcidump/parser/lmp.c b/hcidump/parser/lmp.c new file mode 100644 index 000000000..d80b5bffa --- /dev/null +++ b/hcidump/parser/lmp.c @@ -0,0 +1,1349 @@ +/* + * + * 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 + +#include "parser.h" + +#define LMP_U8(frm) (get_u8(frm)) +#define LMP_U16(frm) (btohs(htons(get_u16(frm)))) +#define LMP_U32(frm) (btohl(htonl(get_u32(frm)))) + +static enum { + IN_RAND, + COMB_KEY_M, + COMB_KEY_S, + AU_RAND_M, + AU_RAND_S, + SRES_M, + SRES_S, +} pairing_state = IN_RAND; + +static struct { + uint8_t in_rand[16]; + uint8_t comb_key_m[16]; + uint8_t comb_key_s[16]; + uint8_t au_rand_m[16]; + uint8_t au_rand_s[16]; + uint8_t sres_m[4]; + uint8_t sres_s[4]; +} pairing_data; + +static inline void pairing_data_dump(void) +{ + int i; + + p_indent(6, NULL); + printf("IN_RAND "); + for (i = 0; i < 16; i++) + printf("%2.2x", pairing_data.in_rand[i]); + printf("\n"); + + p_indent(6, NULL); + printf("COMB_KEY "); + for (i = 0; i < 16; i++) + printf("%2.2x", pairing_data.comb_key_m[i]); + printf(" (M)\n"); + + p_indent(6, NULL); + printf("COMB_KEY "); + for (i = 0; i < 16; i++) + printf("%2.2x", pairing_data.comb_key_s[i]); + printf(" (S)\n"); + + p_indent(6, NULL); + printf("AU_RAND "); + for (i = 0; i < 16; i++) + printf("%2.2x", pairing_data.au_rand_m[i]); + printf(" SRES "); + for (i = 0; i < 4; i++) + printf("%2.2x", pairing_data.sres_m[i]); + printf(" (M)\n"); + + p_indent(6, NULL); + printf("AU_RAND "); + for (i = 0; i < 16; i++) + printf("%2.2x", pairing_data.au_rand_s[i]); + printf(" SRES "); + for (i = 0; i < 4; i++) + printf("%2.2x", pairing_data.sres_s[i]); + printf(" (S)\n"); +} + +static inline void in_rand(struct frame *frm) +{ + uint8_t *val = frm->ptr; + + memcpy(pairing_data.in_rand, val, 16); + pairing_state = COMB_KEY_M; +} + +static inline void comb_key(struct frame *frm) +{ + uint8_t *val = frm->ptr; + + switch (pairing_state) { + case COMB_KEY_M: + memcpy(pairing_data.comb_key_m, val, 16); + pairing_state = COMB_KEY_S; + break; + case COMB_KEY_S: + memcpy(pairing_data.comb_key_s, val, 16); + pairing_state = AU_RAND_M; + break; + default: + pairing_state = IN_RAND; + break; + } +} + +static inline void au_rand(struct frame *frm) +{ + uint8_t *val = frm->ptr; + + switch (pairing_state) { + case AU_RAND_M: + memcpy(pairing_data.au_rand_m, val, 16); + pairing_state = SRES_M; + break; + case AU_RAND_S: + memcpy(pairing_data.au_rand_s, val, 16); + pairing_state = SRES_S; + break; + default: + pairing_state = IN_RAND; + break; + } +} + +static inline void sres(struct frame *frm) +{ + uint8_t *val = frm->ptr; + + switch (pairing_state) { + case SRES_M: + memcpy(pairing_data.sres_m, val, 4); + pairing_state = AU_RAND_S; + break; + case SRES_S: + memcpy(pairing_data.sres_s, val, 4); + pairing_state = IN_RAND; + pairing_data_dump(); + break; + default: + pairing_state = IN_RAND; + break; + } +} + +static char *opcode2str(uint16_t opcode) +{ + switch (opcode) { + case 1: + return "name_req"; + case 2: + return "name_res"; + case 3: + return "accepted"; + case 4: + return "not_accepted"; + case 5: + return "clkoffset_req"; + case 6: + return "clkoffset_res"; + case 7: + return "detach"; + case 8: + return "in_rand"; + case 9: + return "comb_key"; + case 10: + return "unit_key"; + case 11: + return "au_rand"; + case 12: + return "sres"; + case 13: + return "temp_rand"; + case 14: + return "temp_key"; + case 15: + return "encryption_mode_req"; + case 16: + return "encryption_key_size_req"; + case 17: + return "start_encryption_req"; + case 18: + return "stop_encryption_req"; + case 19: + return "switch_req"; + case 20: + return "hold"; + case 21: + return "hold_req"; + case 22: + return "sniff"; + case 23: + return "sniff_req"; + case 24: + return "unsniff_req"; + case 25: + return "park_req"; + case 26: + return "park"; + case 27: + return "set_broadcast_scan_window"; + case 28: + return "modify_beacon"; + case 29: + return "unpark_BD_ADDR_req"; + case 30: + return "unpark_PM_ADDR_req"; + case 31: + return "incr_power_req"; + case 32: + return "decr_power_req"; + case 33: + return "max_power"; + case 34: + return "min_power"; + case 35: + return "auto_rate"; + case 36: + return "preferred_rate"; + case 37: + return "version_req"; + case 38: + return "version_res"; + case 39: + return "feature_req"; + case 40: + return "feature_res"; + case 41: + return "quality_of_service"; + case 42: + return "quality_of_service_req"; + case 43: + return "SCO_link_req"; + case 44: + return "remove_SCO_link_req"; + case 45: + return "max_slot"; + case 46: + return "max_slot_req"; + case 47: + return "timing_accuracy_req"; + case 48: + return "timing_accuracy_res"; + case 49: + return "setup_complete"; + case 50: + return "use_semi_permanent_key"; + case 51: + return "host_connection_req"; + case 52: + return "slot_offset"; + case 53: + return "page_mode_req"; + case 54: + return "page_scan_mode_req"; + case 55: + return "supervision_timeout"; + case 56: + return "test_activate"; + case 57: + return "test_control"; + case 58: + return "encryption_key_size_mask_req"; + case 59: + return "encryption_key_size_mask_res"; + case 60: + return "set_AFH"; + case 61: + return "encapsulated_header"; + case 62: + return "encapsulated_payload"; + case 63: + return "simple_pairing_confirm"; + case 64: + return "simple_pairing_number"; + case 65: + return "DHkey_check"; + case 127 + (1 << 7): + return "accepted_ext"; + case 127 + (2 << 7): + return "not_accepted_ext"; + case 127 + (3 << 7): + return "features_req_ext"; + case 127 + (4 << 7): + return "features_res_ext"; + case 127 + (11 << 7): + return "packet_type_table_req"; + case 127 + (12 << 7): + return "eSCO_link_req"; + case 127 + (13 << 7): + return "remove_eSCO_link_req"; + case 127 + (16 << 7): + return "channel_classification_req"; + case 127 + (17 << 7): + return "channel_classification"; + case 127 + (21 << 7): + return "sniff_subrating_req"; + case 127 + (22 << 7): + return "sniff_subrating_res"; + case 127 + (23 << 7): + return "pause_encryption_req"; + case 127 + (24 << 7): + return "resume_encryption_req"; + case 127 + (25 << 7): + return "IO_capability_req"; + case 127 + (26 << 7): + return "IO_capability_res"; + case 127 + (27 << 7): + return "numeric_comparison_failed"; + case 127 + (28 << 7): + return "passkey_failed"; + case 127 + (29 << 7): + return "oob_failed"; + case 127 + (30 << 7): + return "keypress_notification"; + default: + return "unknown"; + } +} + +static inline void name_req_dump(int level, struct frame *frm) +{ + uint8_t offset = LMP_U8(frm); + + p_indent(level, frm); + printf("name offset %d\n", offset); +} + +static inline void name_res_dump(int level, struct frame *frm) +{ + uint8_t offset = LMP_U8(frm); + uint8_t length = LMP_U8(frm); + uint8_t *name = frm->ptr; + int i, size; + + frm->ptr += 14; + frm->len -= 14; + + p_indent(level, frm); + printf("name offset %d\n", offset); + + p_indent(level, frm); + printf("name length %d\n", length); + + size = length - offset; + if (size > 14) + size = 14; + + p_indent(level, frm); + printf("name fragment '"); + for (i = 0; i < size; i++) + if (isprint(name[i])) + printf("%c", name[i]); + else + printf("."); + printf("'\n"); +} + +static inline void accepted_dump(int level, struct frame *frm) +{ + uint8_t opcode = LMP_U8(frm); + + p_indent(level, frm); + printf("op code %d (%s)\n", opcode, opcode2str(opcode)); +} + +static inline void not_accepted_dump(int level, struct frame *frm) +{ + uint8_t opcode = LMP_U8(frm); + uint8_t error = LMP_U8(frm); + + p_indent(level, frm); + printf("op code %d (%s)\n", opcode, opcode2str(opcode)); + + p_indent(level, frm); + printf("error code 0x%2.2x\n", error); +} + +static inline void clkoffset_dump(int level, struct frame *frm) +{ + uint16_t clkoffset = LMP_U16(frm); + + p_indent(level, frm); + printf("clock offset 0x%4.4x\n", clkoffset); +} + +static inline void detach_dump(int level, struct frame *frm) +{ + uint8_t error = LMP_U8(frm); + + p_indent(level, frm); + printf("error code 0x%2.2x\n", error); +} + +static inline void random_number_dump(int level, struct frame *frm) +{ + uint8_t *number = frm->ptr; + int i; + + frm->ptr += 16; + frm->len -= 16; + + p_indent(level, frm); + printf("random number "); + for (i = 0; i < 16; i++) + printf("%2.2x", number[i]); + printf("\n"); +} + +static inline void key_dump(int level, struct frame *frm) +{ + uint8_t *key = frm->ptr; + int i; + + frm->ptr += 16; + frm->len -= 16; + + p_indent(level, frm); + printf("key "); + for (i = 0; i < 16; i++) + printf("%2.2x", key[i]); + printf("\n"); +} + +static inline void auth_resp_dump(int level, struct frame *frm) +{ + uint8_t *resp = frm->ptr; + int i; + + frm->ptr += 4; + frm->ptr -= 4; + + p_indent(level, frm); + printf("authentication response "); + for (i = 0; i < 4; i++) + printf("%2.2x", resp[i]); + printf("\n"); +} + +static inline void encryption_mode_req_dump(int level, struct frame *frm) +{ + uint8_t mode = LMP_U8(frm); + + p_indent(level, frm); + printf("encryption mode %d\n", mode); +} + +static inline void encryption_key_size_req_dump(int level, struct frame *frm) +{ + uint8_t keysize = LMP_U8(frm); + + p_indent(level, frm); + printf("key size %d\n", keysize); +} + +static inline void switch_req_dump(int level, struct frame *frm) +{ + uint32_t instant = LMP_U32(frm); + + p_indent(level, frm); + printf("switch instant 0x%4.4x\n", instant); +} + +static inline void hold_dump(int level, struct frame *frm) +{ + uint16_t time = LMP_U16(frm); + uint32_t instant = LMP_U32(frm); + + p_indent(level, frm); + printf("hold time 0x%4.4x\n", time); + + p_indent(level, frm); + printf("hold instant 0x%4.4x\n", instant); +} + +static inline void sniff_req_dump(int level, struct frame *frm) +{ + uint8_t timing = LMP_U8(frm); + uint16_t dsniff = LMP_U16(frm); + uint16_t tsniff = LMP_U16(frm); + uint16_t attempt = LMP_U16(frm); + uint16_t timeout = LMP_U16(frm); + + p_indent(level, frm); + printf("timing control flags 0x%2.2x\n", timing); + + p_indent(level, frm); + printf("D_sniff %d T_sniff %d\n", dsniff, tsniff); + + p_indent(level, frm); + printf("sniff attempt %d\n", attempt); + + p_indent(level, frm); + printf("sniff timeout %d\n", timeout); +} + +static inline void park_req_dump(int level, struct frame *frm) +{ + uint8_t timing = LMP_U8(frm); + uint16_t db = LMP_U16(frm); + uint16_t tb = LMP_U16(frm); + uint8_t nb = LMP_U8(frm); + uint8_t xb = LMP_U8(frm); + uint8_t pmaddr = LMP_U8(frm); + uint8_t araddr = LMP_U8(frm); + uint8_t nbsleep = LMP_U8(frm); + uint8_t dbsleep = LMP_U8(frm); + uint8_t daccess = LMP_U8(frm); + uint8_t taccess = LMP_U8(frm); + uint8_t nslots = LMP_U8(frm); + uint8_t npoll = LMP_U8(frm); + uint8_t access = LMP_U8(frm); + + p_indent(level, frm); + printf("timing control flags 0x%2.2x\n", timing); + + p_indent(level, frm); + printf("D_B %d T_B %d N_B %d X_B %d\n", db, tb, nb, xb); + + p_indent(level, frm); + printf("PM_ADDR %d AR_ADDR %d\n", pmaddr, araddr); + + p_indent(level, frm); + printf("N_Bsleep %d D_Bsleep %d\n", nbsleep, dbsleep); + + p_indent(level, frm); + printf("D_access %d T_access %d\n", daccess, taccess); + + p_indent(level, frm); + printf("N_acc-slots %d N_poll %d\n", nslots, npoll); + + p_indent(level, frm); + printf("M_access %d\n", access & 0x0f); + + p_indent(level, frm); + printf("access scheme 0x%2.2x\n", access >> 4); +} + +static inline void modify_beacon_dump(int level, struct frame *frm) +{ + uint8_t timing = LMP_U8(frm); + uint16_t db = LMP_U16(frm); + uint16_t tb = LMP_U16(frm); + uint8_t nb = LMP_U8(frm); + uint8_t xb = LMP_U8(frm); + uint8_t daccess = LMP_U8(frm); + uint8_t taccess = LMP_U8(frm); + uint8_t nslots = LMP_U8(frm); + uint8_t npoll = LMP_U8(frm); + uint8_t access = LMP_U8(frm); + + p_indent(level, frm); + printf("timing control flags 0x%2.2x\n", timing); + + p_indent(level, frm); + printf("D_B %d T_B %d N_B %d X_B %d\n", db, tb, nb, xb); + + p_indent(level, frm); + printf("D_access %d T_access %d\n", daccess, taccess); + + p_indent(level, frm); + printf("N_acc-slots %d N_poll %d\n", nslots, npoll); + + p_indent(level, frm); + printf("M_access %d\n", access & 0x0f); + + p_indent(level, frm); + printf("access scheme 0x%2.2x\n", access >> 4); +} + +static inline void power_req_dump(int level, struct frame *frm) +{ + uint8_t val = LMP_U8(frm); + + p_indent(level, frm); + printf("future use 0x%2.2x\n", val); +} + +static inline void preferred_rate_dump(int level, struct frame *frm) +{ + uint8_t rate = LMP_U8(frm); + + p_indent(level, frm); + printf("data rate 0x%2.2x\n", rate); + + p_indent(level, frm); + printf("Basic: "); + + printf("%suse FEC, ", rate & 0x01 ? "do not " : ""); + + switch ((rate >> 1) & 0x03) { + case 0x00: + printf("no packet-size preference\n"); + break; + case 0x01: + printf("use 1-slot packets\n"); + break; + case 0x02: + printf("use 3-slot packets\n"); + break; + case 0x03: + printf("use 5-slot packets\n"); + break; + } + + p_indent(level, frm); + printf("EDR: "); + + switch ((rate >> 3) & 0x03) { + case 0x00: + printf("use DM1 packets, "); + break; + case 0x01: + printf("use 2 Mbps packets, "); + break; + case 0x02: + printf("use 3 Mbps packets, "); + break; + case 0x03: + printf("reserved, \n"); + break; + } + + switch ((rate >> 5) & 0x03) { + case 0x00: + printf("no packet-size preference\n"); + break; + case 0x01: + printf("use 1-slot packets\n"); + break; + case 0x02: + printf("use 3-slot packets\n"); + break; + case 0x03: + printf("use 5-slot packets\n"); + break; + } +} + +static inline void version_dump(int level, struct frame *frm) +{ + uint8_t ver = LMP_U8(frm); + uint16_t compid = LMP_U16(frm); + uint16_t subver = LMP_U16(frm); + char *tmp; + + p_indent(level, frm); + tmp = lmp_vertostr(ver); + printf("VersNr %d (%s)\n", ver, tmp); + bt_free(tmp); + + p_indent(level, frm); + printf("CompId %d (%s)\n", compid, bt_compidtostr(compid)); + + p_indent(level, frm); + printf("SubVersNr %d\n", subver); +} + +static inline void features_dump(int level, struct frame *frm) +{ + uint8_t *features = frm->ptr; + int i; + + frm->ptr += 8; + frm->len -= 8; + + p_indent(level, frm); + printf("features"); + for (i = 0; i < 8; i++) + printf(" 0x%2.2x", features[i]); + printf("\n"); +} + +static inline void set_afh_dump(int level, struct frame *frm) +{ + uint32_t instant = LMP_U32(frm); + uint8_t mode = LMP_U8(frm); + uint8_t *map = frm->ptr; + int i; + + frm->ptr += 10; + frm->len -= 10; + + p_indent(level, frm); + printf("AFH_instant 0x%04x\n", instant); + + p_indent(level, frm); + printf("AFH_mode %d\n", mode); + + p_indent(level, frm); + printf("AFH_channel_map 0x"); + for (i = 0; i < 10; i++) + printf("%2.2x", map[i]); + printf("\n"); +} + +static inline void encapsulated_header_dump(int level, struct frame *frm) +{ + uint8_t major = LMP_U8(frm); + uint8_t minor = LMP_U8(frm); + uint8_t length = LMP_U8(frm); + + p_indent(level, frm); + printf("major type %d minor type %d payload length %d\n", + major, minor, length); + + if (major == 1 && minor == 1) { + p_indent(level, frm); + printf("P-192 Public Key\n"); + } +} + +static inline void encapsulated_payload_dump(int level, struct frame *frm) +{ + uint8_t *value = frm->ptr; + int i; + + frm->ptr += 16; + frm->len -= 16; + + p_indent(level, frm); + printf("data "); + for (i = 0; i < 16; i++) + printf("%2.2x", value[i]); + printf("\n"); +} + +static inline void simple_pairing_confirm_dump(int level, struct frame *frm) +{ + uint8_t *value = frm->ptr; + int i; + + frm->ptr += 16; + frm->len -= 16; + + p_indent(level, frm); + printf("commitment value "); + for (i = 0; i < 16; i++) + printf("%2.2x", value[i]); + printf("\n"); +} + +static inline void simple_pairing_number_dump(int level, struct frame *frm) +{ + uint8_t *value = frm->ptr; + int i; + + frm->ptr += 16; + frm->len -= 16; + + p_indent(level, frm); + printf("nounce value "); + for (i = 0; i < 16; i++) + printf("%2.2x", value[i]); + printf("\n"); +} + +static inline void dhkey_check_dump(int level, struct frame *frm) +{ + uint8_t *value = frm->ptr; + int i; + + frm->ptr += 16; + frm->len -= 16; + + p_indent(level, frm); + printf("confirmation value "); + for (i = 0; i < 16; i++) + printf("%2.2x", value[i]); + printf("\n"); +} + +static inline void accepted_ext_dump(int level, struct frame *frm) +{ + uint16_t opcode = LMP_U8(frm) + (LMP_U8(frm) << 7); + + p_indent(level, frm); + printf("op code %d/%d (%s)\n", opcode & 0x7f, opcode >> 7, opcode2str(opcode)); +} + +static inline void not_accepted_ext_dump(int level, struct frame *frm) +{ + uint16_t opcode = LMP_U8(frm) + (LMP_U8(frm) << 7); + uint8_t error = LMP_U8(frm); + + p_indent(level, frm); + printf("op code %d/%d (%s)\n", opcode & 0x7f, opcode >> 7, opcode2str(opcode)); + + p_indent(level, frm); + printf("error code 0x%2.2x\n", error); +} + +static inline void features_ext_dump(int level, struct frame *frm) +{ + uint8_t page = LMP_U8(frm); + uint8_t max = LMP_U8(frm); + uint8_t *features = frm->ptr; + int i; + + frm->ptr += 8; + frm->len -= 8; + + p_indent(level, frm); + printf("features page %d\n", page); + + p_indent(level, frm); + printf("max supported page %d\n", max); + + p_indent(level, frm); + printf("extended features"); + for (i = 0; i < 8; i++) + printf(" 0x%2.2x", features[i]); + printf("\n"); +} + +static inline void quality_of_service_dump(int level, struct frame *frm) +{ + uint16_t interval = LMP_U16(frm); + uint8_t nbc = LMP_U8(frm); + + p_indent(level, frm); + printf("poll interval %d\n", interval); + + p_indent(level, frm); + printf("N_BC %d\n", nbc); +} + +static inline void sco_link_req_dump(int level, struct frame *frm) +{ + uint8_t handle = LMP_U8(frm); + uint8_t timing = LMP_U8(frm); + uint8_t dsco = LMP_U8(frm); + uint8_t tsco = LMP_U8(frm); + uint8_t packet = LMP_U8(frm); + uint8_t airmode = LMP_U8(frm); + + p_indent(level, frm); + printf("SCO handle %d\n", handle); + + p_indent(level, frm); + printf("timing control flags 0x%2.2x\n", timing); + + p_indent(level, frm); + printf("D_SCO %d T_SCO %d\n", dsco, tsco); + + p_indent(level, frm); + printf("SCO packet 0x%2.2x\n", packet); + + p_indent(level, frm); + printf("air mode 0x%2.2x\n", airmode); +} + +static inline void remove_sco_link_req_dump(int level, struct frame *frm) +{ + uint8_t handle = LMP_U8(frm); + uint8_t error = LMP_U8(frm); + + p_indent(level, frm); + printf("SCO handle %d\n", handle); + + p_indent(level, frm); + printf("error code 0x%2.2x\n", error); +} + +static inline void max_slots_dump(int level, struct frame *frm) +{ + uint8_t slots = LMP_U8(frm); + + p_indent(level, frm); + printf("max slots %d\n", slots); +} + +static inline void timing_accuracy_dump(int level, struct frame *frm) +{ + uint8_t drift = LMP_U8(frm); + uint8_t jitter = LMP_U8(frm); + + p_indent(level, frm); + printf("drift %d\n", drift); + + p_indent(level, frm); + printf("jitter %d\n", jitter); +} + +static inline void slot_offset_dump(int level, struct frame *frm) +{ + uint16_t offset = LMP_U16(frm); + char addr[18]; + + p_ba2str((bdaddr_t *) frm->ptr, addr); + + p_indent(level, frm); + printf("slot offset %d\n", offset); + + p_indent(level, frm); + printf("BD_ADDR %s\n", addr); +} + +static inline void page_mode_dump(int level, struct frame *frm) +{ + uint8_t scheme = LMP_U8(frm); + uint8_t settings = LMP_U8(frm); + + p_indent(level, frm); + printf("page scheme %d\n", scheme); + + p_indent(level, frm); + printf("page scheme settings %d\n", settings); +} + +static inline void supervision_timeout_dump(int level, struct frame *frm) +{ + uint16_t timeout = LMP_U16(frm); + + p_indent(level, frm); + printf("supervision timeout %d\n", timeout); +} + +static inline void test_control_dump(int level, struct frame *frm) +{ + uint8_t scenario = LMP_U8(frm); + uint8_t hopping = LMP_U8(frm); + uint8_t txfreq = LMP_U8(frm); + uint8_t rxfreq = LMP_U8(frm); + uint8_t power = LMP_U8(frm); + uint8_t poll = LMP_U8(frm); + uint8_t packet = LMP_U8(frm); + uint16_t length = LMP_U16(frm); + + p_indent(level, frm); + printf("test scenario %d\n", scenario); + + p_indent(level, frm); + printf("hopping mode %d\n", hopping); + + p_indent(level, frm); + printf("TX frequency %d\n", txfreq); + + p_indent(level, frm); + printf("RX frequency %d\n", rxfreq); + + p_indent(level, frm); + printf("power control mode %d\n", power); + + p_indent(level, frm); + printf("poll period %d\n", poll); + + p_indent(level, frm); + printf("poll period %d\n", poll); + + p_indent(level, frm); + printf("packet type 0x%2.2x\n", packet); + + p_indent(level, frm); + printf("length of test data %d\n", length); +} + +static inline void encryption_key_size_mask_res_dump(int level, struct frame *frm) +{ + uint16_t mask = LMP_U16(frm); + + p_indent(level, frm); + printf("key size mask 0x%4.4x\n", mask); +} + +static inline void packet_type_table_dump(int level, struct frame *frm) +{ + uint8_t type = LMP_U8(frm); + + p_indent(level, frm); + printf("packet type table %d ", type); + switch (type) { + case 0: + printf("(1Mbps only)\n"); + break; + case 1: + printf("(2/3Mbps)\n"); + break; + default: + printf("(Reserved)\n"); + break; + } +} + +static inline void esco_link_req_dump(int level, struct frame *frm) +{ + uint8_t handle = LMP_U8(frm); + uint8_t ltaddr = LMP_U8(frm); + uint8_t timing = LMP_U8(frm); + uint8_t desco = LMP_U8(frm); + uint8_t tesco = LMP_U8(frm); + uint8_t wesco = LMP_U8(frm); + uint8_t mspkt = LMP_U8(frm); + uint8_t smpkt = LMP_U8(frm); + uint16_t mslen = LMP_U16(frm); + uint16_t smlen = LMP_U16(frm); + uint8_t airmode = LMP_U8(frm); + uint8_t negstate = LMP_U8(frm); + + p_indent(level, frm); + printf("eSCO handle %d\n", handle); + + p_indent(level, frm); + printf("eSCO LT_ADDR %d\n", ltaddr); + + p_indent(level, frm); + printf("timing control flags 0x%2.2x\n", timing); + + p_indent(level, frm); + printf("D_eSCO %d T_eSCO %d W_eSCO %d\n", desco, tesco, wesco); + + p_indent(level, frm); + printf("eSCO M->S packet type 0x%2.2x length %d\n", mspkt, mslen); + + p_indent(level, frm); + printf("eSCO S->M packet type 0x%2.2x length %d\n", smpkt, smlen); + + p_indent(level, frm); + printf("air mode 0x%2.2x\n", airmode); + + p_indent(level, frm); + printf("negotiation state 0x%2.2x\n", negstate); +} + +static inline void remove_esco_link_req_dump(int level, struct frame *frm) +{ + uint8_t handle = LMP_U8(frm); + uint8_t error = LMP_U8(frm); + + p_indent(level, frm); + printf("eSCO handle %d\n", handle); + + p_indent(level, frm); + printf("error code 0x%2.2x\n", error); +} + +static inline void channel_classification_req_dump(int level, struct frame *frm) +{ + uint8_t mode = LMP_U8(frm); + uint16_t min = LMP_U16(frm); + uint16_t max = LMP_U16(frm); + + p_indent(level, frm); + printf("AFH reporting mode %d\n", mode); + + p_indent(level, frm); + printf("AFH min interval 0x%4.4x\n", min); + + p_indent(level, frm); + printf("AFH max interval 0x%4.4x\n", max); +} + +static inline void channel_classification_dump(int level, struct frame *frm) +{ + uint8_t *map = frm->ptr; + int i; + + frm->ptr += 10; + frm->len -= 10; + + p_indent(level, frm); + printf("AFH channel classification 0x"); + for (i = 0; i < 10; i++) + printf("%2.2x", map[i]); + printf("\n"); +} + +static inline void sniff_subrating_dump(int level, struct frame *frm) +{ + uint8_t subrate = LMP_U8(frm); + uint16_t timeout = LMP_U16(frm); + uint32_t instant = LMP_U32(frm); + + p_indent(level, frm); + printf("max subrate %d\n", subrate); + + p_indent(level, frm); + printf("min sniff timeout %d\n", timeout); + + p_indent(level, frm); + printf("subrate instant 0x%4.4x\n", instant); +} + +static inline void io_capability_dump(int level, struct frame *frm) +{ + uint8_t capability = LMP_U8(frm); + uint8_t oob_data = LMP_U8(frm); + uint8_t authentication = LMP_U8(frm); + + p_indent(level, frm); + printf("capability 0x%2.2x oob 0x%2.2x auth 0x%2.2x\n", + capability, oob_data, authentication); +} + +static inline void keypress_notification_dump(int level, struct frame *frm) +{ + uint8_t value = LMP_U8(frm); + + p_indent(level, frm); + printf("notification value %d\n", value); +} + +void lmp_dump(int level, struct frame *frm) +{ + uint8_t tmp, tid; + uint16_t opcode; + + p_indent(level, frm); + + tmp = LMP_U8(frm); + tid = tmp & 0x01; + opcode = (tmp & 0xfe) >> 1; + if (opcode > 123) { + tmp = LMP_U8(frm); + opcode += tmp << 7; + } + + printf("LMP(%c): %s(%c): ", frm->master ? 's' : 'r', + opcode2str(opcode), tid ? 's' : 'm'); + + if (opcode > 123) + printf("op code %d/%d", opcode & 0x7f, opcode >> 7); + else + printf("op code %d", opcode); + + if (frm->handle > 17) + printf(" handle %d\n", frm->handle); + else + printf("\n"); + + if (!(parser.flags & DUMP_VERBOSE)) { + raw_dump(level, frm); + return; + } + + switch (opcode) { + case 1: + name_req_dump(level + 1, frm); + return; + case 2: + name_res_dump(level + 1, frm); + return; + case 3: + accepted_dump(level + 1, frm); + return; + case 4: + not_accepted_dump(level + 1, frm); + return; + case 6: + clkoffset_dump(level + 1, frm); + return; + case 7: + detach_dump(level + 1, frm); + return; + case 8: + in_rand(frm); + random_number_dump(level + 1, frm); + return; + case 9: + comb_key(frm); + random_number_dump(level + 1, frm); + return; + case 11: + au_rand(frm); + random_number_dump(level + 1, frm); + return; + case 12: + sres(frm); + auth_resp_dump(level + 1, frm); + return; + case 13: + case 17: + random_number_dump(level + 1, frm); + return; + case 10: + case 14: + key_dump(level + 1, frm); + return; + case 15: + encryption_mode_req_dump(level + 1, frm); + return; + case 16: + encryption_key_size_req_dump(level + 1, frm); + return; + case 19: + switch_req_dump(level + 1, frm); + return; + case 20: + case 21: + hold_dump(level + 1, frm); + return; + case 23: + sniff_req_dump(level + 1, frm); + return; + case 25: + park_req_dump(level + 1, frm); + return; + case 28: + modify_beacon_dump(level + 1, frm); + return; + case 31: + case 32: + power_req_dump(level + 1, frm); + return; + case 36: + preferred_rate_dump(level + 1, frm); + return; + case 37: + case 38: + version_dump(level + 1, frm); + return; + case 39: + case 40: + features_dump(level + 1, frm); + return; + case 41: + case 42: + quality_of_service_dump(level + 1, frm); + return; + case 43: + sco_link_req_dump(level + 1, frm); + return; + case 44: + remove_sco_link_req_dump(level + 1, frm); + return; + case 45: + case 46: + max_slots_dump(level + 1, frm); + return; + case 48: + timing_accuracy_dump(level + 1, frm); + return; + case 52: + slot_offset_dump(level + 1, frm); + return; + case 53: + case 54: + page_mode_dump(level + 1, frm); + return; + case 55: + supervision_timeout_dump(level + 1, frm); + return; + case 57: + test_control_dump(level + 1, frm); + return; + case 59: + encryption_key_size_mask_res_dump(level + 1, frm); + return; + case 60: + set_afh_dump(level + 1, frm); + return; + case 61: + encapsulated_header_dump(level + 1, frm); + return; + case 62: + encapsulated_payload_dump(level + 1, frm); + return; + case 63: + simple_pairing_confirm_dump(level + 1, frm); + return; + case 64: + simple_pairing_number_dump(level + 1, frm); + return; + case 65: + dhkey_check_dump(level + 1, frm); + return; + case 5: + case 18: + case 24: + case 33: + case 34: + case 35: + case 47: + case 49: + case 50: + case 51: + case 56: + case 58: + case 127 + (23 << 7): + case 127 + (24 << 7): + case 127 + (27 << 7): + case 127 + (28 << 7): + case 127 + (29 << 7): + return; + case 127 + (1 << 7): + accepted_ext_dump(level + 1, frm); + return; + case 127 + (2 << 7): + not_accepted_ext_dump(level + 1, frm); + return; + case 127 + (3 << 7): + case 127 + (4 << 7): + features_ext_dump(level + 1, frm); + return; + case 127 + (11 << 7): + packet_type_table_dump(level + 1, frm); + return; + case 127 + (12 << 7): + esco_link_req_dump(level + 1, frm); + return; + case 127 + (13 << 7): + remove_esco_link_req_dump(level + 1, frm); + return; + case 127 + (16 << 7): + channel_classification_req_dump(level + 1, frm); + return; + case 127 + (17 << 7): + channel_classification_dump(level + 1, frm); + return; + case 127 + (21 << 7): + case 127 + (22 << 7): + sniff_subrating_dump(level + 1, frm); + return; + case 127 + (25 << 7): + case 127 + (26 << 7): + io_capability_dump(level + 1, frm); + return; + case 127 + (30 << 7): + keypress_notification_dump(level + 1, frm); + return; + } + + raw_dump(level, frm); +} diff --git a/hcidump/parser/obex.c b/hcidump/parser/obex.c new file mode 100644 index 000000000..0f6844348 --- /dev/null +++ b/hcidump/parser/obex.c @@ -0,0 +1,309 @@ +/* + * + * 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 + +#include "parser.h" + +static char *opcode2str(uint8_t opcode) +{ + switch (opcode & 0x7f) { + case 0x00: + return "Connect"; + case 0x01: + return "Disconnect"; + case 0x02: + return "Put"; + case 0x03: + return "Get"; + case 0x04: + return "Reserved"; + case 0x05: + return "SetPath"; + case 0x06: + return "Reserved"; + case 0x07: + return "Session"; + case 0x7f: + return "Abort"; + case 0x10: + return "Continue"; + case 0x20: + return "Success"; + case 0x21: + return "Created"; + case 0x22: + return "Accepted"; + case 0x23: + return "Non-authoritative information"; + case 0x24: + return "No content"; + case 0x25: + return "Reset content"; + case 0x26: + return "Partial content"; + case 0x30: + return "Multiple choices"; + case 0x31: + return "Moved permanently"; + case 0x32: + return "Moved temporarily"; + case 0x33: + return "See other"; + case 0x34: + return "Not modified"; + case 0x35: + return "Use Proxy"; + case 0x40: + return "Bad request"; + case 0x41: + return "Unauthorized"; + case 0x42: + return "Payment required"; + case 0x43: + return "Forbidden"; + case 0x44: + return "Not found"; + case 0x45: + return "Method not allowed"; + case 0x46: + return "Not acceptable"; + case 0x47: + return "Proxy authentication required"; + case 0x48: + return "Request timeout"; + case 0x49: + return "Conflict"; + case 0x4a: + return "Gone"; + case 0x4b: + return "Length required"; + case 0x4c: + return "Precondition failed"; + case 0x4d: + return "Requested entity too large"; + case 0x4e: + return "Requested URL too large"; + case 0x4f: + return "Unsupported media type"; + case 0x50: + return "Internal server error"; + case 0x51: + return "Not implemented"; + case 0x52: + return "Bad gateway"; + case 0x53: + return "Service unavailable"; + case 0x54: + return "Gateway timeout"; + case 0x55: + return "HTTP version not supported"; + case 0x60: + return "Database full"; + case 0x61: + return "Database locked"; + default: + return "Unknown"; + } +} + +static char *hi2str(uint8_t hi) +{ + switch (hi & 0x3f) { + case 0x00: + return "Count"; + case 0x01: + return "Name"; + case 0x02: + return "Type"; + case 0x03: + return "Length"; + case 0x04: + return "Time"; + case 0x05: + return "Description"; + case 0x06: + return "Target"; + case 0x07: + return "HTTP"; + case 0x08: + return "Body"; + case 0x09: + return "End of Body"; + case 0x0a: + return "Who"; + case 0x0b: + return "Connection ID"; + case 0x0c: + return "App. Parameters"; + case 0x0d: + return "Auth. Challenge"; + case 0x0e: + return "Auth. Response"; + case 0x0f: + return "Creator ID"; + case 0x10: + return "WAN UUID"; + case 0x11: + return "Object Class"; + case 0x12: + return "Session Parameters"; + case 0x13: + return "Session Sequence Number"; + default: + return "Unknown"; + } +} + +static void parse_headers(int level, struct frame *frm) +{ + uint8_t hi, hv8; + uint16_t len; + uint32_t hv32; + + while (frm->len > 0) { + hi = get_u8(frm); + + p_indent(level, frm); + + printf("%s (0x%02x)", hi2str(hi), hi); + switch (hi & 0xc0) { + case 0x00: /* Unicode */ + len = get_u16(frm) - 3; + printf(" = Unicode length %d\n", len); + raw_ndump(level, frm, len); + frm->ptr += len; + frm->len -= len; + break; + + case 0x40: /* Byte sequence */ + len = get_u16(frm) - 3; + printf(" = Sequence length %d\n", len); + raw_ndump(level, frm, len); + frm->ptr += len; + frm->len -= len; + break; + + case 0x80: /* One byte */ + hv8 = get_u8(frm); + printf(" = %d\n", hv8); + break; + + case 0xc0: /* Four bytes */ + hv32 = get_u32(frm); + printf(" = %u\n", hv32); + break; + } + } +} + +void obex_dump(int level, struct frame *frm) +{ + uint8_t last_opcode, opcode, status; + uint8_t version, flags, constants; + uint16_t length, pktlen; + + frm = add_frame(frm); + + while (frm->len > 0) { + opcode = get_u8(frm); + length = get_u16(frm); + status = opcode & 0x7f; + + if (frm->len < length - 3) { + frm->ptr -= 3; + frm->len += 3; + return; + } + + p_indent(level, frm); + + last_opcode = get_opcode(frm->handle, frm->dlci); + + if (!(opcode & 0x70)) { + printf("OBEX: %s cmd(%c): len %d", + opcode2str(opcode), + opcode & 0x80 ? 'f' : 'c', length); + set_opcode(frm->handle, frm->dlci, opcode); + } else { + printf("OBEX: %s rsp(%c): status %x%02d len %d", + opcode2str(last_opcode), + opcode & 0x80 ? 'f' : 'c', + status >> 4, status & 0xf, length); + opcode = last_opcode; + } + + if (get_status(frm->handle, frm->dlci) == 0x10) + printf(" (continue)"); + + set_status(frm->handle, frm->dlci, status); + + if (frm->len == 0) { + printf("\n"); + break; + } + + switch (opcode & 0x7f) { + case 0x00: /* Connect */ + version = get_u8(frm); + flags = get_u8(frm); + pktlen = get_u16(frm); + printf(" version %d.%d flags %d mtu %d\n", + version >> 4, version & 0xf, flags, pktlen); + break; + + case 0x05: /* SetPath */ + if (length > 3) { + flags = get_u8(frm); + constants = get_u8(frm); + printf(" flags %d constants %d\n", + flags, constants); + } else + printf("\n"); + break; + + default: + printf("\n"); + } + + if ((status & 0x70) && (parser.flags & DUMP_VERBOSE)) { + p_indent(level, frm); + printf("Status %x%02d = %s\n", + status >> 4, status & 0xf, + opcode2str(status)); + } + + parse_headers(level, frm); + } +} diff --git a/hcidump/parser/parser.c b/hcidump/parser/parser.c new file mode 100644 index 000000000..e50590efb --- /dev/null +++ b/hcidump/parser/parser.c @@ -0,0 +1,346 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2002 Maxim Krasnyansky + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "parser.h" +#include "rfcomm.h" + +struct parser_t parser; + +void init_parser(unsigned long flags, unsigned long filter, + unsigned short defpsm, unsigned short defcompid, + int pppdump_fd, int audio_fd) +{ + if ((flags & DUMP_RAW) && !(flags & DUMP_TYPE_MASK)) + flags |= DUMP_HEX; + + parser.flags = flags; + parser.filter = filter; + parser.defpsm = defpsm; + parser.defcompid = defcompid; + parser.state = 0; + parser.pppdump_fd = pppdump_fd; + parser.audio_fd = audio_fd; +} + +#define PROTO_TABLE_SIZE 20 + +static struct { + uint16_t handle; + uint16_t psm; + uint8_t channel; + uint32_t proto; +} proto_table[PROTO_TABLE_SIZE]; + +void set_proto(uint16_t handle, uint16_t psm, uint8_t channel, uint32_t proto) +{ + int i, pos = -1; + + if (psm > 0 && psm < 0x1000 && !channel) + return; + + if (!psm && channel) + psm = RFCOMM_PSM; + + for (i = 0; i < PROTO_TABLE_SIZE; i++) { + if (proto_table[i].handle == handle && proto_table[i].psm == psm && proto_table[i].channel == channel) { + pos = i; + break; + } + + if (pos < 0 && !proto_table[i].handle && !proto_table[i].psm && !proto_table[i].channel) + pos = i; + } + + if (pos < 0) + return; + + proto_table[pos].handle = handle; + proto_table[pos].psm = psm; + proto_table[pos].channel = channel; + proto_table[pos].proto = proto; +} + +uint32_t get_proto(uint16_t handle, uint16_t psm, uint8_t channel) +{ + int i, pos = -1; + + if (!psm && channel) + psm = RFCOMM_PSM; + + for (i = 0; i < PROTO_TABLE_SIZE; i++) { + if (proto_table[i].handle == handle && proto_table[i].psm == psm && proto_table[i].channel == channel) + return proto_table[i].proto; + + if (!proto_table[i].handle) { + if (proto_table[i].psm == psm && proto_table[i].channel == channel) + pos = i; + } + } + + return (pos < 0) ? 0 : proto_table[pos].proto; +} + +#define FRAME_TABLE_SIZE 20 + +static struct { + uint16_t handle; + uint8_t dlci; + uint8_t opcode; + uint8_t status; + struct frame frm; +} frame_table[FRAME_TABLE_SIZE]; + +void del_frame(uint16_t handle, uint8_t dlci) +{ + int i; + + for (i = 0; i < FRAME_TABLE_SIZE; i++) + if (frame_table[i].handle == handle && + frame_table[i].dlci == dlci) { + frame_table[i].handle = 0; + frame_table[i].dlci = 0; + frame_table[i].opcode = 0; + frame_table[i].status = 0; + if (frame_table[i].frm.data) + free(frame_table[i].frm.data); + memset(&frame_table[i].frm, 0, sizeof(struct frame)); + break; + } +} + +struct frame *add_frame(struct frame *frm) +{ + struct frame *fr; + void *data; + int i, pos = -1; + + for (i = 0; i < FRAME_TABLE_SIZE; i++) { + if (frame_table[i].handle == frm->handle && + frame_table[i].dlci == frm->dlci) { + pos = i; + break; + } + + if (pos < 0 && !frame_table[i].handle && !frame_table[i].dlci) + pos = i; + } + + if (pos < 0) + return frm; + + frame_table[pos].handle = frm->handle; + frame_table[pos].dlci = frm->dlci; + fr = &frame_table[pos].frm; + + data = malloc(fr->len + frm->len); + if (!data) { + perror("Can't allocate frame stream buffer"); + del_frame(frm->handle, frm->dlci); + return frm; + } + + if (fr->len > 0) + memcpy(data, fr->ptr, fr->len); + + if (frm->len > 0) + memcpy(data + fr->len, frm->ptr, frm->len); + + if (fr->data) + free(fr->data); + + fr->data = data; + fr->data_len = fr->len + frm->len; + fr->len = fr->data_len; + fr->ptr = fr->data; + fr->dev_id = frm->dev_id; + fr->in = frm->in; + fr->ts = frm->ts; + fr->handle = frm->handle; + fr->cid = frm->cid; + fr->num = frm->num; + fr->dlci = frm->dlci; + fr->channel = frm->channel; + fr->pppdump_fd = frm->pppdump_fd; + fr->audio_fd = frm->audio_fd; + + return fr; +} + +uint8_t get_opcode(uint16_t handle, uint8_t dlci) +{ + int i; + + for (i = 0; i < FRAME_TABLE_SIZE; i++) + if (frame_table[i].handle == handle && + frame_table[i].dlci == dlci) + return frame_table[i].opcode; + + return 0x00; +} + +void set_opcode(uint16_t handle, uint8_t dlci, uint8_t opcode) +{ + int i; + + for (i = 0; i < FRAME_TABLE_SIZE; i++) + if (frame_table[i].handle == handle && + frame_table[i].dlci == dlci) { + frame_table[i].opcode = opcode; + break; + } +} + +uint8_t get_status(uint16_t handle, uint8_t dlci) +{ + int i; + + for (i = 0; i < FRAME_TABLE_SIZE; i++) + if (frame_table[i].handle == handle && + frame_table[i].dlci == dlci) + return frame_table[i].status; + + return 0x00; +} + +void set_status(uint16_t handle, uint8_t dlci, uint8_t status) +{ + int i; + + for (i = 0; i < FRAME_TABLE_SIZE; i++) + if (frame_table[i].handle == handle && + frame_table[i].dlci == dlci) { + frame_table[i].status = status; + break; + } +} + +void ascii_dump(int level, struct frame *frm, int num) +{ + unsigned char *buf = frm->ptr; + register int i, n; + + if ((num < 0) || (num > frm->len)) + num = frm->len; + + for (i = 0, n = 1; i < num; i++, n++) { + if (n == 1) + p_indent(level, frm); + printf("%1c ", isprint(buf[i]) ? buf[i] : '.'); + if (n == DUMP_WIDTH) { + printf("\n"); + n = 0; + } + } + if (i && n != 1) + printf("\n"); +} + +void hex_dump(int level, struct frame *frm, int num) +{ + unsigned char *buf = frm->ptr; + register int i, n; + + if ((num < 0) || (num > frm->len)) + num = frm->len; + + for (i = 0, n = 1; i < num; i++, n++) { + if (n == 1) + p_indent(level, frm); + printf("%2.2X ", buf[i]); + if (n == DUMP_WIDTH) { + printf("\n"); + n = 0; + } + } + if (i && n != 1) + printf("\n"); +} + +void ext_dump(int level, struct frame *frm, int num) +{ + unsigned char *buf = frm->ptr; + register int i, n = 0, size; + + if ((num < 0) || (num > frm->len)) + num = frm->len; + + while (num > 0) { + p_indent(level, frm); + printf("%04x: ", n); + + size = num > 16 ? 16 : num; + + for (i = 0; i < size; i++) + printf("%02x%s", buf[i], (i + 1) % 8 ? " " : " "); + for (i = size; i < 16; i++) + printf(" %s", (i + 1) % 8 ? " " : " "); + + for (i = 0; i < size; i++) + printf("%1c", isprint(buf[i]) ? buf[i] : '.'); + printf("\n"); + + buf += size; + num -= size; + n += size; + } +} + +void raw_ndump(int level, struct frame *frm, int num) +{ + if (!frm->len) + return; + + switch (parser.flags & DUMP_TYPE_MASK) { + case DUMP_ASCII: + ascii_dump(level, frm, num); + break; + + case DUMP_HEX: + hex_dump(level, frm, num); + break; + + case DUMP_EXT: + ext_dump(level, frm, num); + break; + } +} + +void raw_dump(int level, struct frame *frm) +{ + raw_ndump(level, frm, -1); +} diff --git a/hcidump/parser/parser.h b/hcidump/parser/parser.h new file mode 100644 index 000000000..d3a039791 --- /dev/null +++ b/hcidump/parser/parser.h @@ -0,0 +1,252 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2002 Maxim Krasnyansky + * Copyright (C) 2003-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 + * + */ + +#ifndef __PARSER_H +#define __PARSER_H + +#include +#include +#include +#include + +struct frame { + void *data; + uint32_t data_len; + void *ptr; + uint32_t len; + uint16_t dev_id; + uint8_t in; + uint8_t master; + uint16_t handle; + uint16_t cid; + uint16_t num; + uint8_t dlci; + uint8_t channel; + unsigned long flags; + struct timeval ts; + int pppdump_fd; + int audio_fd; +}; + +/* Parser flags */ +#define DUMP_WIDTH 20 + +#define DUMP_ASCII 0x0001 +#define DUMP_HEX 0x0002 +#define DUMP_EXT 0x0004 +#define DUMP_RAW 0x0008 +#define DUMP_BPA 0x0010 +#define DUMP_TSTAMP 0x0100 +#define DUMP_VERBOSE 0x0200 +#define DUMP_BTSNOOP 0x1000 +#define DUMP_PKTLOG 0x2000 +#define DUMP_NOVENDOR 0x4000 +#define DUMP_TYPE_MASK (DUMP_ASCII | DUMP_HEX | DUMP_EXT) + +/* Parser filter */ +#define FILT_LMP 0x0001 +#define FILT_HCI 0x0002 +#define FILT_SCO 0x0004 +#define FILT_L2CAP 0x0008 +#define FILT_RFCOMM 0x0010 +#define FILT_SDP 0x0020 +#define FILT_BNEP 0x0040 +#define FILT_CMTP 0x0080 +#define FILT_HIDP 0x0100 +#define FILT_HCRP 0x0200 +#define FILT_AVDTP 0x0400 +#define FILT_AVCTP 0x0800 + +#define FILT_OBEX 0x00010000 +#define FILT_CAPI 0x00020000 +#define FILT_PPP 0x00040000 +#define FILT_ERICSSON 0x10000000 +#define FILT_CSR 0x1000000a +#define FILT_DGA 0x1000000c + +#define STRUCT_OFFSET(type, member) ((uint8_t *)&(((type *)NULL)->member) - \ + (uint8_t *)((type *)NULL)) + +#define STRUCT_END(type, member) (STRUCT_OFFSET(type, member) + \ + sizeof(((type *)NULL)->member)) + +#define DEFAULT_COMPID 65535 + +struct parser_t { + unsigned long flags; + unsigned long filter; + unsigned short defpsm; + unsigned short defcompid; + int state; + int pppdump_fd; + int audio_fd; +}; + +extern struct parser_t parser; + +void init_parser(unsigned long flags, unsigned long filter, + unsigned short defpsm, unsigned short defcompid, + int pppdump_fd, int audio_fd); + +static inline int p_filter(unsigned long f) +{ + return !(parser.filter & f); +} + +static inline void p_indent(int level, struct frame *f) +{ + if (level < 0) { + parser.state = 0; + return; + } + + if (!parser.state) { + if (parser.flags & DUMP_TSTAMP) { + if (parser.flags & DUMP_VERBOSE) { + struct tm tm; + time_t t = f->ts.tv_sec; + localtime_r(&t, &tm); + printf("%04d-%02d-%02d %02d:%02d:%02d.%06lu ", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, f->ts.tv_usec); + } else + printf("%8lu.%06lu ", f->ts.tv_sec, f->ts.tv_usec); + } + printf("%c ", (f->in ? '>' : '<')); + parser.state = 1; + } else + printf(" "); + + if (level) + printf("%*c", (level*2), ' '); +} + +static inline void p_ba2str(const bdaddr_t *ba, char *str) +{ + if (parser.flags & DUMP_NOVENDOR) { + uint8_t b[6]; + + baswap((bdaddr_t *) b, ba); + sprintf(str, "%2.2X:%2.2X:%2.2X:*:*:*", b[0], b[1], b[2]); + } else + ba2str(ba, str); +} + +/* get_uXX functions do byte swaping */ + +static inline uint8_t get_u8(struct frame *frm) +{ + uint8_t *u8_ptr = frm->ptr; + frm->ptr += 1; + frm->len -= 1; + return *u8_ptr; +} + +static inline uint16_t get_u16(struct frame *frm) +{ + uint16_t *u16_ptr = frm->ptr; + frm->ptr += 2; + frm->len -= 2; + return ntohs(bt_get_unaligned(u16_ptr)); +} + +static inline uint32_t get_u32(struct frame *frm) +{ + uint32_t *u32_ptr = frm->ptr; + frm->ptr += 4; + frm->len -= 4; + return ntohl(bt_get_unaligned(u32_ptr)); +} + +static inline uint64_t get_u64(struct frame *frm) +{ + uint64_t *u64_ptr = frm->ptr; + uint64_t u64 = bt_get_unaligned(u64_ptr), tmp; + frm->ptr += 8; + frm->len -= 8; + tmp = ntohl(u64 & 0xffffffff); + u64 = (tmp << 32) | ntohl(u64 >> 32); + return u64; +} + +static inline void get_u128(struct frame *frm, uint64_t *l, uint64_t *h) +{ + *h = get_u64(frm); + *l = get_u64(frm); +} + +char *get_uuid_name(int uuid); + +void set_proto(uint16_t handle, uint16_t psm, uint8_t channel, uint32_t proto); +uint32_t get_proto(uint16_t handle, uint16_t psm, uint8_t channel); + +struct frame *add_frame(struct frame *frm); +void del_frame(uint16_t handle, uint8_t dlci); + +uint8_t get_opcode(uint16_t handle, uint8_t dlci); +void set_opcode(uint16_t handle, uint8_t dlci, uint8_t opcode); + +uint8_t get_status(uint16_t handle, uint8_t dlci); +void set_status(uint16_t handle, uint8_t dlci, uint8_t status); + +void l2cap_clear(uint16_t handle); + +void ascii_dump(int level, struct frame *frm, int num); +void hex_dump(int level, struct frame *frm, int num); +void ext_dump(int level, struct frame *frm, int num); +void raw_dump(int level, struct frame *frm); +void raw_ndump(int level, struct frame *frm, int num); + +void lmp_dump(int level, struct frame *frm); +void hci_dump(int level, struct frame *frm); +void l2cap_dump(int level, struct frame *frm); +void rfcomm_dump(int level, struct frame *frm); +void sdp_dump(int level, struct frame *frm); +void bnep_dump(int level, struct frame *frm); +void cmtp_dump(int level, struct frame *frm); +void hidp_dump(int level, struct frame *frm); +void hcrp_dump(int level, struct frame *frm); +void avdtp_dump(int level, struct frame *frm); +void avctp_dump(int level, struct frame *frm); + +void obex_dump(int level, struct frame *frm); +void capi_dump(int level, struct frame *frm); +void ppp_dump(int level, struct frame *frm); +void arp_dump(int level, struct frame *frm); +void ip_dump(int level, struct frame *frm); +void ericsson_dump(int level, struct frame *frm); +void csr_dump(int level, struct frame *frm); +void bpa_dump(int level, struct frame *frm); + +static inline void parse(struct frame *frm) +{ + p_indent(-1, NULL); + if (parser.flags & DUMP_RAW) + raw_dump(0, frm); + else + hci_dump(0, frm); + fflush(stdout); +} + +#endif /* __PARSER_H */ diff --git a/hcidump/parser/ppp.c b/hcidump/parser/ppp.c new file mode 100644 index 000000000..6ef24e919 --- /dev/null +++ b/hcidump/parser/ppp.c @@ -0,0 +1,229 @@ +/* + * + * 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 "parser.h" + +#define PPP_U8(frm) (get_u8(frm)) +#define PPP_U16(frm) (btohs(htons(get_u16(frm)))) +#define PPP_U32(frm) (btohl(htonl(get_u32(frm)))) + +static int ppp_traffic = 0; + +static unsigned char ppp_magic1[] = { 0x7e, 0xff, 0x03, 0xc0, 0x21 }; +static unsigned char ppp_magic2[] = { 0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21 }; +static unsigned char ppp_magic3[] = { 0x7e, 0x7d, 0xdf, 0x7d, 0x23, 0xc0, 0x21 }; + +static inline int check_for_ppp_traffic(unsigned char *data, int size) +{ + int i; + + for (i = 0; i < size - sizeof(ppp_magic1); i++) + if (!memcmp(data + i, ppp_magic1, sizeof(ppp_magic1))) { + ppp_traffic = 1; + return i; + } + + for (i = 0; i < size - sizeof(ppp_magic2); i++) + if (!memcmp(data + i, ppp_magic2, sizeof(ppp_magic2))) { + ppp_traffic = 1; + return i; + } + + for (i = 0; i < size - sizeof(ppp_magic3); i++) + if (!memcmp(data + i, ppp_magic3, sizeof(ppp_magic3))) { + ppp_traffic = 1; + return i; + } + + return -1; +} + +static inline char *dir2str(uint8_t in) +{ + return in ? "DCE" : "DTE"; +} + +static inline char *proto2str(uint16_t proto) +{ + switch (proto) { + case 0x0001: + return "Padding Protocol"; + case 0x0021: + return "IP"; + case 0x8021: + return "IP Control Protocol"; + case 0x80fd: + return "Compression Control Protocol"; + case 0xc021: + return "Link Control Protocol"; + case 0xc023: + return "Password Authentication Protocol"; + case 0xc025: + return "Link Quality Report"; + case 0xc223: + return "Challenge Handshake Authentication Protocol"; + default: + return "Unknown Protocol"; + } +} + +static void hdlc_dump(int level, struct frame *frm) +{ + uint8_t addr = get_u8(frm); + uint8_t ctrl = get_u8(frm); + uint16_t fcs, proto; + + fcs = bt_get_unaligned((uint16_t *) (frm->ptr + frm->len - 2)); + frm->len -= 2; + + p_indent(level, frm); + + if (addr != 0xff || ctrl != 0x03) { + frm->ptr -= 2; + frm->len += 2; + printf("HDLC: %s: len %d fcs 0x%04x\n", + dir2str(frm->in), frm->len, fcs); + } else + printf("HDLC: %s: addr 0x%02x ctrl 0x%02x len %d fcs 0x%04x\n", + dir2str(frm->in), addr, ctrl, frm->len, fcs); + + if (*((uint8_t *) frm->ptr) & 0x80) + proto = get_u16(frm); + else + proto = get_u8(frm); + + p_indent(level + 1, frm); + printf("PPP: %s (0x%04x): len %d\n", proto2str(proto), proto, frm->len); + + raw_dump(level + 1, frm); +} + +static inline void unslip_frame(int level, struct frame *frm, int len) +{ + struct frame msg; + unsigned char *data, *ptr; + int i, p = 0; + + data = malloc(len * 2); + if (!data) + return; + + ptr = frm->ptr; + + for (i = 0; i < len; i++) { + if (ptr[i] == 0x7d) { + data[p++] = ptr[i + 1] ^ 0x20; + i++; + } else + data[p++] = ptr[i]; + } + + memset(&msg, 0, sizeof(msg)); + msg.data = data; + msg.data_len = len * 2; + msg.ptr = msg.data; + msg.len = p; + msg.in = frm->in; + msg.ts = frm->ts; + msg.handle = frm->handle; + msg.cid = frm->cid; + + hdlc_dump(level, &msg); + + free(data); +} + +void ppp_dump(int level, struct frame *frm) +{ + void *ptr, *end; + int err, len, pos = 0; + + if (frm->pppdump_fd > fileno(stderr)) { + unsigned char id; + uint16_t len = htons(frm->len); + uint32_t ts = htonl(frm->ts.tv_sec & 0xffffffff); + + id = 0x07; + err = write(frm->pppdump_fd, &id, 1); + err = write(frm->pppdump_fd, &ts, 4); + + id = frm->in ? 0x02 : 0x01; + err = write(frm->pppdump_fd, &id, 1); + err = write(frm->pppdump_fd, &len, 2); + err = write(frm->pppdump_fd, frm->ptr, frm->len); + } + + if (!ppp_traffic) { + pos = check_for_ppp_traffic(frm->ptr, frm->len); + if (pos < 0) { + raw_dump(level, frm); + return; + } + + if (pos > 0) { + raw_ndump(level, frm, pos); + frm->ptr += pos; + frm->len -= pos; + } + } + + frm = add_frame(frm); + + while (frm->len > 0) { + ptr = memchr(frm->ptr, 0x7e, frm->len); + if (!ptr) + break; + + if (frm->ptr != ptr) { + frm->len -= (ptr - frm->ptr); + frm->ptr = ptr; + } + + end = memchr(frm->ptr + 1, 0x7e, frm->len - 1); + if (!end) + break; + + len = end - ptr - 1; + + frm->ptr++; + frm->len--; + + if (len > 0) { + unslip_frame(level, frm, len); + + frm->ptr += len; + frm->len -= len; + } + } +} diff --git a/hcidump/parser/rfcomm.c b/hcidump/parser/rfcomm.c new file mode 100644 index 000000000..b85df91ad --- /dev/null +++ b/hcidump/parser/rfcomm.c @@ -0,0 +1,350 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Wayne Lee + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "parser.h" +#include "rfcomm.h" +#include "sdp.h" + +static char *cr_str[] = { + "RSP", + "CMD" +}; + +#define CR_STR(mcc_head) cr_str[mcc_head->type.cr] +#define GET_DLCI(addr) ((addr.server_chn << 1) | (addr.d & 1)) + +static void print_rfcomm_hdr(long_frame_head* head, uint8_t *ptr, int len) +{ + address_field addr = head->addr; + uint8_t ctr = head->control; + uint16_t ilen = head->length.bits.len; + uint8_t ctr_type,pf,dlci,fcs; + + dlci = GET_DLCI(addr); + pf = GET_PF(ctr); + ctr_type = CLR_PF(ctr); + fcs = *(ptr + len - 1); + + printf("cr %d dlci %d pf %d ilen %d fcs 0x%x ", addr.cr, dlci, pf, ilen, fcs); +} + +static void print_mcc(mcc_long_frame_head* mcc_head) +{ + printf("mcc_len %d\n", mcc_head->length.bits.len); +} + +static inline void mcc_test(int level, uint8_t *ptr, int len, + long_frame_head *head, mcc_long_frame_head *mcc_head) +{ + printf("TEST %s: ", CR_STR(mcc_head)); + print_rfcomm_hdr(head, ptr, len); + print_mcc(mcc_head); +} +static inline void mcc_fcon(int level, uint8_t *ptr, int len, + long_frame_head *head, mcc_long_frame_head *mcc_head) +{ + printf("FCON %s: ", CR_STR(mcc_head)); + print_rfcomm_hdr(head, ptr, len); + print_mcc(mcc_head); +} + +static inline void mcc_fcoff(int level, uint8_t *ptr, int len, + long_frame_head *head, mcc_long_frame_head *mcc_head) +{ + printf("FCOFF %s: ", CR_STR(mcc_head)); + print_rfcomm_hdr(head, ptr, len); + print_mcc(mcc_head); +} + +static inline void mcc_msc(int level, uint8_t *ptr, int len, + long_frame_head *head, mcc_long_frame_head *mcc_head) +{ + msc_msg *msc = (void*) (ptr - STRUCT_END(msc_msg, mcc_s_head)); + + printf("MSC %s: ", CR_STR(mcc_head)); + print_rfcomm_hdr(head, ptr, len); + print_mcc(mcc_head); + p_indent(level, 0); + printf("dlci %d fc %d rtc %d rtr %d ic %d dv %d", + GET_DLCI(msc->dlci), msc->v24_sigs.fc, msc->v24_sigs.rtc, + msc->v24_sigs.rtr, msc->v24_sigs.ic, msc->v24_sigs.dv ); + + /* Assuming that break_signals field is _not declared_ in struct msc_msg... */ + if (len > STRUCT_OFFSET(msc_msg, fcs) - STRUCT_END(msc_msg, v24_sigs)) { + break_signals *brk = (break_signals *) + (ptr + STRUCT_END(msc_msg, v24_sigs)); + printf(" b1 %d b2 %d b3 %d len %d\n", + brk->b1, brk->b2, brk->b3, brk->len); + } else + printf("\n"); +} + +static inline void mcc_rpn(int level, uint8_t *ptr, int len, + long_frame_head *head, mcc_long_frame_head *mcc_head) +{ + rpn_msg *rpn = (void *) (ptr - STRUCT_END(rpn_msg, mcc_s_head)); + + printf("RPN %s: ", CR_STR(mcc_head)); + print_rfcomm_hdr(head, ptr, len); + print_mcc(mcc_head); + + p_indent(level, 0); + printf("dlci %d ", GET_DLCI(rpn->dlci)); + + /* Assuming that rpn_val is _declared_ as a member of rpn_msg... */ + if (len <= STRUCT_OFFSET(rpn_msg, rpn_val) - STRUCT_END(rpn_msg, mcc_s_head)) { + printf("\n"); + return; + } + + printf("br %d db %d sb %d p %d pt %d xi %d xo %d\n", + rpn->rpn_val.bit_rate, rpn->rpn_val.data_bits, + rpn->rpn_val.stop_bit, rpn->rpn_val.parity, + rpn->rpn_val.parity_type, rpn->rpn_val.xon_input, + rpn->rpn_val.xon_output); + + p_indent(level, 0); + printf("rtri %d rtro %d rtci %d rtco %d xon %d xoff %d pm 0x%04x\n", + rpn->rpn_val.rtr_input, rpn->rpn_val.rtr_output, + rpn->rpn_val.rtc_input, rpn->rpn_val.rtc_output, + rpn->rpn_val.xon, rpn->rpn_val.xoff, btohs(rpn->rpn_val.pm)); +} + +static inline void mcc_rls(int level, uint8_t *ptr, int len, + long_frame_head *head, mcc_long_frame_head *mcc_head) +{ + rls_msg* rls = (void*) (ptr - STRUCT_END(rls_msg, mcc_s_head)); + + printf("RLS %s: ", CR_STR(mcc_head)); + print_rfcomm_hdr(head, ptr, len); + print_mcc(mcc_head); + printf("dlci %d error: %d", GET_DLCI(rls->dlci), rls->error); +} + +static inline void mcc_pn(int level, uint8_t *ptr, int len, + long_frame_head *head, mcc_long_frame_head *mcc_head) +{ + pn_msg *pn = (void*) (ptr - STRUCT_END(pn_msg, mcc_s_head)); + + printf("PN %s: ", CR_STR(mcc_head)); + print_rfcomm_hdr(head, ptr, len); + print_mcc(mcc_head); + + p_indent(level, 0); + printf("dlci %d frame_type %d credit_flow %d pri %d ack_timer %d\n", + pn->dlci, pn->frame_type, pn->credit_flow, pn->prior, pn->ack_timer); + p_indent(level, 0); + printf("frame_size %d max_retrans %d credits %d\n", + btohs(pn->frame_size), pn->max_nbrof_retrans, pn->credits); +} + +static inline void mcc_nsc(int level, uint8_t *ptr, int len, + long_frame_head *head, mcc_long_frame_head *mcc_head) +{ + + nsc_msg *nsc = (void*) (ptr - STRUCT_END(nsc_msg, mcc_s_head)); + + printf("NSC %s: ", CR_STR(mcc_head)); + print_rfcomm_hdr(head, ptr, len); + print_mcc(mcc_head); + + p_indent(level, 0); + printf("cr %d, mcc_cmd_type %x\n", + nsc->command_type.cr, nsc->command_type.type ); +} + +static inline void mcc_frame(int level, struct frame *frm, long_frame_head *head) +{ + mcc_short_frame_head *mcc_short_head_p = frm->ptr; + mcc_long_frame_head mcc_head; + uint8_t hdr_size; + + if ( mcc_short_head_p->length.ea == EA ) { + mcc_head.type = mcc_short_head_p->type; + mcc_head.length.bits.len = mcc_short_head_p->length.len; + hdr_size = sizeof(mcc_short_frame_head); + } else { + mcc_head = *(mcc_long_frame_head *)frm->ptr; + mcc_head.length.val = btohs(mcc_head.length.val); + hdr_size = sizeof(mcc_long_frame_head); + } + + frm->ptr += hdr_size; + frm->len -= hdr_size; + + p_indent(level, frm); + printf("RFCOMM(s): "); + + switch (mcc_head.type.type) { + case TEST: + mcc_test(level, frm->ptr, frm->len, head, &mcc_head); + raw_dump(level, frm); + break; + case FCON: + mcc_fcon(level, frm->ptr, frm->len, head, &mcc_head); + break; + case FCOFF: + mcc_fcoff(level, frm->ptr, frm->len, head, &mcc_head); + break; + case MSC: + mcc_msc(level, frm->ptr, frm->len, head, &mcc_head); + break; + case RPN: + mcc_rpn(level, frm->ptr, frm->len, head, &mcc_head); + break; + case RLS: + mcc_rls(level, frm->ptr, frm->len, head, &mcc_head); + break; + case PN: + mcc_pn(level, frm->ptr, frm->len, head, &mcc_head); + break; + case NSC: + mcc_nsc(level, frm->ptr, frm->len, head, &mcc_head); + break; + default: + printf("MCC message type 0x%02x: ", mcc_head.type.type); + print_rfcomm_hdr(head, frm->ptr, frm->len); + printf("\n"); + + frm->len--; + raw_dump(level, frm); + } +} + +static inline void uih_frame(int level, struct frame *frm, long_frame_head *head) +{ + uint32_t proto; + + if (!head->addr.server_chn) { + mcc_frame(level, frm, head); + } else { + p_indent(level, frm); + printf("RFCOMM(d): UIH: "); + print_rfcomm_hdr(head, frm->ptr, frm->len); + if (GET_PF(head->control)) { + printf("credits %d\n", *(uint8_t *)(frm->ptr)); + frm->ptr++; + frm->len--; + } else + printf("\n"); + + frm->len--; + frm->dlci = GET_DLCI(head->addr); + frm->channel = head->addr.server_chn; + + proto = get_proto(frm->handle, RFCOMM_PSM, frm->channel); + + if (frm->len > 0) { + switch (proto) { + case SDP_UUID_OBEX: + if (!p_filter(FILT_OBEX)) + obex_dump(level + 1, frm); + else + raw_dump(level, frm); + break; + + case SDP_UUID_LAN_ACCESS_PPP: + case SDP_UUID_DIALUP_NETWORKING: + if (!p_filter(FILT_PPP)) + ppp_dump(level + 1, frm); + else + raw_dump(level, frm); + break; + + default: + if (p_filter(FILT_RFCOMM)) + break; + + raw_dump(level, frm); + break; + } + } + } +} + +void rfcomm_dump(int level, struct frame *frm) +{ + uint8_t hdr_size, ctr_type; + short_frame_head *short_head_p = (void *) frm->ptr; + long_frame_head head; + + if (short_head_p->length.ea == EA) { + head.addr = short_head_p->addr; + head.control = short_head_p->control; + head.length.bits.len = short_head_p->length.len; + hdr_size = sizeof(short_frame_head); + } else { + head = *(long_frame_head *) frm->ptr; + head.length.val = btohs(head.length.val); + hdr_size = sizeof(long_frame_head); + } + + frm->ptr += hdr_size; + frm->len -= hdr_size; + + ctr_type = CLR_PF(head.control); + + if (ctr_type == UIH) { + uih_frame(level, frm, &head); + } else { + p_indent(level, frm); + printf("RFCOMM(s): "); + + switch (ctr_type) { + case SABM: + printf("SABM: "); + break; + case UA: + printf("UA: "); + break; + case DM: + printf("DM: "); + break; + case DISC: + printf("DISC: "); + del_frame(frm->handle, GET_DLCI(head.addr)); + break; + default: + printf("ERR: "); + } + print_rfcomm_hdr(&head, frm->ptr, frm->len); + printf("\n"); + } +} diff --git a/hcidump/parser/rfcomm.h b/hcidump/parser/rfcomm.h new file mode 100644 index 000000000..482484287 --- /dev/null +++ b/hcidump/parser/rfcomm.h @@ -0,0 +1,494 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Wayne Lee + * Copyright (C) 2003-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 + * + */ + +#ifndef __RFCOMM_H +#define __RFCOMM_H + +#include + +#define RFCOMM_PSM 3 + +#define TRUE 1 +#define FALSE 0 + +#define RFCOMM_MAX_CONN 10 +#define BT_NBR_DATAPORTS RFCOMM_MAX_CONN + +#define GET_BIT(pos,bitfield) ((bitfield[(pos)/32]) & (1 << ((pos) % 32))) +#define SET_BIT(pos,bitfield) ((bitfield[(pos)/32]) |= (1 << ((pos) % 32))) +#define CLR_BIT(pos,bitfield) ((bitfield[(pos)/32]) &= ((1 << ((pos) % 32)) ^ (~0))) + +/* Sets the P/F-bit in the control field */ +#define SET_PF(ctr) ((ctr) | (1 << 4)) +/* Clears the P/F-bit in the control field */ +#define CLR_PF(ctr) ((ctr) & 0xef) +/* Returns the P/F-bit */ +#define GET_PF(ctr) (((ctr) >> 4) & 0x1) + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/* Endian-swapping macros for structs */ +#define swap_long_frame(x) ((x)->h.length.val = le16_to_cpu((x)->h.length.val)) +#define swap_mcc_long_frame(x) (swap_long_frame(x)) + +/* Used for UIH packets */ +#define SHORT_CRC_CHECK 2 +/* Used for all packet exepts for the UIH packets */ +#define LONG_CRC_CHECK 3 +/* Short header for short UIH packets */ +#define SHORT_HDR 2 +/* Long header for long UIH packets */ +#define LONG_HDR 3 + +/* FIXME: Should this one be defined here? */ +#define SHORT_PAYLOAD_SIZE 127 +/* Used for setting the EA field in different packets, really neccessary? */ +#define EA 1 +/* Yes the FCS size is only one byte */ +#define FCS_SIZE 1 + +#define RFCOMM_MAX_HDR_SIZE 5 + +#define MAX_CREDITS 30 +#define START_CREDITS 7 +#define MIN_CREDITS 6 + +#define DEF_RFCOMM_MTU 127 + +/* The values in the control field when sending ordinary rfcomm packets */ +#define SABM 0x2f /* set asynchronous balanced mode */ +#define UA 0x63 /* unnumbered acknolodgement */ +#define DM 0x0f /* disconnected mode */ +#define DISC 0x43 /* disconnect */ +#define UIH 0xef /* unnumbered information with header check (only) */ +#define UI 0x03 /* unnumbered information (with all data check) */ + +#define SABM_SIZE 4 +#define UA_SIZE 4 + +/* The values in the type field in a multiplexer command packet */ +#define PN (0x80 >> 2) /* parameter negotiation */ +#define PSC (0x40 >> 2) /* power saving control */ +#define CLD (0xc0 >> 2) /* close down */ +#define TEST (0x20 >> 2) /* test */ +#define FCON (0xa0 >> 2) /* flow control on */ +#define FCOFF (0x60 >> 2) /* flow control off */ +#define MSC (0xe0 >> 2) /* modem status command */ +#define NSC (0x10 >> 2) /* not supported command response */ +#define RPN (0x90 >> 2) /* remote port negotiation */ +#define RLS (0x50 >> 2) /* remote line status */ +#define SNC (0xd0 >> 2) /* service negotiation command */ + +/* Define of some V.24 signals modem control signals in RFCOMM */ +#define DV 0x80 /* data valid */ +#define IC 0x40 /* incoming call */ +#define RTR 0x08 /* ready to receive */ +#define RTC 0x04 /* ready to communicate */ +#define FC 0x02 /* flow control (unable to accept frames) */ + +#define CTRL_CHAN 0 /* The control channel is defined as DLCI 0 in rfcomm */ +#define MCC_CMD 1 /* Multiplexer command */ +#define MCC_RSP 0 /* Multiplexer response */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +typedef struct parameter_mask { + uint8_t bit_rate:1; + uint8_t data_bits:1; + uint8_t stop_bit:1; + uint8_t parity:1; + uint8_t parity_type:1; + uint8_t xon:1; + uint8_t xoff:1; + uint8_t res1:1; + uint8_t xon_input:1; + uint8_t xon_output:1; + uint8_t rtr_input:1; + uint8_t rtr_output:1; + uint8_t rtc_input:1; + uint8_t rtc_output:1; + uint8_t res2:2; +} __attribute__ ((packed)) parameter_mask; + +typedef struct rpn_values { + uint8_t bit_rate; + uint8_t data_bits:2; + uint8_t stop_bit:1; + uint8_t parity:1; + uint8_t parity_type:2; + uint8_t res1:2; + uint8_t xon_input:1; + uint8_t xon_output:1; + uint8_t rtr_input:1; + uint8_t rtr_output:1; + uint8_t rtc_input:1; + uint8_t rtc_output:1; + uint8_t res2:2; + uint8_t xon; + uint8_t xoff; + uint16_t pm; + //parameter_mask pm; +} __attribute__ ((packed)) rpn_values; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +typedef struct parameter_mask { + uint8_t res1:1; + uint8_t xoff:1; + uint8_t xon:1; + uint8_t parity_type:1; + uint8_t parity:1; + uint8_t stop_bit:1; + uint8_t data_bits:1; + uint8_t bit_rate:1; + uint8_t res2:2; + uint8_t rtc_output:1; + uint8_t rtc_input:1; + uint8_t rtr_output:1; + uint8_t rtr_input:1; + uint8_t xon_output:1; + uint8_t xon_input:1; + +} __attribute__ ((packed)) parameter_mask; + +typedef struct rpn_values { + uint8_t bit_rate; + uint8_t res1:2; + uint8_t parity_type:2; + uint8_t parity:1; + uint8_t stop_bit:1; + uint8_t data_bits:2; + uint8_t res2:2; + uint8_t rtc_output:1; + uint8_t rtc_input:1; + uint8_t rtr_output:1; + uint8_t rtr_input:1; + uint8_t xon_output:1; + uint8_t xon_input:1; + uint8_t xon; + uint8_t xoff; + uint16_t pm; + //parameter_mask pm; +} __attribute__ ((packed)) rpn_values; + +#else +#error "Unknown byte order" +#endif + +/* Typedefinitions of stuctures used for creating and parsing packets, for a + * further description of the structures please se the bluetooth core + * specification part F:1 and the ETSI TS 07.10 specification */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +typedef struct address_field { + uint8_t ea:1; + uint8_t cr:1; + uint8_t d:1; + uint8_t server_chn:5; +} __attribute__ ((packed)) address_field; + +typedef struct short_length { + uint8_t ea:1; + uint8_t len:7; +} __attribute__ ((packed)) short_length; + +typedef union long_length { + struct bits { + uint8_t ea:1; + unsigned short len:15; + } __attribute__ ((packed)) bits ; + uint16_t val ; +} __attribute__ ((packed)) long_length; + +typedef struct short_frame_head { + address_field addr; + uint8_t control; + short_length length; +} __attribute__ ((packed)) short_frame_head; + +typedef struct short_frame { + short_frame_head h; + uint8_t data[0]; +} __attribute__ ((packed)) short_frame; + +typedef struct long_frame_head { + address_field addr; + uint8_t control; + long_length length; + uint8_t data[0]; +} __attribute__ ((packed)) long_frame_head; + +typedef struct long_frame { + long_frame_head h; + uint8_t data[0]; +} __attribute__ ((packed)) long_frame; + +/* Typedefinitions for structures used for the multiplexer commands */ +typedef struct mcc_type { + uint8_t ea:1; + uint8_t cr:1; + uint8_t type:6; +} __attribute__ ((packed)) mcc_type; + +typedef struct mcc_short_frame_head { + mcc_type type; + short_length length; + uint8_t value[0]; +} __attribute__ ((packed)) mcc_short_frame_head; + +typedef struct mcc_short_frame { + mcc_short_frame_head h; + uint8_t value[0]; +} __attribute__ ((packed)) mcc_short_frame; + +typedef struct mcc_long_frame_head { + mcc_type type; + long_length length; + uint8_t value[0]; +} __attribute__ ((packed)) mcc_long_frame_head; + +typedef struct mcc_long_frame { + mcc_long_frame_head h; + uint8_t value[0]; +} __attribute__ ((packed)) mcc_long_frame; + +/* MSC-command */ +typedef struct v24_signals { + uint8_t ea:1; + uint8_t fc:1; + uint8_t rtc:1; + uint8_t rtr:1; + uint8_t reserved:2; + uint8_t ic:1; + uint8_t dv:1; +} __attribute__ ((packed)) v24_signals; + +typedef struct break_signals { + uint8_t ea:1; + uint8_t b1:1; + uint8_t b2:1; + uint8_t b3:1; + uint8_t len:4; +} __attribute__ ((packed)) break_signals; + +typedef struct msc_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + v24_signals v24_sigs; + //break_signals break_sigs; + uint8_t fcs; +} __attribute__ ((packed)) msc_msg; + +typedef struct rpn_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + rpn_values rpn_val; + uint8_t fcs; +} __attribute__ ((packed)) rpn_msg; + +/* RLS-command */ +typedef struct rls_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + uint8_t error:4; + uint8_t res:4; + uint8_t fcs; +} __attribute__ ((packed)) rls_msg; + +/* PN-command */ +typedef struct pn_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; +/* The res1, res2 and res3 values have to be set to 0 by the sender */ + uint8_t dlci:6; + uint8_t res1:2; + uint8_t frame_type:4; + uint8_t credit_flow:4; + uint8_t prior:6; + uint8_t res2:2; + uint8_t ack_timer; + uint16_t frame_size:16; + uint8_t max_nbrof_retrans; + uint8_t credits; + uint8_t fcs; +} __attribute__ ((packed)) pn_msg; + +/* NSC-command */ +typedef struct nsc_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + mcc_type command_type; + uint8_t fcs; +} __attribute__ ((packed)) nsc_msg; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +typedef struct address_field { + uint8_t server_chn:5; + uint8_t d:1; + uint8_t cr:1; + uint8_t ea:1; +} __attribute__ ((packed)) address_field; + +typedef struct short_length { + uint8_t len:7; + uint8_t ea:1; +} __attribute__ ((packed)) short_length; + +typedef union long_length { + struct bits { + unsigned short len:15; + uint8_t ea:1; + } __attribute__ ((packed)) bits; + uint16_t val; +} __attribute__ ((packed)) long_length; + +typedef struct short_frame_head { + address_field addr; + uint8_t control; + short_length length; +} __attribute__ ((packed)) short_frame_head; + +typedef struct short_frame { + short_frame_head h; + uint8_t data[0]; +} __attribute__ ((packed)) short_frame; + +typedef struct long_frame_head { + address_field addr; + uint8_t control; + long_length length; + uint8_t data[0]; +} __attribute__ ((packed)) long_frame_head; + +typedef struct long_frame { + long_frame_head h; + uint8_t data[0]; +} __attribute__ ((packed)) long_frame; + +typedef struct mcc_type { + uint8_t type:6; + uint8_t cr:1; + uint8_t ea:1; +} __attribute__ ((packed)) mcc_type; + +typedef struct mcc_short_frame_head { + mcc_type type; + short_length length; + uint8_t value[0]; +} __attribute__ ((packed)) mcc_short_frame_head; + +typedef struct mcc_short_frame { + mcc_short_frame_head h; + uint8_t value[0]; +} __attribute__ ((packed)) mcc_short_frame; + +typedef struct mcc_long_frame_head { + mcc_type type; + long_length length; + uint8_t value[0]; +} __attribute__ ((packed)) mcc_long_frame_head; + +typedef struct mcc_long_frame { + mcc_long_frame_head h; + uint8_t value[0]; +} __attribute__ ((packed)) mcc_long_frame; + +typedef struct v24_signals { + uint8_t dv:1; + uint8_t ic:1; + uint8_t reserved:2; + uint8_t rtr:1; + uint8_t rtc:1; + uint8_t fc:1; + uint8_t ea:1; +} __attribute__ ((packed)) v24_signals; + +typedef struct break_signals { + uint8_t len:4; + uint8_t b3:1; + uint8_t b2:1; + uint8_t b1:1; + uint8_t ea:1; +} __attribute__ ((packed)) break_signals; + +typedef struct msc_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + v24_signals v24_sigs; + //break_signals break_sigs; + uint8_t fcs; +} __attribute__ ((packed)) msc_msg; + +typedef struct rpn_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + rpn_values rpn_val; + uint8_t fcs; +} __attribute__ ((packed)) rpn_msg; + +typedef struct rls_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + address_field dlci; + uint8_t res:4; + uint8_t error:4; + uint8_t fcs; +} __attribute__ ((packed)) rls_msg; + +typedef struct pn_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + uint8_t res1:2; + uint8_t dlci:6; + uint8_t credit_flow:4; + uint8_t frame_type:4; + uint8_t res2:2; + uint8_t prior:6; + uint8_t ack_timer; + uint16_t frame_size:16; + uint8_t max_nbrof_retrans; + uint8_t credits; + uint8_t fcs; +} __attribute__ ((packed)) pn_msg; + +typedef struct nsc_msg { + short_frame_head s_head; + mcc_short_frame_head mcc_s_head; + mcc_type command_type; + uint8_t fcs; +} __attribute__ ((packed)) nsc_msg; + +#else +#error "Unknown byte order" +#error Processor endianness unknown! +#endif + +#endif /* __RFCOMM_H */ diff --git a/hcidump/parser/sdp.c b/hcidump/parser/sdp.c new file mode 100644 index 000000000..f0ffea334 --- /dev/null +++ b/hcidump/parser/sdp.c @@ -0,0 +1,808 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Ricky Yuen + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "parser.h" +#include "sdp.h" + +#define SDP_ERROR_RSP 0x01 +#define SDP_SERVICE_SEARCH_REQ 0x02 +#define SDP_SERVICE_SEARCH_RSP 0x03 +#define SDP_SERVICE_ATTR_REQ 0x04 +#define SDP_SERVICE_ATTR_RSP 0x05 +#define SDP_SERVICE_SEARCH_ATTR_REQ 0x06 +#define SDP_SERVICE_SEARCH_ATTR_RSP 0x07 + +typedef struct { + uint8_t pid; + uint16_t tid; + uint16_t len; +} __attribute__ ((packed)) sdp_pdu_hdr; +#define SDP_PDU_HDR_SIZE 5 + +/* Data element type descriptor */ +#define SDP_DE_NULL 0 +#define SDP_DE_UINT 1 +#define SDP_DE_INT 2 +#define SDP_DE_UUID 3 +#define SDP_DE_STRING 4 +#define SDP_DE_BOOL 5 +#define SDP_DE_SEQ 6 +#define SDP_DE_ALT 7 +#define SDP_DE_URL 8 + +/* Data element size index lookup table */ +typedef struct { + int addl_bits; + int num_bytes; +} sdp_siz_idx_lookup_table_t; + +static sdp_siz_idx_lookup_table_t sdp_siz_idx_lookup_table[] = { + { 0, 1 }, /* Size index = 0 */ + { 0, 2 }, /* 1 */ + { 0, 4 }, /* 2 */ + { 0, 8 }, /* 3 */ + { 0, 16 }, /* 4 */ + { 1, 1 }, /* 5 */ + { 1, 2 }, /* 6 */ + { 1, 4 }, /* 7 */ +}; + +/* UUID name lookup table */ +typedef struct { + int uuid; + char* name; +} sdp_uuid_nam_lookup_table_t; + +static sdp_uuid_nam_lookup_table_t sdp_uuid_nam_lookup_table[] = { + { SDP_UUID_SDP, "SDP" }, + { SDP_UUID_UDP, "UDP" }, + { SDP_UUID_RFCOMM, "RFCOMM" }, + { SDP_UUID_TCP, "TCP" }, + { SDP_UUID_TCS_BIN, "TCS-BIN" }, + { SDP_UUID_TCS_AT, "TCS-AT" }, + { SDP_UUID_OBEX, "OBEX" }, + { SDP_UUID_IP, "IP" }, + { SDP_UUID_FTP, "FTP" }, + { SDP_UUID_HTTP, "HTTP" }, + { SDP_UUID_WSP, "WSP" }, + { SDP_UUID_L2CAP, "L2CAP" }, + { SDP_UUID_BNEP, "BNEP" }, /* PAN */ + { SDP_UUID_HIDP, "HIDP" }, /* HID */ + { SDP_UUID_AVCTP, "AVCTP" }, /* AVCTP */ + { SDP_UUID_AVDTP, "AVDTP" }, /* AVDTP */ + { SDP_UUID_CMTP, "CMTP" }, /* CIP */ + { SDP_UUID_UDI_C_PLANE, "UDI_C-Plane" }, /* UDI */ + { SDP_UUID_SERVICE_DISCOVERY_SERVER, "SDServer" }, + { SDP_UUID_BROWSE_GROUP_DESCRIPTOR, "BrwsGrpDesc" }, + { SDP_UUID_PUBLIC_BROWSE_GROUP, "PubBrwsGrp" }, + { SDP_UUID_SERIAL_PORT, "SP" }, + { SDP_UUID_LAN_ACCESS_PPP, "LAN" }, + { SDP_UUID_DIALUP_NETWORKING, "DUN" }, + { SDP_UUID_IR_MC_SYNC, "IRMCSync" }, + { SDP_UUID_OBEX_OBJECT_PUSH, "OBEXObjPush" }, + { SDP_UUID_OBEX_FILE_TRANSFER, "OBEXObjTrnsf" }, + { SDP_UUID_IR_MC_SYNC_COMMAND, "IRMCSyncCmd" }, + { SDP_UUID_HEADSET, "Headset" }, + { SDP_UUID_CORDLESS_TELEPHONY, "CordlessTel" }, + { SDP_UUID_AUDIO_SOURCE, "AudioSource" }, /* A2DP */ + { SDP_UUID_AUDIO_SINK, "AudioSink" }, /* A2DP */ + { SDP_UUID_AV_REMOTE_TARGET, "AVRemTarget" }, /* AVRCP */ + { SDP_UUID_ADVANCED_AUDIO, "AdvAudio" }, /* A2DP */ + { SDP_UUID_AV_REMOTE, "AVRemote" }, /* AVRCP */ + { SDP_UUID_VIDEO_CONFERENCING, "VideoConf" }, /* VCP */ + { SDP_UUID_INTERCOM, "Intercom" }, + { SDP_UUID_FAX, "Fax" }, + { SDP_UUID_HEADSET_AUDIO_GATEWAY, "Headset AG" }, + { SDP_UUID_WAP, "WAP" }, + { SDP_UUID_WAP_CLIENT, "WAP Client" }, + { SDP_UUID_PANU, "PANU" }, /* PAN */ + { SDP_UUID_NAP, "NAP" }, /* PAN */ + { SDP_UUID_GN, "GN" }, /* PAN */ + { SDP_UUID_DIRECT_PRINTING, "DirectPrint" }, /* BPP */ + { SDP_UUID_REFERENCE_PRINTING, "RefPrint" }, /* BPP */ + { SDP_UUID_IMAGING, "Imaging" }, /* BIP */ + { SDP_UUID_IMAGING_RESPONDER, "ImagingResp" }, /* BIP */ + { SDP_UUID_HANDSFREE, "Handsfree" }, + { SDP_UUID_HANDSFREE_AUDIO_GATEWAY, "Handsfree AG" }, + { SDP_UUID_DIRECT_PRINTING_REF_OBJS, "RefObjsPrint" }, /* BPP */ + { SDP_UUID_REFLECTED_UI, "ReflectedUI" }, /* BPP */ + { SDP_UUID_BASIC_PRINTING, "BasicPrint" }, /* BPP */ + { SDP_UUID_PRINTING_STATUS, "PrintStatus" }, /* BPP */ + { SDP_UUID_HUMAN_INTERFACE_DEVICE, "HID" }, /* HID */ + { SDP_UUID_HARDCOPY_CABLE_REPLACE, "HCRP" }, /* HCRP */ + { SDP_UUID_HCR_PRINT, "HCRPrint" }, /* HCRP */ + { SDP_UUID_HCR_SCAN, "HCRScan" }, /* HCRP */ + { SDP_UUID_COMMON_ISDN_ACCESS, "CIP" }, /* CIP */ + { SDP_UUID_VIDEO_CONFERENCING_GW, "VideoConf GW" }, /* VCP */ + { SDP_UUID_UDI_MT, "UDI MT" }, /* UDI */ + { SDP_UUID_UDI_TA, "UDI TA" }, /* UDI */ + { SDP_UUID_AUDIO_VIDEO, "AudioVideo" }, /* VCP */ + { SDP_UUID_SIM_ACCESS, "SAP" }, /* SAP */ + { SDP_UUID_PHONEBOOK_ACCESS_PCE, "PBAP PCE" }, /* PBAP */ + { SDP_UUID_PHONEBOOK_ACCESS_PSE, "PBAP PSE" }, /* PBAP */ + { SDP_UUID_PHONEBOOK_ACCESS, "PBAP" }, /* PBAP */ + { SDP_UUID_PNP_INFORMATION, "PNPInfo" }, + { SDP_UUID_GENERIC_NETWORKING, "Networking" }, + { SDP_UUID_GENERIC_FILE_TRANSFER, "FileTrnsf" }, + { SDP_UUID_GENERIC_AUDIO, "Audio" }, + { SDP_UUID_GENERIC_TELEPHONY, "Telephony" }, + { SDP_UUID_UPNP_SERVICE, "UPNP" }, /* ESDP */ + { SDP_UUID_UPNP_IP_SERVICE, "UPNP IP" }, /* ESDP */ + { SDP_UUID_ESDP_UPNP_IP_PAN, "UPNP PAN" }, /* ESDP */ + { SDP_UUID_ESDP_UPNP_IP_LAP, "UPNP LAP" }, /* ESDP */ + { SDP_UUID_ESDP_UPNP_L2CAP, "UPNP L2CAP" }, /* ESDP */ + { SDP_UUID_VIDEO_SOURCE, "VideoSource" }, /* VDP */ + { SDP_UUID_VIDEO_SINK, "VideoSink" }, /* VDP */ + { SDP_UUID_VIDEO_DISTRIBUTION, "VideoDist" }, /* VDP */ + { SDP_UUID_APPLE_AGENT, "AppleAgent" }, +}; + +#define SDP_UUID_NAM_LOOKUP_TABLE_SIZE \ + (sizeof(sdp_uuid_nam_lookup_table)/sizeof(sdp_uuid_nam_lookup_table_t)) + +/* AttrID name lookup table */ +typedef struct { + int attr_id; + char* name; +} sdp_attr_id_nam_lookup_table_t; + +static sdp_attr_id_nam_lookup_table_t sdp_attr_id_nam_lookup_table[] = { + { SDP_ATTR_ID_SERVICE_RECORD_HANDLE, "SrvRecHndl" }, + { SDP_ATTR_ID_SERVICE_CLASS_ID_LIST, "SrvClassIDList" }, + { SDP_ATTR_ID_SERVICE_RECORD_STATE, "SrvRecState" }, + { SDP_ATTR_ID_SERVICE_SERVICE_ID, "SrvID" }, + { SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST, "ProtocolDescList" }, + { SDP_ATTR_ID_BROWSE_GROUP_LIST, "BrwGrpList" }, + { SDP_ATTR_ID_LANGUAGE_BASE_ATTRIBUTE_ID_LIST, "LangBaseAttrIDList" }, + { SDP_ATTR_ID_SERVICE_INFO_TIME_TO_LIVE, "SrvInfoTimeToLive" }, + { SDP_ATTR_ID_SERVICE_AVAILABILITY, "SrvAvail" }, + { SDP_ATTR_ID_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, "BTProfileDescList" }, + { SDP_ATTR_ID_DOCUMENTATION_URL, "DocURL" }, + { SDP_ATTR_ID_CLIENT_EXECUTABLE_URL, "ClientExeURL" }, + { SDP_ATTR_ID_ICON_10, "Icon10" }, + { SDP_ATTR_ID_ICON_URL, "IconURL" }, + { SDP_ATTR_ID_SERVICE_NAME, "SrvName" }, + { SDP_ATTR_ID_SERVICE_DESCRIPTION, "SrvDesc" }, + { SDP_ATTR_ID_PROVIDER_NAME, "ProviderName" }, + { SDP_ATTR_ID_VERSION_NUMBER_LIST, "VersionNumList" }, + { SDP_ATTR_ID_GROUP_ID, "GrpID" }, + { SDP_ATTR_ID_SERVICE_DATABASE_STATE, "SrvDBState" }, + { SDP_ATTR_ID_SERVICE_VERSION, "SrvVersion" }, + { SDP_ATTR_ID_SECURITY_DESCRIPTION, "SecurityDescription"}, /* PAN */ + { SDP_ATTR_ID_SUPPORTED_DATA_STORES_LIST, "SuppDataStoresList" }, /* Synchronization */ + { SDP_ATTR_ID_SUPPORTED_FORMATS_LIST, "SuppFormatsList" }, /* OBEX Object Push */ + { SDP_ATTR_ID_NET_ACCESS_TYPE, "NetAccessType" }, /* PAN */ + { SDP_ATTR_ID_MAX_NET_ACCESS_RATE, "MaxNetAccessRate" }, /* PAN */ + { SDP_ATTR_ID_IPV4_SUBNET, "IPv4Subnet" }, /* PAN */ + { SDP_ATTR_ID_IPV6_SUBNET, "IPv6Subnet" }, /* PAN */ + { SDP_ATTR_ID_SUPPORTED_CAPABILITIES, "SuppCapabilities" }, /* Imaging */ + { SDP_ATTR_ID_SUPPORTED_FEATURES, "SuppFeatures" }, /* Imaging and Hansfree */ + { SDP_ATTR_ID_SUPPORTED_FUNCTIONS, "SuppFunctions" }, /* Imaging */ + { SDP_ATTR_ID_TOTAL_IMAGING_DATA_CAPACITY, "SuppTotalCapacity" }, /* Imaging */ + { SDP_ATTR_ID_SUPPORTED_REPOSITORIES, "SuppRepositories" }, /* PBAP */ +}; + +#define SDP_ATTR_ID_NAM_LOOKUP_TABLE_SIZE \ + (sizeof(sdp_attr_id_nam_lookup_table)/sizeof(sdp_attr_id_nam_lookup_table_t)) + +char* get_uuid_name(int uuid) +{ + int i; + + for (i = 0; i < SDP_UUID_NAM_LOOKUP_TABLE_SIZE; i++) { + if (sdp_uuid_nam_lookup_table[i].uuid == uuid) + return sdp_uuid_nam_lookup_table[i].name; + } + + return 0; +} + +static inline char* get_attr_id_name(int attr_id) +{ + int i; + + for (i = 0; i < SDP_ATTR_ID_NAM_LOOKUP_TABLE_SIZE; i++) + if (sdp_attr_id_nam_lookup_table[i].attr_id == attr_id) + return sdp_attr_id_nam_lookup_table[i].name; + return 0; +} + +static inline uint8_t parse_de_hdr(struct frame *frm, int *n) +{ + uint8_t de_hdr = get_u8(frm); + uint8_t de_type = de_hdr >> 3; + uint8_t siz_idx = de_hdr & 0x07; + + /* Get the number of bytes */ + if (sdp_siz_idx_lookup_table[siz_idx].addl_bits) { + switch(sdp_siz_idx_lookup_table[siz_idx].num_bytes) { + case 1: + *n = get_u8(frm); break; + case 2: + *n = get_u16(frm); break; + case 4: + *n = get_u32(frm); break; + case 8: + *n = get_u64(frm); break; + } + } else + *n = sdp_siz_idx_lookup_table[siz_idx].num_bytes; + + return de_type; +} + +static inline void print_int(uint8_t de_type, int level, int n, struct frame *frm, uint16_t *psm, uint8_t *channel) +{ + uint64_t val, val2; + + switch(de_type) { + case SDP_DE_UINT: + printf(" uint"); + break; + case SDP_DE_INT: + printf(" int"); + break; + case SDP_DE_BOOL: + printf(" bool"); + break; + } + + switch(n) { + case 1: /* 8-bit */ + val = get_u8(frm); + if (channel && de_type == SDP_DE_UINT) + if (*channel == 0) + *channel = val; + break; + case 2: /* 16-bit */ + val = get_u16(frm); + if (psm && de_type == SDP_DE_UINT) + if (*psm == 0) + *psm = val; + break; + case 4: /* 32-bit */ + val = get_u32(frm); + break; + case 8: /* 64-bit */ + val = get_u64(frm); + break; + case 16:/* 128-bit */ + get_u128(frm, &val, &val2); + printf(" 0x%jx", val2); + if (val < 0x1000000000000000LL) + printf("0"); + printf("%jx", val); + return; + default: /* syntax error */ + printf(" err"); + frm->ptr += n; + frm->len -= n; + return; + } + + printf(" 0x%jx", val); +} + +static inline void print_uuid(int n, struct frame *frm, uint16_t *psm, uint8_t *channel) +{ + uint32_t uuid = 0; + char* s; + int i; + + switch(n) { + case 2: /* 16-bit UUID */ + uuid = get_u16(frm); + s = "uuid-16"; + break; + case 4: /* 32_bit UUID */ + uuid = get_u32(frm); + s = "uuid-32"; + break; + case 16: /* 128-bit UUID */ + printf(" uuid-128 "); + for (i = 0; i < 16; i++) { + printf("%02x", ((unsigned char *) frm->ptr)[i]); + if (i == 3 || i == 5 || i == 7 || i == 9) + printf("-"); + } + frm->ptr += 16; + frm->len -= 16; + return; + default: /* syntax error */ + printf(" *err*"); + frm->ptr += n; + frm->len -= n; + return; + } + + if (psm && *psm > 0 && *psm != 0xffff) { + set_proto(frm->handle, *psm, 0, uuid); + *psm = 0xffff; + } + + if (channel && *channel > 0 && *channel != 0xff) { + set_proto(frm->handle, *psm, *channel, uuid); + *channel = 0xff; + } + + printf(" %s 0x%04x", s, uuid); + if ((s = get_uuid_name(uuid))) + printf(" (%s)", s); +} + +static inline void print_string(int n, struct frame *frm, const char *name) +{ + int i, hex = 0; + + for (i = 0; i < n; i++) { + if (i == (n - 1) && ((char *) frm->ptr)[i] == '\0') + break; + + if (!isprint(((char *) frm->ptr)[i])) { + hex = 1; + break; + } + } + + printf(" %s", name); + if (hex) { + for (i = 0; i < n; i++) + printf(" %02x", ((unsigned char *) frm->ptr)[i]); + } else { + printf(" \""); + for (i = 0; i < n; i++) + printf("%c", ((char *) frm->ptr)[i]); + printf("\""); + } + + frm->ptr += n; + frm->len -= n; +} + +static inline void print_de(int, struct frame *frm, int *split, uint16_t *psm, uint8_t *channel); + +static inline void print_des(uint8_t de_type, int level, int n, struct frame *frm, int *split, uint16_t *psm, uint8_t *channel) +{ + int len = frm->len; + while (len - frm->len < n && frm->len > 0) + print_de(level, frm, split, psm, channel); +} + +static inline void print_de(int level, struct frame *frm, int *split, uint16_t *psm, uint8_t *channel) +{ + int n = 0; + uint8_t de_type = parse_de_hdr(frm, &n); + + switch (de_type) { + case SDP_DE_NULL: + printf(" null"); + break; + case SDP_DE_UINT: + case SDP_DE_INT: + case SDP_DE_BOOL: + print_int(de_type, level, n, frm, psm, channel); + break; + case SDP_DE_UUID: + if (split) { + /* Split output by uuids. + * Used for printing Protocol Desc List */ + if (*split) { + printf("\n"); + p_indent(level, NULL); + } + ++*split; + } + print_uuid(n, frm, psm, channel); + break; + case SDP_DE_URL: + case SDP_DE_STRING: + print_string(n, frm, de_type == SDP_DE_URL? "url": "str"); + break; + case SDP_DE_SEQ: + printf(" <"); + print_des(de_type, level, n, frm, split, psm, channel); + printf(" >"); + break; + case SDP_DE_ALT: + printf(" ["); + print_des(de_type, level, n, frm, split, psm, channel); + printf(" ]"); + break; + } +} + +static inline void print_srv_srch_pat(int level, struct frame *frm) +{ + int len, n1 = 0, n2 = 0; + + p_indent(level, frm); + printf("pat"); + + if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) { + len = frm->len; + while (len - frm->len < n1 && frm->len > 0) { + if (parse_de_hdr(frm, &n2) == SDP_DE_UUID) { + print_uuid(n2, frm, NULL, NULL); + } else { + printf("\nERROR: Unexpected syntax (UUID)\n"); + raw_dump(level, frm); + } + } + printf("\n"); + } else { + printf("\nERROR: Unexpected syntax (SEQ)\n"); + raw_dump(level, frm); + } +} + +static inline void print_attr_id_list(int level, struct frame *frm) +{ + uint16_t attr_id; + uint32_t attr_id_range; + int len, n1 = 0, n2 = 0; + + p_indent(level, frm); + printf("aid(s)"); + + if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) { + len = frm->len; + while (len - frm->len < n1 && frm->len > 0) { + /* Print AttributeID */ + if (parse_de_hdr(frm, &n2) == SDP_DE_UINT) { + char *name; + switch(n2) { + case 2: + attr_id = get_u16(frm); + name = get_attr_id_name(attr_id); + if (!name) + name = "unknown"; + printf(" 0x%04x (%s)", attr_id, name); + break; + case 4: + attr_id_range = get_u32(frm); + printf(" 0x%04x - 0x%04x", + (attr_id_range >> 16), + (attr_id_range & 0xFFFF)); + break; + } + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } + } + printf("\n"); + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } +} + +static inline void print_attr_list(int level, struct frame *frm) +{ + uint16_t attr_id, psm; + uint8_t channel; + int len, split, n1 = 0, n2 = 0; + + if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) { + len = frm->len; + while (len - frm->len < n1 && frm->len > 0) { + /* Print AttributeID */ + if (parse_de_hdr(frm, &n2) == SDP_DE_UINT && n2 == sizeof(attr_id)) { + char *name; + attr_id = get_u16(frm); + p_indent(level, 0); + name = get_attr_id_name(attr_id); + if (!name) + name = "unknown"; + printf("aid 0x%04x (%s)\n", attr_id, name); + split = (attr_id != SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST); + psm = 0; + channel = 0; + + /* Print AttributeValue */ + p_indent(level + 1, 0); + print_de(level + 1, frm, split ? NULL: &split, + attr_id == SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST ? &psm : NULL, + attr_id == SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST ? &channel : NULL); + printf("\n"); + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + break; + } + } + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } +} + +static inline void print_attr_lists(int level, struct frame *frm) +{ + int n = 0, cnt = 0; + int count = frm->len; + + if (parse_de_hdr(frm, &n) == SDP_DE_SEQ) { + while (count - frm->len < n && frm->len > 0) { + p_indent(level, 0); + printf("record #%d\n", cnt++); + print_attr_list(level + 2, frm); + } + } else { + printf("\nERROR: Unexpected syntax\n"); + raw_dump(level, frm); + } +} + +static inline void print_cont_state(int level, unsigned char *buf) +{ + uint8_t cont = buf[0]; + int i; + + p_indent(level, 0); + printf("cont"); + for (i = 0; i < cont + 1; i++) + printf(" %2.2X", buf[i]); + printf("\n"); +} + +static char *pid2str(uint8_t pid) +{ + switch (pid) { + case SDP_ERROR_RSP: + return "Error Rsp"; + case SDP_SERVICE_SEARCH_REQ: + return "SS Req"; + case SDP_SERVICE_SEARCH_RSP: + return "SS Rsp"; + case SDP_SERVICE_ATTR_REQ: + return "SA Req"; + case SDP_SERVICE_ATTR_RSP: + return "SA Rsp"; + case SDP_SERVICE_SEARCH_ATTR_REQ: + return "SSA Req"; + case SDP_SERVICE_SEARCH_ATTR_RSP: + return "SSA Rsp"; + default: + return "Unknown"; + } +} + +#define FRAME_TABLE_SIZE 10 + +static struct frame frame_table[FRAME_TABLE_SIZE]; + +static int frame_add(struct frame *frm, int count) +{ + register struct frame *fr; + register unsigned char *data; + register int i, len = 0, pos = -1; + + for (i = 0; i < FRAME_TABLE_SIZE; i++) { + if (frame_table[i].handle == frm->handle && + frame_table[i].cid == frm->cid) { + pos = i; + len = frame_table[i].data_len; + break; + } + if (pos < 0 && !frame_table[i].handle) + pos = i; + } + + if (pos < 0 || count <= 0) + return -EIO; + + data = malloc(len + count); + if (!data) + return -ENOMEM; + + fr = &frame_table[pos]; + + if (len > 0) { + memcpy(data, fr->data, len); + memcpy(data + len, frm->ptr, count); + } else + memcpy(data, frm->ptr, count); + + if (fr->data) + free(fr->data); + + fr->data = data; + fr->data_len = len + count; + fr->len = fr->data_len; + fr->ptr = fr->data; + fr->dev_id = frm->dev_id; + fr->in = frm->in; + fr->ts = frm->ts; + fr->handle = frm->handle; + fr->cid = frm->cid; + fr->num = frm->num; + fr->channel = frm->channel; + fr->pppdump_fd = frm->pppdump_fd; + fr->audio_fd = frm->audio_fd; + + return pos; +} + +static struct frame *frame_get(struct frame *frm, int count) +{ + register int pos; + + pos = frame_add(frm, count); + if (pos < 0) + return frm; + + frame_table[pos].handle = 0; + + return &frame_table[pos]; +} + +void sdp_dump(int level, struct frame *frm) +{ + sdp_pdu_hdr *hdr = frm->ptr; + uint16_t tid = ntohs(hdr->tid); + uint16_t len = ntohs(hdr->len); + uint16_t total, count; + uint8_t cont; + + frm->ptr += SDP_PDU_HDR_SIZE; + frm->len -= SDP_PDU_HDR_SIZE; + + p_indent(level, frm); + printf("SDP %s: tid 0x%x len 0x%x\n", pid2str(hdr->pid), tid, len); + + switch (hdr->pid) { + case SDP_ERROR_RSP: + p_indent(level + 1, frm); + printf("code 0x%x info ", get_u16(frm)); + if (frm->len > 0) + hex_dump(0, frm, frm->len); + else + printf("none\n"); + break; + + case SDP_SERVICE_SEARCH_REQ: + /* Parse ServiceSearchPattern */ + print_srv_srch_pat(level + 1, frm); + + /* Parse MaximumServiceRecordCount */ + p_indent(level + 1, frm); + printf("max %d\n", get_u16(frm)); + + /* Parse ContinuationState */ + print_cont_state(level + 1, frm->ptr); + break; + + case SDP_SERVICE_SEARCH_RSP: + /* Parse TotalServiceRecordCount */ + total = get_u16(frm); + + /* Parse CurrentServiceRecordCount */ + count = get_u16(frm); + p_indent(level + 1, frm); + if (count < total) + printf("count %d of %d\n", count, total); + else + printf("count %d\n", count); + + /* Parse service record handle(s) */ + if (count > 0) { + int i; + p_indent(level + 1, frm); + printf("handle%s", count > 1 ? "s" : ""); + for (i = 0; i < count; i++) + printf(" 0x%x", get_u32(frm)); + printf("\n"); + } + + /* Parse ContinuationState */ + print_cont_state(level + 1, frm->ptr); + break; + + case SDP_SERVICE_ATTR_REQ: + /* Parse ServiceRecordHandle */ + p_indent(level + 1, frm); + printf("handle 0x%x\n", get_u32(frm)); + + /* Parse MaximumAttributeByteCount */ + p_indent(level + 1, frm); + printf("max %d\n", get_u16(frm)); + + /* Parse ServiceSearchPattern */ + print_attr_id_list(level + 1, frm); + + /* Parse ContinuationState */ + print_cont_state(level + 1, frm->ptr); + break; + + case SDP_SERVICE_ATTR_RSP: + /* Parse AttributeByteCount */ + count = get_u16(frm); + p_indent(level + 1, frm); + printf("count %d\n", count); + + /* Parse ContinuationState */ + cont = *(unsigned char *)(frm->ptr + count); + + if (cont == 0) { + /* Parse AttributeList */ + print_attr_list(level + 1, frame_get(frm, count)); + } else + frame_add(frm, count); + + print_cont_state(level + 1, frm->ptr + count); + break; + + case SDP_SERVICE_SEARCH_ATTR_REQ: + /* Parse ServiceSearchPattern */ + print_srv_srch_pat(level + 1, frm); + + /* Parse MaximumAttributeByteCount */ + p_indent(level + 1, frm); + printf("max %d\n", get_u16(frm)); + + /* Parse AttributeList */ + print_attr_id_list(level + 1, frm); + + /* Parse ContinuationState */ + print_cont_state(level + 1, frm->ptr); + break; + + case SDP_SERVICE_SEARCH_ATTR_RSP: + /* Parse AttributeByteCount */ + count = get_u16(frm); + p_indent(level + 1, frm); + printf("count %d\n", count); + + /* Parse ContinuationState */ + cont = *(unsigned char *)(frm->ptr + count); + + if (cont == 0) { + /* Parse AttributeLists */ + print_attr_lists(level + 1, frame_get(frm, count)); + } else + frame_add(frm, count); + + print_cont_state(level + 1, frm->ptr + count); + break; + + default: + raw_dump(level + 1, frm); + break; + } +} diff --git a/hcidump/parser/sdp.h b/hcidump/parser/sdp.h new file mode 100644 index 000000000..914bdb60b --- /dev/null +++ b/hcidump/parser/sdp.h @@ -0,0 +1,162 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Ricky Yuen + * Copyright (C) 2003-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 + * + */ + +#ifndef __SDP_H +#define __SDP_H + +/* Bluetooth assigned UUIDs for protocols */ +#define SDP_UUID_SDP 0x0001 +#define SDP_UUID_UDP 0x0002 +#define SDP_UUID_RFCOMM 0x0003 +#define SDP_UUID_TCP 0x0004 +#define SDP_UUID_TCS_BIN 0x0005 +#define SDP_UUID_TCS_AT 0x0006 +#define SDP_UUID_OBEX 0x0008 +#define SDP_UUID_IP 0x0009 +#define SDP_UUID_FTP 0x000A +#define SDP_UUID_HTTP 0x000C +#define SDP_UUID_WSP 0x000E +#define SDP_UUID_BNEP 0x000F /* PAN */ +#define SDP_UUID_HIDP 0x0011 /* HID */ +#define SDP_UUID_HARDCOPY_CONTROL_CHANNEL 0x0012 /* HCRP */ +#define SDP_UUID_HARDCOPY_DATA_CHANNEL 0x0014 /* HCRP */ +#define SDP_UUID_HARDCOPY_NOTIFICATION 0x0016 /* HCRP */ +#define SDP_UUID_AVCTP 0x0017 /* AVCTP */ +#define SDP_UUID_AVDTP 0x0019 /* AVDTP */ +#define SDP_UUID_CMTP 0x001B /* CIP */ +#define SDP_UUID_UDI_C_PLANE 0x001D /* UDI */ +#define SDP_UUID_L2CAP 0x0100 + +/* Bluetooth assigned UUIDs for Service Classes */ +#define SDP_UUID_SERVICE_DISCOVERY_SERVER 0x1000 +#define SDP_UUID_BROWSE_GROUP_DESCRIPTOR 0x1001 +#define SDP_UUID_PUBLIC_BROWSE_GROUP 0x1002 +#define SDP_UUID_SERIAL_PORT 0x1101 +#define SDP_UUID_LAN_ACCESS_PPP 0x1102 +#define SDP_UUID_DIALUP_NETWORKING 0x1103 +#define SDP_UUID_IR_MC_SYNC 0x1104 +#define SDP_UUID_OBEX_OBJECT_PUSH 0x1105 +#define SDP_UUID_OBEX_FILE_TRANSFER 0x1106 +#define SDP_UUID_IR_MC_SYNC_COMMAND 0x1107 +#define SDP_UUID_HEADSET 0x1108 +#define SDP_UUID_CORDLESS_TELEPHONY 0x1109 +#define SDP_UUID_AUDIO_SOURCE 0x110a /* A2DP */ +#define SDP_UUID_AUDIO_SINK 0x110b /* A2DP */ +#define SDP_UUID_AV_REMOTE_TARGET 0x110c /* AVRCP */ +#define SDP_UUID_ADVANCED_AUDIO 0x110d /* A2DP */ +#define SDP_UUID_AV_REMOTE 0x110e /* AVRCP */ +#define SDP_UUID_VIDEO_CONFERENCING 0x110f /* VCP */ +#define SDP_UUID_INTERCOM 0x1110 +#define SDP_UUID_FAX 0x1111 +#define SDP_UUID_HEADSET_AUDIO_GATEWAY 0x1112 +#define SDP_UUID_WAP 0x1113 +#define SDP_UUID_WAP_CLIENT 0x1114 +#define SDP_UUID_PANU 0x1115 /* PAN */ +#define SDP_UUID_NAP 0x1116 /* PAN */ +#define SDP_UUID_GN 0x1117 /* PAN */ +#define SDP_UUID_DIRECT_PRINTING 0x1118 /* BPP */ +#define SDP_UUID_REFERENCE_PRINTING 0x1119 /* BPP */ +#define SDP_UUID_IMAGING 0x111a /* BIP */ +#define SDP_UUID_IMAGING_RESPONDER 0x111b /* BIP */ +#define SDP_UUID_IMAGING_AUTOMATIC_ARCHIVE 0x111c /* BIP */ +#define SDP_UUID_IMAGING_REFERENCED_OBJECTS 0x111d /* BIP */ +#define SDP_UUID_HANDSFREE 0x111e +#define SDP_UUID_HANDSFREE_AUDIO_GATEWAY 0x111f +#define SDP_UUID_DIRECT_PRINTING_REF_OBJS 0x1120 /* BPP */ +#define SDP_UUID_DIRECT_PRINTING_REFERENCE_OBJECTS 0x1120 /* BPP */ +#define SDP_UUID_REFLECTED_UI 0x1121 /* BPP */ +#define SDP_UUID_BASIC_PRINTING 0x1122 /* BPP */ +#define SDP_UUID_PRINTING_STATUS 0x1123 /* BPP */ +#define SDP_UUID_HUMAN_INTERFACE_DEVICE 0x1124 /* HID */ +#define SDP_UUID_HARDCOPY_CABLE_REPLACE 0x1125 /* HCRP */ +#define SDP_UUID_HCR_PRINT 0x1126 /* HCRP */ +#define SDP_UUID_HCR_SCAN 0x1127 /* HCRP */ +#define SDP_UUID_COMMON_ISDN_ACCESS 0x1128 /* CIP */ +#define SDP_UUID_VIDEO_CONFERENCING_GW 0x1129 /* VCP */ +#define SDP_UUID_UDI_MT 0x112a /* UDI */ +#define SDP_UUID_UDI_TA 0x112b /* UDI */ +#define SDP_UUID_AUDIO_VIDEO 0x112c /* VCP */ +#define SDP_UUID_SIM_ACCESS 0x112d /* SAP */ +#define SDP_UUID_PHONEBOOK_ACCESS_PCE 0x112e /* PBAP */ +#define SDP_UUID_PHONEBOOK_ACCESS_PSE 0x112f /* PBAP */ +#define SDP_UUID_PHONEBOOK_ACCESS 0x1130 /* PBAP */ +#define SDP_UUID_PNP_INFORMATION 0x1200 +#define SDP_UUID_GENERIC_NETWORKING 0x1201 +#define SDP_UUID_GENERIC_FILE_TRANSFER 0x1202 +#define SDP_UUID_GENERIC_AUDIO 0x1203 +#define SDP_UUID_GENERIC_TELEPHONY 0x1204 +#define SDP_UUID_UPNP_SERVICE 0x1205 /* ESDP */ +#define SDP_UUID_UPNP_IP_SERVICE 0x1206 /* ESDP */ +#define SDP_UUID_ESDP_UPNP_IP_PAN 0x1300 /* ESDP */ +#define SDP_UUID_ESDP_UPNP_IP_LAP 0x1301 /* ESDP */ +#define SDP_UUID_ESDP_UPNP_L2CAP 0x1302 /* ESDP */ +#define SDP_UUID_VIDEO_SOURCE 0x1303 /* VDP */ +#define SDP_UUID_VIDEO_SINK 0x1304 /* VDP */ +#define SDP_UUID_VIDEO_DISTRIBUTION 0x1305 /* VDP */ +#define SDP_UUID_APPLE_AGENT 0x2112 + +/* Bluetooth assigned numbers for Attribute IDs */ +#define SDP_ATTR_ID_SERVICE_RECORD_HANDLE 0x0000 +#define SDP_ATTR_ID_SERVICE_CLASS_ID_LIST 0x0001 +#define SDP_ATTR_ID_SERVICE_RECORD_STATE 0x0002 +#define SDP_ATTR_ID_SERVICE_SERVICE_ID 0x0003 +#define SDP_ATTR_ID_PROTOCOL_DESCRIPTOR_LIST 0x0004 +#define SDP_ATTR_ID_BROWSE_GROUP_LIST 0x0005 +#define SDP_ATTR_ID_LANGUAGE_BASE_ATTRIBUTE_ID_LIST 0x0006 +#define SDP_ATTR_ID_SERVICE_INFO_TIME_TO_LIVE 0x0007 +#define SDP_ATTR_ID_SERVICE_AVAILABILITY 0x0008 +#define SDP_ATTR_ID_BLUETOOTH_PROFILE_DESCRIPTOR_LIST 0x0009 +#define SDP_ATTR_ID_DOCUMENTATION_URL 0x000A +#define SDP_ATTR_ID_CLIENT_EXECUTABLE_URL 0x000B +#define SDP_ATTR_ID_ICON_10 0x000C +#define SDP_ATTR_ID_ICON_URL 0x000D +#define SDP_ATTR_ID_SERVICE_NAME 0x0100 +#define SDP_ATTR_ID_SERVICE_DESCRIPTION 0x0101 +#define SDP_ATTR_ID_PROVIDER_NAME 0x0102 +#define SDP_ATTR_ID_VERSION_NUMBER_LIST 0x0200 +#define SDP_ATTR_ID_GROUP_ID 0x0200 +#define SDP_ATTR_ID_SERVICE_DATABASE_STATE 0x0201 +#define SDP_ATTR_ID_SERVICE_VERSION 0x0300 + +#define SDP_ATTR_ID_EXTERNAL_NETWORK 0x0301 /* Cordless Telephony */ +#define SDP_ATTR_ID_SUPPORTED_DATA_STORES_LIST 0x0301 /* Synchronization */ +#define SDP_ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL 0x0302 /* GAP */ +#define SDP_ATTR_ID_SUPPORTED_FORMATS_LIST 0x0303 /* OBEX Object Push */ +#define SDP_ATTR_ID_FAX_CLASS_1_SUPPORT 0x0302 /* Fax */ +#define SDP_ATTR_ID_FAX_CLASS_2_0_SUPPORT 0x0303 +#define SDP_ATTR_ID_FAX_CLASS_2_SUPPORT 0x0304 +#define SDP_ATTR_ID_AUDIO_FEEDBACK_SUPPORT 0x0305 +#define SDP_ATTR_ID_SECURITY_DESCRIPTION 0x030a /* PAN */ +#define SDP_ATTR_ID_NET_ACCESS_TYPE 0x030b /* PAN */ +#define SDP_ATTR_ID_MAX_NET_ACCESS_RATE 0x030c /* PAN */ +#define SDP_ATTR_ID_IPV4_SUBNET 0x030d /* PAN */ +#define SDP_ATTR_ID_IPV6_SUBNET 0x030e /* PAN */ + +#define SDP_ATTR_ID_SUPPORTED_CAPABILITIES 0x0310 /* Imaging */ +#define SDP_ATTR_ID_SUPPORTED_FEATURES 0x0311 /* Imaging and Hansfree */ +#define SDP_ATTR_ID_SUPPORTED_FUNCTIONS 0x0312 /* Imaging */ +#define SDP_ATTR_ID_TOTAL_IMAGING_DATA_CAPACITY 0x0313 /* Imaging */ +#define SDP_ATTR_ID_SUPPORTED_REPOSITORIES 0x0314 /* PBAP */ + +#endif /* __SDP_H */ diff --git a/hcidump/parser/tcpip.c b/hcidump/parser/tcpip.c new file mode 100644 index 000000000..3cccee874 --- /dev/null +++ b/hcidump/parser/tcpip.c @@ -0,0 +1,142 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "parser.h" + +void arp_dump(int level, struct frame *frm) +{ +#if 0 + int i; + char buf[20]; + struct sockaddr_in sai; + struct ether_arp *arp = (struct ether_arp *) frm->ptr; + + printf("Src "); + for (i = 0; i < 5; i++) + printf("%02x:", arp->arp_sha[i]); + printf("%02x", arp->arp_sha[5]); + sai.sin_family = AF_INET; + memcpy(&sai.sin_addr, &arp->arp_spa, sizeof(sai.sin_addr)); + getnameinfo((struct sockaddr *) &sai, sizeof(sai), buf, sizeof(buf), + NULL, 0, NI_NUMERICHOST); + printf("(%s) ", buf); + printf("Tgt "); + for (i = 0; i < 5; i++) + printf("%02x:", arp->arp_tha[i]); + printf("%02x", arp->arp_tha[5]); + memcpy(&sai.sin_addr, &arp->arp_tpa, sizeof(sai.sin_addr)); + getnameinfo((struct sockaddr *) &sai, sizeof(sai), buf, sizeof(buf), + NULL, 0, NI_NUMERICHOST); + printf("(%s)\n", buf); + frm->ptr += sizeof(struct ether_arp); + frm->len -= sizeof(struct ether_arp); +#endif + raw_dump(level, frm); // not needed. +} + +void ip_dump(int level, struct frame *frm) +{ +#if 0 + char src[50], dst[50]; + struct ip *ip = (struct ip *) (frm->ptr); + uint8_t proto; + int len; + + if (ip->ip_v == 4) { + struct sockaddr_in sai; + proto = ip->ip_p; + len = ip->ip_hl << 2; + memset(&sai, 0, sizeof(sai)); + sai.sin_family = AF_INET; + memcpy(&sai.sin_addr, &ip->ip_src, sizeof(struct in_addr)); + getnameinfo((struct sockaddr *) &sai, sizeof(sai), + src, sizeof(src), NULL, 0, NI_NUMERICHOST); + memcpy(&sai.sin_addr, &ip->ip_dst, sizeof(struct in_addr)); + getnameinfo((struct sockaddr *) &sai, sizeof(sai), + dst, sizeof(dst), NULL, 0, NI_NUMERICHOST); + } else if (ip->ip_v == 6) { + struct sockaddr_in6 sai6; + struct ip6_hdr *ip6 = (struct ip6_hdr *) ip; + proto = ip6->ip6_nxt; + len = sizeof(struct ip6_hdr); + memset(&sai6, 0, sizeof(sai6)); + sai6.sin6_family = AF_INET6; + memcpy(&sai6.sin6_addr, &ip6->ip6_src, sizeof(struct in6_addr)); + getnameinfo((struct sockaddr *) &sai6, sizeof(sai6), + src, sizeof(src), NULL, 0, NI_NUMERICHOST); + memcpy(&sai6.sin6_addr, &ip6->ip6_dst, sizeof(struct in6_addr)); + getnameinfo((struct sockaddr *) &sai6, sizeof(sai6), + dst, sizeof(dst), NULL, 0, NI_NUMERICHOST); + } else { + raw_dump(level, frm); + return; + } + + printf("src %s ", src); + printf("dst %s\n", dst); + + frm->ptr += len; + frm->len -= len; + p_indent(++level, frm); + + switch (proto) { + case IPPROTO_TCP: + printf("TCP:\n"); + break; + + case IPPROTO_UDP: + printf("UDP:\n"); + break; + + case IPPROTO_ICMP: + printf("ICMP:\n"); + break; + + case IPPROTO_ICMPV6: + printf("ICMPv6:\n"); + break; + + default: + printf("Unknown Protocol: 0x%02x\n", ip->ip_p); + break; + } +#endif + raw_dump(level, frm); +} diff --git a/hcidump/src/Makefile.am b/hcidump/src/Makefile.am new file mode 100644 index 000000000..c66a1aa1c --- /dev/null +++ b/hcidump/src/Makefile.am @@ -0,0 +1,16 @@ + +sbin_PROGRAMS = hcidump + +noinst_PROGRAMS = bpasniff csrsniff + +LDADD = @BLUEZ_LIBS@ $(top_builddir)/parser/libparser.a + +man_MANS = hcidump.8 + +AM_CFLAGS = @BLUEZ_CFLAGS@ + +INCLUDES = -I$(top_srcdir) + +EXTRA_DIST = $(man_MANS) magic.btsnoop + +MAINTAINERCLEANFILES = Makefile.in diff --git a/hcidump/src/Makefile.in b/hcidump/src/Makefile.in new file mode 100644 index 000000000..ee3bd9384 --- /dev/null +++ b/hcidump/src/Makefile.in @@ -0,0 +1,490 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +sbin_PROGRAMS = hcidump$(EXEEXT) +noinst_PROGRAMS = bpasniff$(EXEEXT) csrsniff$(EXEEXT) +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" +sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS) +bpasniff_SOURCES = bpasniff.c +bpasniff_OBJECTS = bpasniff.$(OBJEXT) +bpasniff_LDADD = $(LDADD) +bpasniff_DEPENDENCIES = $(top_builddir)/parser/libparser.a +csrsniff_SOURCES = csrsniff.c +csrsniff_OBJECTS = csrsniff.$(OBJEXT) +csrsniff_LDADD = $(LDADD) +csrsniff_DEPENDENCIES = $(top_builddir)/parser/libparser.a +hcidump_SOURCES = hcidump.c +hcidump_OBJECTS = hcidump.$(OBJEXT) +hcidump_LDADD = $(LDADD) +hcidump_DEPENDENCIES = $(top_builddir)/parser/libparser.a +DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = bpasniff.c csrsniff.c hcidump.c +DIST_SOURCES = bpasniff.c csrsniff.c hcidump.c +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man_MANS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ_CFLAGS = @BLUEZ_CFLAGS@ +BLUEZ_LIBS = @BLUEZ_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +LDADD = @BLUEZ_LIBS@ $(top_builddir)/parser/libparser.a +man_MANS = hcidump.8 +AM_CFLAGS = @BLUEZ_CFLAGS@ +INCLUDES = -I$(top_srcdir) +EXTRA_DIST = $(man_MANS) magic.btsnoop +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \ + rm -f "$(DESTDIR)$(sbindir)/$$f"; \ + done + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) +bpasniff$(EXEEXT): $(bpasniff_OBJECTS) $(bpasniff_DEPENDENCIES) + @rm -f bpasniff$(EXEEXT) + $(LINK) $(bpasniff_OBJECTS) $(bpasniff_LDADD) $(LIBS) +csrsniff$(EXEEXT): $(csrsniff_OBJECTS) $(csrsniff_DEPENDENCIES) + @rm -f csrsniff$(EXEEXT) + $(LINK) $(csrsniff_OBJECTS) $(csrsniff_LDADD) $(LIBS) +hcidump$(EXEEXT): $(hcidump_OBJECTS) $(hcidump_DEPENDENCIES) + @rm -f hcidump$(EXEEXT) + $(LINK) $(hcidump_OBJECTS) $(hcidump_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpasniff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csrsniff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hcidump.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +install-man8: $(man8_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_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/^.*\\.//'`; \ + case "$$ext" in \ + 8*) ;; \ + *) ext='8' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \ + done +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_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/^.*\\.//'`; \ + case "$$ext" in \ + 8*) ;; \ + *) ext='8' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man8dir)/$$inst"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-noinstPROGRAMS clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-exec-am: install-sbinPROGRAMS + +install-html: install-html-am + +install-info: install-info-am + +install-man: install-man8 + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man uninstall-sbinPROGRAMS + +uninstall-man: uninstall-man8 + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstPROGRAMS clean-sbinPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man8 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-man uninstall-man8 \ + uninstall-sbinPROGRAMS + +# 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/hcidump/src/bpasniff.c b/hcidump/src/bpasniff.c new file mode 100644 index 000000000..43f6d5161 --- /dev/null +++ b/hcidump/src/bpasniff.c @@ -0,0 +1,476 @@ +/* + * + * 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 +#include +#include +#include + +#include +#include +#include + +#include + +#include "parser/parser.h" + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ +} + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static int read_revision(int dd, char *revision, int size) +{ + struct hci_request rq; + unsigned char req[] = { 0x07 }; + unsigned char buf[46]; + + 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) + return -1; + + if (buf[0] > 0) { + errno = EIO; + return -1; + } + + if (revision) + strncpy(revision, (char *) (buf + 1), size); + + return 0; +} + +static int enable_sniffer(int dd, uint8_t enable) +{ + struct hci_request rq; + unsigned char req[] = { 0x00, enable }; + unsigned char buf[1]; + + 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) + return -1; + + if (buf[0] > 0) { + errno = EIO; + return -1; + } + + return 0; +} + +static int enable_sync(int dd, uint8_t enable, bdaddr_t *bdaddr) +{ + struct hci_request rq; + unsigned char req[] = { 0x01, enable, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfa, 0x00 }; + + memcpy(req + 2, bdaddr, 6); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x000e; + rq.cparam = req; + rq.clen = sizeof(req); + + hci_send_req(dd, &rq, 1000); + + return 0; +} + +static char *type2str(uint8_t type) +{ + switch (type) { + case 0x00: + return "NULL"; + case 0x01: + return "POLL"; + case 0x02: + return "FHS"; + case 0x03: + return "DM1"; + case 0x04: + return "DH1"; + case 0x05: + return "HV1"; + case 0x06: + return "HV2"; + case 0x07: + return "HV3"; + case 0x08: + return "DV"; + case 0x09: + return "AUX1"; + case 0x0a: + return "DM3"; + case 0x0b: + return "DH3"; + case 0x0c: + return "EV4"; + case 0x0d: + return "EV5"; + case 0x0e: + return "DM5"; + case 0x0f: + return "DH5"; + case 0xff: + return "ID"; + default: + return "UNK"; + } +} + +static void decode(unsigned char *buf, int count) +{ + struct frame frm; + uint8_t id, status, channel; + uint16_t num, len; + uint32_t time; + uint8_t type, addr, temp, hdr; + uint8_t flow, arqn, seqn, hec, llid, pflow; + uint16_t plen; + + if (count < 7) + return; + + id = buf[0]; + num = ntohs(bt_get_unaligned((uint16_t *) (buf + 1))); + len = btohs(bt_get_unaligned((uint16_t *) (buf + 3))); + + status = buf[5]; + time = ntohl(bt_get_unaligned((uint32_t *) (buf + 6))); + channel = buf[10]; + + if (len < 8) + return; + + type = (len < 7) ? 0xff : bt_get_unaligned((uint8_t *) (buf + 11)); + + if (type < 2) + return; + + p_indent(-1, NULL); + + memset(&frm, 0, sizeof(frm)); + frm.data = buf + 12; + frm.data_len = count - 12; + frm.ptr = frm.data; + frm.len = frm.data_len; + frm.in = 0; + frm.master = 0; + frm.handle = 0; + frm.flags = 0; + + p_indent(0, &frm); + + printf("BPA: id %d num %d status 0x%02x time %d channel %2d len %d\n", + id, num, status, time, channel, len - 6); + + if (type < 3) { + printf(" %s\n", type2str(type)); + raw_dump(1, &frm); + return; + } + + addr = bt_get_unaligned((uint8_t *) (buf + 12)); + temp = bt_get_unaligned((uint8_t *) (buf + 13)); + flow = (temp & 0x04) >> 2; + arqn = (temp & 0x02) >> 1; + seqn = (temp & 0x01); + hec = bt_get_unaligned((uint8_t *) (buf + 14)); + + hdr = bt_get_unaligned((uint8_t *) (buf + 20)); + plen = ((hdr & 0x10) >> 4) | ((hdr & 0x08) >> 2) | (hdr & 0x04) | ((hdr & 0x02) << 2) | ((hdr & 0x01) << 4); + pflow = ((hdr & 0x20) >> 5); + llid = ((hdr & 0x80) >> 7) | ((hdr & 0x40) >> 5); + hdr = bt_get_unaligned((uint8_t *) (buf + 21)); + plen = plen | ((hdr & 0x80) >> 2) | (hdr & 0x40) | ((hdr & 0x20) << 2) | ((hdr & 0x08) << 4); + + p_indent(0, &frm); + + printf("%s: addr 0x%02x flow %d arqn %d seqn %d hec 0x%02x llid %d pflow %d plen %d\n", + type2str(type), addr, flow, arqn, seqn, hec, llid, pflow, plen); + + if (type == 0x03 && llid == 3) { + memset(&frm, 0, sizeof(frm)); + frm.data = buf + 22; + frm.data_len = plen; + frm.ptr = frm.data; + frm.len = frm.data_len; + frm.in = 0; + frm.master = 1; + frm.handle = 0; + frm.flags = llid; + + lmp_dump(1, &frm); + return; + } + + raw_dump(1, &frm); +} + +static void process_frames(int dev) +{ + struct sigaction sa; + struct hci_filter flt; + unsigned char *buf; + int dd, size = 2048; + + buf = malloc(size); + if (!buf) { + fprintf(stderr, "Can't allocate buffer for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + return; + } + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + free(buf); + return; + } + + hci_filter_clear(&flt); + hci_filter_set_ptype(HCI_VENDOR_PKT, &flt); + hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_set_event(EVT_VENDOR, &flt); + + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + fprintf(stderr, "Can't set filter for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + free(buf); + return; + } + + 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); + + while (!__io_canceled) { + int len; + + len = read(dd, buf, size); + if (len < 0) + break; + if (len < 2) + continue; + + if (buf[0] == 0x04 && buf[1] == 0xff) { + if (buf[3] == 0x02) { + switch (buf[4]) { + case 0x00: + printf("Waiting for synchronization...\n"); + break; + case 0x08: + printf("Synchronization lost\n"); + __io_canceled = 1; + break; + default: + printf("Unknown event 0x%02x\n", buf[4]); + break; + } + } + } + + if (buf[0] != 0xff) + continue; + + decode(buf + 1, len - 1); + } + + hci_close_dev(dd); + + free(buf); +} + +static void usage(void) +{ + printf("bpasniff - Utility for the BPA 100/105 sniffers\n\n"); + printf("Usage:\n" + "\tbpasniff [-i ] \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; + char rev[46]; + bdaddr_t bdaddr; + int dd, opt, dev = 0; + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + str2ba(argv[0], &bdaddr); + + 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 != 12) { + fprintf(stderr, "Can't find sniffer at hci%d: %s (%d)\n", + dev, strerror(ENOSYS), ENOSYS); + hci_close_dev(dd); + exit(1); + } + + if (read_revision(dd, rev, sizeof(rev)) < 0) { + fprintf(stderr, "Can't read revision info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + printf("%s\n", rev); + + if (enable_sniffer(dd, 0x01) < 0) { + fprintf(stderr, "Can't enable sniffer for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (enable_sync(dd, 0x01, &bdaddr) < 0) { + fprintf(stderr, "Can't enable sync for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + enable_sniffer(dd, 0x00); + hci_close_dev(dd); + exit(1); + } + + init_parser(DUMP_EXT | DUMP_VERBOSE, ~0L, 0, DEFAULT_COMPID, -1, -1); + + process_frames(dev); + + if (enable_sync(dd, 0x00, &bdaddr) < 0) { + fprintf(stderr, "Can't disable sync for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + enable_sniffer(dd, 0x00); + hci_close_dev(dd); + exit(1); + } + + if (enable_sniffer(dd, 0x00) < 0) { + fprintf(stderr, "Can't disable sniffer for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + hci_close_dev(dd); + + return 0; +} diff --git a/hcidump/src/csrsniff.c b/hcidump/src/csrsniff.c new file mode 100644 index 000000000..c32ca87c5 --- /dev/null +++ b/hcidump/src/csrsniff.c @@ -0,0 +1,282 @@ +/* + * + * 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 +#include + +#include +#include +#include + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ +} + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static struct { + uint16_t id; + uint16_t ver; + char *date; +} firmware_map[] = { + { 195, 1, "2001-11-27" }, + { 220, 2, "2002-01-03" }, + { 269, 3, "2002-02-22" }, + { 270, 4, "2002-02-26" }, + { 284, 5, "2002-03-12" }, + { 292, 6, "2002-03-20" }, + { 305, 7, "2002-04-12" }, + { 306, 8, "2002-04-12" }, + { 343, 9, "2002-05-02" }, + { 346, 10, "2002-05-03" }, + { 355, 11, "2002-05-16" }, + { 256, 11, "2002-05-16" }, + { 390, 12, "2002-06-26" }, + { 450, 13, "2002-08-16" }, + { 451, 13, "2002-08-16" }, + { 533, 14, "2002-10-11" }, + { 580, 15, "2002-11-14" }, + { 623, 16, "2002-12-12" }, + { 678, 17, "2003-01-29" }, + { 847, 18, "2003-04-17" }, + { 876, 19, "2003-06-10" }, + { 997, 22, "2003-09-05" }, + { 1027, 23, "2003-10-03" }, + { 1029, 24, "2003-10-03" }, + { 1112, 25, "2003-12-03" }, + { 1113, 25, "2003-12-03" }, + { 1133, 26, "2003-12-18" }, + { 1134, 26, "2003-12-18" }, + { 1223, 27, "2004-03-08" }, + { 1224, 27, "2004-03-08" }, + { 1319, 31, "2004-04-22" }, + { 1320, 31, "2004-04-22" }, + { 1427, 34, "2004-06-16" }, + { 1508, 35, "2004-07-19" }, + { 1509, 35, "2004-07-19" }, + { 1587, 36, "2004-08-18" }, + { 1588, 36, "2004-08-18" }, + { 1641, 37, "2004-09-16" }, + { 1642, 37, "2004-09-16" }, + { 1699, 38, "2004-10-07" }, + { 1700, 38, "2004-10-07" }, + { 1752, 39, "2004-11-02" }, + { 1753, 39, "2004-11-02" }, + { 1759, 40, "2004-11-03" }, + { 1760, 40, "2004-11-03" }, + { 1761, 40, "2004-11-03" }, + { 2009, 41, "2005-04-06" }, + { 2010, 41, "2005-04-06" }, + { 2011, 41, "2005-04-06" }, + { 2016, 42, "2005-04-11" }, + { 2017, 42, "2005-04-11" }, + { 2018, 42, "2005-04-11" }, + { 2023, 43, "2005-04-14" }, + { 2024, 43, "2005-04-14" }, + { 2025, 43, "2005-04-14" }, + { 2032, 44, "2005-04-18" }, + { 2033, 44, "2005-04-18" }, + { 2034, 44, "2005-04-18" }, + { 2288, 45, "2005-07-08" }, + { 2289, 45, "2005-07-08" }, + { 2290, 45, "2005-07-08" }, + { 2388, 46, "2005-08-17" }, + { 2389, 46, "2005-08-17" }, + { 2390, 46, "2005-08-17" }, + { 2869, 47, "2006-02-15" }, + { 2870, 47, "2006-02-15" }, + { 2871, 47, "2006-02-15" }, + { 3214, 48, "2006-02-16" }, + { 3215, 48, "2006-02-16" }, + { 3216, 48, "2006-02-16" }, + { 0, } +}; + +static int id2ver(uint16_t id) +{ + int i; + + for (i = 0; firmware_map[i].id; i++) + if (firmware_map[i].id == id) + return firmware_map[i].ver; + + return -1; +} + +static void usage(void) +{ + printf("csrsniff - Utility for the CSR BlueCore sniffers\n\n"); + printf("Usage:\n" + "\tcsrsniff [-i ] [slave-bdaddr]\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0} +}; + +int main(int argc, char *argv[]) +{ + struct sigaction sa; + struct hci_dev_info di; + struct hci_version ver; + struct hci_filter flt; + bdaddr_t bdaddr, master, slave; + int need_raw; + int dd, opt, dev = 0; + + bacpy(&slave, BDADDR_ANY); + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + str2ba(argv[0], &master); + + if (argc > 1) + str2ba(argv[1], &slave); + + 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 for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (ver.manufacturer != 10 || id2ver(ver.hci_rev) < 0) { + fprintf(stderr, "Can't find sniffer at hci%d: %s (%d)\n", + dev, strerror(ENOSYS), ENOSYS); + hci_close_dev(dd); + exit(1); + } + + if (!bacmp(&di.bdaddr, BDADDR_ANY)) { + if (hci_read_bd_addr(dd, &bdaddr, 1000) < 0) { + fprintf(stderr, "Can't read address for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + } else + bacpy(&bdaddr, &di.bdaddr); + + need_raw = !hci_test_bit(HCI_RAW, &di.flags); + + hci_filter_clear(&flt); + hci_filter_set_ptype(HCI_ACLDATA_PKT, &flt); + hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_set_event(EVT_VENDOR, &flt); + + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + fprintf(stderr, "Can't set filter for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + 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 (need_raw) { + if (ioctl(dd, HCISETRAW, 1) < 0) { + fprintf(stderr, "Can't set raw mode on hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + } + + printf("CSR sniffer - Bluetooth packet analyzer ver %s\n", VERSION); + + if (need_raw) { + if (ioctl(dd, HCISETRAW, 0) < 0) + fprintf(stderr, "Can't clear raw mode on hci%d: %s (%d)\n", + dev, strerror(errno), errno); + } + + hci_close_dev(dd); + + return 0; +} diff --git a/hcidump/src/hcidump.8 b/hcidump/src/hcidump.8 new file mode 100644 index 000000000..0bd4ec475 --- /dev/null +++ b/hcidump/src/hcidump.8 @@ -0,0 +1,148 @@ +.TH HCIDUMP 8 "Nov 12 2002" BlueZ "Linux System Administration" +.SH NAME +hcidump \- Parse HCI data +.SH SYNOPSIS +.B hcidump [-h] +.br +.B hcidump [option [option...]] [filter] + +.SH DESCRIPTION +.LP +.B +hcidump +reads raw HCI data coming from and going to a Bluetooth device (which can be +specified with the option +.BR -i , +default is the first available one) and prints to screen commands, events and +data in a human-readable form. Optionally, the dump can be written to a file +rather than parsed, and the dump file can be parsed in a subsequent moment. +.SH OPTIONS +.TP +.BI -h +Prints usage info and exits +.TP +.BI -i " " +Data is read from +.IR hciX , +which must be the name of an installed Bluetooth device. If not specified, +and if +.B +-r +option is not set, data is read from the first available Bluetooth device. +.TP +.BI -l " " "\fR,\fP \-\^\-snap-len=" "" +Sets max length of processed packets to +.IR len . +.TP +.BI -p " " "\fR,\fP \-\^\-psm=" "" +Sets default Protocol Service Multiplexer to +.IR psm . +.TP +.BI -m " " "\fR,\fP \-\^\-manufacturer=" "" +Sets default company id for manufacturer to +.IR compid . +.TP +.BI -w " " "\fR,\fP \-\^\-save-dump=" "" +Parse output is not printed to screen, instead data read from device is saved in file +.IR file . +The saved dump file can be subsequently parsed with option +.BR -r . +.TP +.BI -r " " "\fR,\fP \-\^\-read-dump=" "" +Data is not read from a Bluetooth device, but from file +.IR file . +.I +file +is created with option +.BR -w . +.TP +.BI -s " " "\fR,\fP \-\^\-send-dump=" "" +Parse output is not printed to screen, instead data read from device is sent to host +.IR host . +.TP +.BI -n " " "\fR,\fP \-\^\-recv-dump=" "" +Data is not read from a Bluetooth device, but from host +.IR host . +.TP +.BI -d " " "\fR,\fP \-\^\-wait-dump=" "" +Data is read from a Bluetooth device, but then send to +.IR host +for processing. No data is read if no host is connected. +.TP +.BR -t ", " "\-\^\-timestamp" +Prepend a time stamp to every packet. +.TP +.BR -a ", " "\-\^\-ascii" +For every packet, not only is the packet type displayed, but also all data in ASCII. +.TP +.BR -x ", " "\-\^\-hex" +For every packet, not only is the packet type displayed, but also all data in hex. +.TP +.BR -X ", " "\-\^\-ext" +For every packet, not only is the packet type displayed, but also all data in hex and ASCII. +.TP +.BR -R ", " "\-\^\-raw" +For every packet, only the raw data is displayed. +.TP +.BR -C ", " "\-\^\-cmtp=" "" +Sets the PSM value for the CAPI Message Transport Protocol. +.TP +.BR -H ", " "\-\^\-hcrp=" "" +Sets the PSM value for the Hardcopy Control Channel. +.TP +.BR -O ", " "\-\^\-obex=" "" +Sets the RFCOMM channel value for the Object Exchange Protocol. +.TP +.BR -P ", " "\-\^\-ppp=" "" +Sets the RFCOMM channel value for the Point-to-Point Protocol. +.TP +.BR -D ", " "\-\^\-pppdump=" "" +Extract PPP traffic with pppdump format. +.TP +.BR -A ", " "\-\^\-audio=" "" +Extract SCO audio data. +.TP +.BR -B ", " "\-\^\-btsnoop" +Use the BTSnoop file format. +.TP +.BR -V ", " "\-\^\-verbose" +Enables a more verbose decoding of every packet. +.TP +.BR -Y ", " "\-\^\-novendor" +Don't display any vendor commands or events and don't show any pin code or link key in plain text. +.TP +.BR -N ", " "\-\^\-noappend" +No appending to existing files. Always create new files. +.TP +.BR -4 ", " "\-\^\-ipv4" +Use IPv4 when sending information over the network +.TP +.BR -6 ", " "\-\^\-ipv6" +Use IPv6 when sending information over the network +.SH FILTERS +.B +filter +is a space-separated list of packet categories: available categories are +.IR lmp , +.IR hci , +.IR sco , +.IR l2cap , +.IR rfcomm , +.IR sdp , +.IR bnep , +.IR cmtp , +.IR hidp , +.IR hcrp , +.IR avdtp , +.IR avctp , +.IR obex , +.IR capi +and +.IR ppp . +If filters are used, only packets belonging to the specified categories are +dumped. By default, all packets are dumped. +.SH AUTHORS +Written by Maxim Krasnyansky +and Marcel Holtmann +.PP +man page by Fabrizio Gennari diff --git a/hcidump/src/hcidump.c b/hcidump/src/hcidump.c new file mode 100644 index 000000000..fd9ddc921 --- /dev/null +++ b/hcidump/src/hcidump.c @@ -0,0 +1,1172 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2002 Maxim Krasnyansky + * Copyright (C) 2003-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "parser/parser.h" +#include "parser/sdp.h" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +static inline uint64_t ntoh64(uint64_t n) +{ + uint64_t h; + uint64_t tmp = ntohl(n & 0x00000000ffffffff); + h = ntohl(n >> 32); + h |= tmp << 32; + return h; +} +#elif __BYTE_ORDER == __BIG_ENDIAN +#define ntoh64(x) (x) +#else +#error "Unknown byte order" +#endif +#define hton64(x) ntoh64(x) + +#define SNAP_LEN HCI_MAX_FRAME_SIZE +#define DEFAULT_PORT "10839"; + +/* Modes */ +enum { + PARSE, + READ, + WRITE, + RECEIVE, + SEND, + SERVER, + PPPDUMP, + AUDIO +}; + +/* Default options */ +static int snap_len = SNAP_LEN; +static int mode = PARSE; +static int permcheck = 1; +static int noappend = 0; +static char *dump_file = NULL; +static char *pppdump_file = NULL; +static char *audio_file = NULL; +static char *dump_addr; +static char *dump_port = DEFAULT_PORT; +static int af = AF_UNSPEC; + +struct hcidump_hdr { + uint16_t len; + uint8_t in; + uint8_t pad; + uint32_t ts_sec; + uint32_t ts_usec; +} __attribute__ ((packed)); +#define HCIDUMP_HDR_SIZE (sizeof(struct hcidump_hdr)) + +struct btsnoop_hdr { + uint8_t id[8]; /* Identification Pattern */ + uint32_t version; /* Version Number = 1 */ + uint32_t type; /* Datalink Type */ +} __attribute__ ((packed)); +#define BTSNOOP_HDR_SIZE (sizeof(struct btsnoop_hdr)) + +struct btsnoop_pkt { + uint32_t size; /* Original Length */ + uint32_t len; /* Included Length */ + uint32_t flags; /* Packet Flags */ + uint32_t drops; /* Cumulative Drops */ + uint64_t ts; /* Timestamp microseconds */ + uint8_t data[0]; /* Packet Data */ +} __attribute__ ((packed)); +#define BTSNOOP_PKT_SIZE (sizeof(struct btsnoop_pkt)) + +static uint8_t btsnoop_id[] = { 0x62, 0x74, 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00 }; + +static uint32_t btsnoop_version = 0; +static uint32_t btsnoop_type = 0; + +struct pktlog_hdr { + uint32_t len; + uint64_t ts; + uint8_t type; +} __attribute__ ((packed)); +#define PKTLOG_HDR_SIZE (sizeof(struct pktlog_hdr)) + +static inline int read_n(int fd, char *buf, int len) +{ + int t = 0, w; + + while (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; +} + +static inline int write_n(int fd, char *buf, int len) +{ + int t = 0, w; + + while (len > 0) { + if ((w = write(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; buf += w; t += w; + } + return t; +} + +static int process_frames(int dev, int sock, int fd, unsigned long flags) +{ + struct cmsghdr *cmsg; + struct msghdr msg; + struct iovec iv; + struct hcidump_hdr *dh; + struct btsnoop_pkt *dp; + struct frame frm; + struct pollfd fds[2]; + int nfds = 0; + char *buf, *ctrl; + int len, hdr_size = HCIDUMP_HDR_SIZE; + + if (sock < 0) + return -1; + + if (mode == SERVER) + flags |= DUMP_BTSNOOP; + + if (snap_len < SNAP_LEN) + snap_len = SNAP_LEN; + + if (flags & DUMP_BTSNOOP) + hdr_size = BTSNOOP_PKT_SIZE; + + buf = malloc(snap_len + hdr_size); + if (!buf) { + perror("Can't allocate data buffer"); + return -1; + } + + dh = (void *) buf; + dp = (void *) buf; + frm.data = buf + hdr_size; + + ctrl = malloc(100); + if (!ctrl) { + free(buf); + perror("Can't allocate control buffer"); + return -1; + } + + if (dev == HCI_DEV_NONE) + printf("system: "); + else + printf("device: hci%d ", dev); + + printf("snap_len: %d filter: 0x%lx\n", snap_len, parser.filter); + + memset(&msg, 0, sizeof(msg)); + + if (mode == SERVER) { + struct btsnoop_hdr *hdr = (void *) buf; + + btsnoop_version = 1; + btsnoop_type = 1002; + + memcpy(hdr->id, btsnoop_id, sizeof(btsnoop_id)); + hdr->version = htonl(btsnoop_version); + hdr->type = htonl(btsnoop_type); + + printf("btsnoop version: %d datalink type: %d\n", + btsnoop_version, btsnoop_type); + + len = write(fd, buf, BTSNOOP_HDR_SIZE); + if (len < 0) { + perror("Can't create dump header"); + return -1; + } + + if (len != BTSNOOP_HDR_SIZE) { + fprintf(stderr, "Header size mismatch\n"); + return -1; + } + + fds[nfds].fd = fd; + fds[nfds].events = POLLIN; + fds[nfds].revents = 0; + nfds++; + } + + fds[nfds].fd = sock; + fds[nfds].events = POLLIN; + fds[nfds].revents = 0; + nfds++; + + while (1) { + int i, n = poll(fds, nfds, -1); + if (n <= 0) + continue; + + for (i = 0; i < nfds; i++) { + if (fds[i].revents & (POLLHUP | POLLERR | POLLNVAL)) { + if (fds[i].fd == sock) + printf("device: disconnected\n"); + else + printf("client: disconnect\n"); + return 0; + } + } + + if (mode == SERVER) { + len = recv(fd, buf, snap_len, MSG_DONTWAIT); + if (len == 0) { + printf("client: disconnect\n"); + return 0; + } + if (len < 0 && errno != EAGAIN && errno != EINTR) { + perror("Connection read failure"); + return -1; + } + } + + iv.iov_base = frm.data; + iv.iov_len = snap_len; + + msg.msg_iov = &iv; + msg.msg_iovlen = 1; + msg.msg_control = ctrl; + msg.msg_controllen = 100; + + len = recvmsg(sock, &msg, MSG_DONTWAIT); + if (len < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + perror("Receive failed"); + return -1; + } + + /* Process control message */ + frm.data_len = len; + frm.dev_id = dev; + frm.in = 0; + frm.pppdump_fd = parser.pppdump_fd; + frm.audio_fd = parser.audio_fd; + + cmsg = CMSG_FIRSTHDR(&msg); + while (cmsg) { + switch (cmsg->cmsg_type) { + case HCI_CMSG_DIR: + frm.in = *((int *) CMSG_DATA(cmsg)); + break; + case HCI_CMSG_TSTAMP: + frm.ts = *((struct timeval *) CMSG_DATA(cmsg)); + break; + } + cmsg = CMSG_NXTHDR(&msg, cmsg); + } + + frm.ptr = frm.data; + frm.len = frm.data_len; + + switch (mode) { + case WRITE: + case SEND: + case SERVER: + /* Save or send dump */ + if (flags & DUMP_BTSNOOP) { + uint64_t ts; + uint8_t pkt_type = ((uint8_t *) frm.data)[0]; + dp->size = htonl(frm.data_len); + dp->len = dp->size; + dp->flags = ntohl(frm.in & 0x01); + dp->drops = 0; + ts = (frm.ts.tv_sec - 946684800ll) * 1000000ll + frm.ts.tv_usec; + dp->ts = hton64(ts + 0x00E03AB44A676000ll); + if (pkt_type == HCI_COMMAND_PKT || + pkt_type == HCI_EVENT_PKT) + dp->flags |= ntohl(0x02); + } else { + dh->len = htobs(frm.data_len); + dh->in = frm.in; + dh->ts_sec = htobl(frm.ts.tv_sec); + dh->ts_usec = htobl(frm.ts.tv_usec); + } + + if (write_n(fd, buf, frm.data_len + hdr_size) < 0) { + perror("Write error"); + return -1; + } + break; + + default: + /* Parse and print */ + parse(&frm); + break; + } + } + + return 0; +} + +static void read_dump(int fd) +{ + struct hcidump_hdr dh; + struct btsnoop_pkt dp; + struct pktlog_hdr ph; + struct frame frm; + uint8_t pkt_type; + int err; + + frm.data = malloc(HCI_MAX_FRAME_SIZE); + if (!frm.data) { + perror("Can't allocate data buffer"); + exit(1); + } + + while (1) { + if (parser.flags & DUMP_PKTLOG) + err = read_n(fd, (void *) &ph, PKTLOG_HDR_SIZE); + else if (parser.flags & DUMP_BTSNOOP) + err = read_n(fd, (void *) &dp, BTSNOOP_PKT_SIZE); + else + err = read_n(fd, (void *) &dh, HCIDUMP_HDR_SIZE); + + if (err < 0) + goto failed; + if (!err) + return; + + if (parser.flags & DUMP_PKTLOG) { + switch (ph.type) { + case 0x00: + ((uint8_t *) frm.data)[0] = HCI_COMMAND_PKT; + frm.in = 0; + break; + case 0x01: + ((uint8_t *) frm.data)[0] = HCI_EVENT_PKT; + frm.in = 1; + break; + case 0x02: + ((uint8_t *) frm.data)[0] = HCI_ACLDATA_PKT; + frm.in = 0; + break; + case 0x03: + ((uint8_t *) frm.data)[0] = HCI_ACLDATA_PKT; + frm.in = 1; + break; + default: + lseek(fd, ntohl(ph.len) - 9, SEEK_CUR); + continue; + } + + frm.data_len = ntohl(ph.len) - 8; + err = read_n(fd, frm.data + 1, frm.data_len - 1); + } else if (parser.flags & DUMP_BTSNOOP) { + switch (btsnoop_type) { + case 1001: + if (ntohl(dp.flags) & 0x02) { + if (ntohl(dp.flags) & 0x01) + pkt_type = HCI_EVENT_PKT; + else + pkt_type = HCI_COMMAND_PKT; + } else + pkt_type = HCI_ACLDATA_PKT; + + ((uint8_t *) frm.data)[0] = pkt_type; + + frm.data_len = ntohl(dp.len) + 1; + err = read_n(fd, frm.data + 1, frm.data_len - 1); + break; + + case 1002: + frm.data_len = ntohl(dp.len); + err = read_n(fd, frm.data, frm.data_len); + break; + } + } else { + frm.data_len = btohs(dh.len); + err = read_n(fd, frm.data, frm.data_len); + } + + if (err < 0) + goto failed; + if (!err) + return; + + frm.ptr = frm.data; + frm.len = frm.data_len; + + if (parser.flags & DUMP_PKTLOG) { + uint64_t ts; + ts = ntoh64(ph.ts); + frm.ts.tv_sec = ts >> 32; + frm.ts.tv_usec = ts & 0xffffffff; + } else if (parser.flags & DUMP_BTSNOOP) { + uint64_t ts; + frm.in = ntohl(dp.flags) & 0x01; + ts = ntoh64(dp.ts) - 0x00E03AB44A676000ll; + frm.ts.tv_sec = (ts / 1000000ll) + 946684800ll; + frm.ts.tv_usec = ts % 1000000ll; + } else { + frm.in = dh.in; + frm.ts.tv_sec = btohl(dh.ts_sec); + frm.ts.tv_usec = btohl(dh.ts_usec); + } + + parse(&frm); + } + +failed: + perror("Read failed"); + exit(1); +} + +static int open_file(char *file, int mode, unsigned long flags) +{ + unsigned char buf[BTSNOOP_HDR_SIZE]; + struct btsnoop_hdr *hdr = (struct btsnoop_hdr *) buf; + int fd, len, open_flags; + + if (mode == WRITE || mode == PPPDUMP || mode == AUDIO) { + if (noappend || flags & DUMP_BTSNOOP) + open_flags = O_WRONLY | O_CREAT | O_TRUNC; + else + open_flags = O_WRONLY | O_CREAT | O_APPEND; + } else + open_flags = O_RDONLY; + + fd = open(file, open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + perror("Can't open dump file"); + exit(1); + } + + if (mode == READ) { + len = read(fd, buf, BTSNOOP_HDR_SIZE); + if (len != BTSNOOP_HDR_SIZE) { + lseek(fd, 0, SEEK_SET); + return fd; + } + + if (!memcmp(hdr->id, btsnoop_id, sizeof(btsnoop_id))) { + parser.flags |= DUMP_BTSNOOP; + + btsnoop_version = ntohl(hdr->version); + btsnoop_type = ntohl(hdr->type); + + printf("btsnoop version: %d datalink type: %d\n", + btsnoop_version, btsnoop_type); + + if (btsnoop_version != 1) { + fprintf(stderr, "Unsupported BTSnoop version\n"); + exit(1); + } + + if (btsnoop_type != 1001 && btsnoop_type != 1002) { + fprintf(stderr, "Unsupported BTSnoop datalink type\n"); + exit(1); + } + } else { + if (buf[0] == 0x00 && buf[1] == 0x00) { + parser.flags |= DUMP_PKTLOG; + printf("packet logger data format\n"); + } + + parser.flags &= ~DUMP_BTSNOOP; + lseek(fd, 0, SEEK_SET); + return fd; + } + } else { + if (flags & DUMP_BTSNOOP) { + btsnoop_version = 1; + btsnoop_type = 1002; + + memcpy(hdr->id, btsnoop_id, sizeof(btsnoop_id)); + hdr->version = htonl(btsnoop_version); + hdr->type = htonl(btsnoop_type); + + printf("btsnoop version: %d datalink type: %d\n", + btsnoop_version, btsnoop_type); + + len = write(fd, buf, BTSNOOP_HDR_SIZE); + if (len < 0) { + perror("Can't create dump header"); + exit(1); + } + + if (len != BTSNOOP_HDR_SIZE) { + fprintf(stderr, "Header size mismatch\n"); + exit(1); + } + } + } + + return fd; +} + +static int open_socket(int dev, unsigned long flags) +{ + struct sockaddr_hci addr; + struct hci_filter flt; + struct hci_dev_info di; + int sk, dd, opt; + + if (permcheck && dev != HCI_DEV_NONE) { + dd = hci_open_dev(dev); + if (dd < 0) { + perror("Can't open device"); + return -1; + } + + if (hci_devinfo(dev, &di) < 0) { + perror("Can't get device info"); + return -1; + } + + opt = hci_test_bit(HCI_RAW, &di.flags); + if (ioctl(dd, HCISETRAW, opt) < 0) { + if (errno == EACCES) { + perror("Can't access device"); + return -1; + } + } + + hci_close_dev(dd); + } + + /* Create HCI socket */ + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) { + perror("Can't create raw socket"); + return -1; + } + + opt = 1; + if (setsockopt(sk, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) { + perror("Can't enable data direction info"); + return -1; + } + + opt = 1; + if (setsockopt(sk, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { + perror("Can't enable time stamp"); + return -1; + } + + /* Setup filter */ + hci_filter_clear(&flt); + hci_filter_all_ptypes(&flt); + hci_filter_all_events(&flt); + if (setsockopt(sk, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + perror("Can't set filter"); + return -1; + } + + /* Bind socket to the HCI device */ + addr.hci_family = AF_BLUETOOTH; + addr.hci_dev = dev; + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + printf("Can't attach to device hci%d. %s(%d)\n", + dev, strerror(errno), errno); + return -1; + } + + return sk; +} + +static int open_connection(char *addr, char *port) +{ + struct sockaddr_storage ss; + struct addrinfo hints, *res0, *res; + int sk = -1, opt = 1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + if (getaddrinfo(addr, port, &hints, &res0)) + if(getaddrinfo(NULL, port, &hints, &res0)) { + perror("getaddrinfo"); + exit(1); + } + + for (res = res0; res; res = res->ai_next) { + sk = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sk < 0) { + if (res->ai_next) + continue; + + perror("Can't create socket"); + freeaddrinfo(res0); + exit(1); + } + + setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + memcpy(&ss, res->ai_addr, res->ai_addrlen); + + switch(ss.ss_family) { + case AF_INET: + ((struct sockaddr_in *) &ss)->sin_addr.s_addr = htonl(INADDR_ANY); + ((struct sockaddr_in *) &ss)->sin_port = 0; + break; + } + + if (bind(sk, (struct sockaddr *) &ss, sizeof(ss)) < 0) { + perror("Can't bind socket"); + close(sk); + freeaddrinfo(res0); + exit(1); + } + + if (connect(sk, res->ai_addr, res->ai_addrlen) < 0) { + perror("Can't connect socket"); + close(sk); + freeaddrinfo(res0); + exit(1); + } + } + + freeaddrinfo(res0); + + return sk; +} + +static int create_datagram(unsigned short port) +{ + struct sockaddr_in addr; + int sk, opt = 1; + + sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sk < 0) + return -1; + + if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { + close(sk); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(sk); + return -1; + } + + return sk; +} + +static unsigned char ping_data[] = { 'p', 'i', 'n', 'g' }; +static unsigned char pong_data[] = { 'p', 'o', 'n', 'g' }; + +static void handle_datagram(int sk) +{ + struct sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + unsigned char buf[64]; + ssize_t len; + + len = recvfrom(sk, buf, sizeof(buf), MSG_DONTWAIT, + (struct sockaddr *) &addr, &addr_len); + + if (len != sizeof(ping_data)) + return; + + if (memcmp(buf, ping_data, sizeof(ping_data)) != 0) + return; + + len = sendto(sk, pong_data, sizeof(pong_data), 0, + (struct sockaddr *) &addr, sizeof(addr)); +} + +static int wait_connection(char *addr, char *port) +{ + char hname[100], hport[10]; + struct addrinfo *ai, *runp; + struct addrinfo hints; + struct pollfd fds[3]; + int err, opt, datagram, nfds = 0; + + memset(&hints, 0, sizeof (hints)); + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + err = getaddrinfo(dump_addr, dump_port, &hints, &ai); + if (err < 0) { + printf("Can't get address info: %s\n", gai_strerror(err)); + return -1; + } + + runp = ai; + + datagram = create_datagram(atoi(dump_port)); + if (datagram < 0) { + printf("server: no discover protocol\n"); + } else { + fds[nfds].fd = datagram; + fds[nfds].events = POLLIN; + nfds++; + } + + while (runp != NULL && nfds < sizeof(fds) / sizeof(fds[0])) { + fds[nfds].fd = socket(runp->ai_family, runp->ai_socktype, + runp->ai_protocol); + if (fds[nfds].fd < 0) { + perror("Can't create socket"); + return -1; + } + + fds[nfds].events = POLLIN; + + opt = 1; + setsockopt(fds[nfds].fd, SOL_SOCKET, SO_REUSEADDR, + &opt, sizeof(opt)); + + opt = 0; + setsockopt(fds[nfds].fd, SOL_SOCKET, SO_KEEPALIVE, + &opt, sizeof(opt)); + + if (bind(fds[nfds].fd, runp->ai_addr, runp->ai_addrlen) < 0) { + if (errno != EADDRINUSE) { + perror("Can't bind socket"); + return -1; + } + + close(fds[nfds].fd); + } else { + if (listen(fds[nfds].fd, SOMAXCONN) < 0) { + perror("Can't listen on socket"); + return -1; + } + + getnameinfo(runp->ai_addr, runp->ai_addrlen, + hname, sizeof(hname), + hport, sizeof(hport), + NI_NUMERICSERV); + + printf("server: %s:%s snap_len: %d filter: 0x%lx\n", + hname, hport, snap_len, parser.filter); + + nfds++; + } + + runp = runp->ai_next; + } + + freeaddrinfo(ai); + + while (1) { + int i, n = poll(fds, nfds, -1); + if (n <= 0) + continue; + + for (i = 0; i < nfds; i++) { + struct sockaddr_storage rem; + socklen_t remlen = sizeof(rem); + int sk; + + if (!(fds[i].revents & POLLIN)) + continue; + + if (fds[i].fd == datagram) { + handle_datagram(datagram); + continue; + } + + sk = accept(fds[i].fd, (struct sockaddr *) &rem, &remlen); + if (sk < 0) + continue; + + getnameinfo((struct sockaddr *) &rem, remlen, + hname, sizeof(hname), + hport, sizeof(hport), + NI_NUMERICSERV); + + printf("client: %s:%s snap_len: %d filter: 0x%lx\n", + hname, hport, snap_len, parser.filter); + + for (n = 0; n < nfds; n++) + close(fds[n].fd); + + return sk; + } + } + + return -1; +} + +static int run_server(int dev, char *addr, char *port, unsigned long flags) +{ + while (1) { + int dd, sk; + + sk = wait_connection(addr, port); + if (sk < 0) + continue; + + //fcntl(sk, F_SETFL, O_NONBLOCK); + + dd = open_socket(dev, flags); + if (dd < 0) { + close(sk); + continue; + } + + process_frames(dev, dd, sk, flags); + + close(dd); + close(sk); + } + + return 0; +} + +static struct { + char *name; + int flag; +} filters[] = { + { "lmp", FILT_LMP }, + { "hci", FILT_HCI }, + { "sco", FILT_SCO }, + { "l2cap", FILT_L2CAP }, + { "rfcomm", FILT_RFCOMM }, + { "sdp", FILT_SDP }, + { "bnep", FILT_BNEP }, + { "cmtp", FILT_CMTP }, + { "hidp", FILT_HIDP }, + { "hcrp", FILT_HCRP }, + { "avdtp", FILT_AVDTP }, + { "avctp", FILT_AVCTP }, + { "obex", FILT_OBEX }, + { "capi", FILT_CAPI }, + { "ppp", FILT_PPP }, + { "csr", FILT_CSR }, + { "dga", FILT_DGA }, + { 0 } +}; + +static unsigned long parse_filter(int argc, char **argv) +{ + unsigned long filter = 0; + int i,n; + + for (i = 0; i < argc; i++) { + for (n = 0; filters[n].name; n++) { + if (!strcasecmp(filters[n].name, argv[i])) { + filter |= filters[n].flag; + break; + } + } + } + + return filter; +} + +static void usage(void) +{ + printf( + "Usage: hcidump [OPTION...] [filter]\n" + " -i, --device=hci_dev HCI device\n" + " -l, --snap-len=len Snap len (in bytes)\n" + " -p, --psm=psm Default PSM\n" + " -m, --manufacturer=compid Default manufacturer\n" + " -w, --save-dump=file Save dump to a file\n" + " -r, --read-dump=file Read dump from a file\n" + " -s, --send-dump=host Send dump to a host\n" + " -n, --recv-dump=host Receive dump on a host\n" + " -d, --wait-dump=host Wait on a host and send\n" + " -t, --ts Display time stamps\n" + " -a, --ascii Dump data in ascii\n" + " -x, --hex Dump data in hex\n" + " -X, --ext Dump data in hex and ascii\n" + " -R, --raw Dump raw data\n" + " -C, --cmtp=psm PSM for CMTP\n" + " -H, --hcrp=psm PSM for HCRP\n" + " -O, --obex=channel Channel for OBEX\n" + " -P, --ppp=channel Channel for PPP\n" + " -D, --pppdump=file Extract PPP traffic\n" + " -A, --audio=file Extract SCO audio data\n" + " -B, --btsnoop Use BTSnoop file format\n" + " -V, --verbose Verbose decoding\n" + " -Y, --novendor No vendor commands or events\n" + " -N, --noappend No appending to existing files\n" + " -4, --ipv4 Use IPv4 as transport\n" + " -6 --ipv6 Use IPv6 as transport\n" + " -h, --help Give this help list\n" + " --usage Give a short usage message\n" + ); +} + +static struct option main_options[] = { + { "device", 1, 0, 'i' }, + { "snap-len", 1, 0, 'l' }, + { "psm", 1, 0, 'p' }, + { "manufacturer", 1, 0, 'm' }, + { "save-dump", 1, 0, 'w' }, + { "read-dump", 1, 0, 'r' }, + { "send-dump", 1, 0, 's' }, + { "recv-dump", 1, 0, 'n' }, + { "wait-dump", 1, 0, 'd' }, + { "timestamp", 0, 0, 't' }, + { "ascii", 0, 0, 'a' }, + { "hex", 0, 0, 'x' }, + { "ext", 0, 0, 'X' }, + { "raw", 0, 0, 'R' }, + { "cmtp", 1, 0, 'C' }, + { "hcrp", 1, 0, 'H' }, + { "obex", 1, 0, 'O' }, + { "ppp", 1, 0, 'P' }, + { "pppdump", 1, 0, 'D' }, + { "audio", 1, 0, 'A' }, + { "btsnoop", 0, 0, 'B' }, + { "verbose", 0, 0, 'V' }, + { "novendor", 0, 0, 'Y' }, + { "nopermcheck", 0, 0, 'Z' }, + { "noappend", 0, 0, 'N' }, + { "ipv4", 0, 0, '4' }, + { "ipv6", 0, 0, '6' }, + { "help", 0, 0, 'h' }, + { 0 } +}; + +int main(int argc, char *argv[]) +{ + unsigned long flags = 0; + unsigned long filter = 0; + int device = 0; + int defpsm = 0; + int defcompid = DEFAULT_COMPID; + int opt, pppdump_fd = -1, audio_fd = -1; + + printf("HCI sniffer - Bluetooth packet analyzer ver %s\n", VERSION); + + while ((opt=getopt_long(argc, argv, "i:l:p:m:w:r:s:n:d:taxXRC:H:O:P:D:A:BVYZN46h", main_options, NULL)) != -1) { + switch(opt) { + case 'i': + if (strcasecmp(optarg, "none") && strcasecmp(optarg, "system")) + device = atoi(optarg + 3); + else + device = HCI_DEV_NONE; + break; + + case 'l': + snap_len = atoi(optarg); + break; + + case 'p': + defpsm = atoi(optarg); + break; + + case 'm': + defcompid = atoi(optarg); + break; + + case 'w': + mode = WRITE; + dump_file = strdup(optarg); + break; + + case 'r': + mode = READ; + dump_file = strdup(optarg); + break; + + case 's': + mode = SEND; + dump_addr = optarg; + break; + + case 'n': + mode = RECEIVE; + dump_addr = optarg; + break; + + case 'd': + mode = SERVER; + dump_addr = optarg; + break; + + case 't': + flags |= DUMP_TSTAMP; + break; + + case 'a': + flags |= DUMP_ASCII; + break; + + case 'x': + flags |= DUMP_HEX; + break; + + case 'X': + flags |= DUMP_EXT; + break; + + case 'R': + flags |= DUMP_RAW; + break; + + case 'C': + set_proto(0, atoi(optarg), 0, SDP_UUID_CMTP); + break; + + case 'H': + set_proto(0, atoi(optarg), 0, SDP_UUID_HARDCOPY_CONTROL_CHANNEL); + break; + + case 'O': + set_proto(0, 0, atoi(optarg), SDP_UUID_OBEX); + break; + + case 'P': + set_proto(0, 0, atoi(optarg), SDP_UUID_LAN_ACCESS_PPP); + break; + + case 'D': + pppdump_file = strdup(optarg); + break; + + case 'A': + audio_file = strdup(optarg); + break; + + case 'B': + flags |= DUMP_BTSNOOP; + break; + + case 'V': + flags |= DUMP_VERBOSE; + break; + + case 'Y': + flags |= DUMP_NOVENDOR; + break; + + case 'Z': + permcheck = 0; + break; + + case 'N': + noappend = 1; + break; + + case '4': + af = AF_INET; + break; + + case '6': + af = AF_INET6; + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc > 0) + filter = parse_filter(argc, argv); + + /* Default settings */ + if (!filter) + filter = ~0L; + + if (pppdump_file) + pppdump_fd = open_file(pppdump_file, PPPDUMP, flags); + + if (audio_file) + audio_fd = open_file(audio_file, AUDIO, flags); + + switch (mode) { + case PARSE: + init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd); + process_frames(device, open_socket(device, flags), -1, flags); + break; + + case READ: + init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd); + read_dump(open_file(dump_file, mode, flags)); + break; + + case WRITE: + process_frames(device, open_socket(device, flags), + open_file(dump_file, mode, flags), flags); + break; + + case RECEIVE: + init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd); + read_dump(wait_connection(dump_addr, dump_port)); + break; + + case SEND: + process_frames(device, open_socket(device, flags), + open_connection(dump_addr, dump_port), flags); + break; + + case SERVER: + init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd); + run_server(device, dump_addr, dump_port, flags); + break; + } + + return 0; +} diff --git a/hcidump/src/magic.btsnoop b/hcidump/src/magic.btsnoop new file mode 100644 index 000000000..1dca663f2 --- /dev/null +++ b/hcidump/src/magic.btsnoop @@ -0,0 +1,12 @@ + +#------------------------------------------------------------------------------ +# BTSnoop: file(1) magic for BTSnoop files +# +# From +0 string btsnoop\0 BTSnoop +>8 belong x version %d, +>12 belong 1001 Unencapsulated HCI +>12 belong 1002 HCI UART (H4) +>12 belong 1003 HCI BCSP +>12 belong 1004 HCI Serial (H5) +>>12 belong x type %d diff --git a/utils/audio/Android.mk b/utils/audio/Android.mk index b6ed509a9..3dc2d40dc 100644 --- a/utils/audio/Android.mk +++ b/utils/audio/Android.mk @@ -1,33 +1,9 @@ -# Note: this currently does not build due to a dependency on -# libhciserver, which the Android build of bluez-utils/hcid -# does not produce. - -BUILD_HEADSETD:=0 -ifeq ($(BUILD_HEADSETD),1) - LOCAL_PATH:= $(call my-dir) -# -# headsetd -# +# A2DP plugin include $(CLEAR_VARS) -LOCAL_C_INCLUDES:= \ - $(call include-path-for, bluez-libs) \ - $(call include-path-for, dbus) \ - $(call include-path-for, bluez-utils)/common \ - $(call include-path-for, bluez-utils)/sdpd \ - $(call include-path-for, bluez-utils)/eglib \ - $(call include-path-for, bluez-utils)/gdbus - -LOCAL_CFLAGS:= \ - -DVERSION=\"3.36\" \ - -DSTORAGEDIR=\"/data\" \ - -DCONFIGDIR=\"/etc\" \ - -DENABLE_DEBUG \ - -D__S_IFREG=0100000 # missing from bionic stat.h - LOCAL_SRC_FILES:= \ a2dp.c \ avdtp.c \ @@ -35,22 +11,62 @@ LOCAL_SRC_FILES:= \ device.c \ headset.c \ ipc.c \ - sink.c \ - unix.c \ + main.c \ manager.c \ + sink.c \ + unix.c + +LOCAL_CFLAGS:= \ + -DVERSION=\"3.36\" \ + -DSTORAGEDIR=\"/data/misc/hcid\" \ + -DCONFIGDIR=\"/etc/bluez\" \ + -D__S_IFREG=0100000 # missing from bionic stat.h + +LOCAL_C_INCLUDES:= \ + $(call include-path-for, bluez-libs) \ + $(call include-path-for, bluez-utils)/common \ + $(call include-path-for, bluez-utils)/hcid \ + $(call include-path-for, bluez-utils)/sdpd \ + $(call include-path-for, bluez-utils)/eglib \ + $(call include-path-for, bluez-utils)/gdbus \ + $(call include-path-for, dbus) LOCAL_SHARED_LIBRARIES := \ libbluetooth \ + libhcid \ libdbus -LOCAL_STATIC_LIBRARIES := \ - libbluez-utils-common-static \ - libeglib_static \ - libsdpserver_static \ - libgdbus_static +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/bluez-plugin +LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)/bluez-plugin +LOCAL_MODULE := audio + +include $(BUILD_SHARED_LIBRARY) -LOCAL_MODULE:=headsetd +# liba2sp + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + liba2dp.c \ + ipc.c \ + ../sbc/sbc.c.arm + +LOCAL_C_INCLUDES:= \ + $(call include-path-for, bluez-libs) \ + $(call include-path-for, bluez-utils)/common \ + $(call include-path-for, bluez-utils)/hcid \ + $(call include-path-for, bluez-utils)/sdpd \ + $(call include-path-for, bluez-utils)/eglib \ + $(call include-path-for, bluez-utils)/gdbus \ + $(call include-path-for, bluez-utils)/sbc \ + $(call include-path-for, dbus) + +LOCAL_SHARED_LIBRARIES := \ + libbluetooth \ + libhcid \ + libdbus \ + libcutils -include $(BUILD_EXECUTABLE) +LOCAL_MODULE := liba2dp -endif +include $(BUILD_SHARED_LIBRARY) diff --git a/utils/audio/avdtp.c b/utils/audio/avdtp.c index bda21ac5f..db97ec5df 100644 --- a/utils/audio/avdtp.c +++ b/utils/audio/avdtp.c @@ -2370,6 +2370,9 @@ gboolean avdtp_stream_remove_cb(struct avdtp *session, GSList *l; struct stream_callback *cb; + if (!stream) + return FALSE; + for (cb = NULL, l = stream->callbacks; l != NULL; l = l->next) { struct stream_callback *tmp = l->data; if (tmp->id == id) { diff --git a/utils/audio/control.c b/utils/audio/control.c index 9139213b8..c16e79c84 100644 --- a/utils/audio/control.c +++ b/utils/audio/control.c @@ -101,7 +101,7 @@ static uint32_t tg_record_id = 0; static uint32_t ct_record_id = 0; static GIOChannel *avctp_server = NULL; - +static gchar *input_device_name = NULL; static GSList *sessions = NULL; typedef enum { @@ -584,10 +584,14 @@ static int uinput_create(char *name) static void init_uinput(struct avctp *session) { char address[18], *name; + GError *err = NULL; ba2str(&session->dst, address); - name = session->dev->name ? session->dev->name : address; + /* use device name from config file if specified */ + name = input_device_name; + if (!name) + name = session->dev->name ? session->dev->name : address; session->uinput = uinput_create(name); if (session->uinput < 0) @@ -825,8 +829,17 @@ int avrcp_init(DBusConnection *conn, GKeyFile *config) if (err) { debug("audio.conf: %s", err->message); g_error_free(err); + err = NULL; } else master = tmp; + + input_device_name = g_key_file_get_string(config, + "AVRCP", "InputDeviceName", &err); + if (err) { + debug("InputDeviceName not specified in audio.conf"); + input_device_name = NULL; + g_error_free(err); + } } connection = dbus_connection_ref(conn); diff --git a/utils/audio/liba2dp.c b/utils/audio/liba2dp.c new file mode 100644 index 000000000..79049488d --- /dev/null +++ b/utils/audio/liba2dp.c @@ -0,0 +1,691 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2006-2007 Nokia Corporation + * Copyright (C) 2004-2008 Marcel Holtmann + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; 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 "ipc.h" +#include "sbc.h" +#include "rtp.h" +#include "liba2dp.h" + +#define LOG_TAG "A2DP" +#include + +// #define ENABLE_DEBUG + +#define BUFFER_SIZE 2048 + +#ifdef ENABLE_DEBUG +#define DBG LOGD +#else +#define DBG(fmt, arg...) +#endif + + +#ifndef MIN +# define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif + +#ifndef MAX +# define MAX(x, y) ((x) > (y) ? (x) : (y)) +#endif + +#define MAX_BITPOOL 64 +#define MIN_BITPOOL 2 + +#define SNDERR LOGE + +struct bluetooth_a2dp { + sbc_capabilities_t sbc_capabilities; + sbc_t sbc; /* Codec data */ + int sbc_initialized; /* Keep track if the encoder is initialized */ + int codesize; /* SBC codesize */ + int samples; /* Number of encoded samples */ + uint8_t buffer[BUFFER_SIZE]; /* Codec transfer buffer */ + int count; /* Codec transfer buffer counter */ + + int nsamples; /* Cumulative number of codec samples */ + uint16_t seq_num; /* Cumulative packet sequence */ + int frame_count; /* Current frames in buffer*/ +}; + + +struct bluetooth_data { + volatile long hw_ptr; + int transport; /* chosen transport SCO or AD2P */ + int link_mtu; /* MTU for selected transport channel */ + volatile struct pollfd stream; /* Audio stream filedescriptor */ + struct pollfd server; /* Audio daemon filedescriptor */ + uint8_t buffer[BUFFER_SIZE]; /* Encoded transfer buffer */ + int count; /* Transfer buffer counter */ + struct bluetooth_a2dp a2dp; /* A2DP data */ + + sig_atomic_t reset; /* Request XRUN handling */ + + char address[20]; +}; + + + +static int audioservice_send(int sk, const bt_audio_msg_header_t *msg); +static int audioservice_expect(int sk, bt_audio_msg_header_t *outmsg, + int expected_type); + + +static void bluetooth_exit(struct bluetooth_data *data) +{ + struct bluetooth_a2dp *a2dp = &data->a2dp; + + if (data->server.fd >= 0) + bt_audio_service_close(data->server.fd); + + if (data->stream.fd >= 0) + close(data->stream.fd); + + if (a2dp->sbc_initialized) + sbc_finish(&a2dp->sbc); +} + +static int bluetooth_prepare(struct bluetooth_data *data) +{ + char c = 'w'; + char buf[BT_AUDIO_IPC_PACKET_SIZE]; + struct bt_streamstart_req *start_req = (void*) buf; + bt_audio_rsp_msg_header_t *rsp_hdr = (void*) buf; + struct bt_streamfd_ind *streamfd_ind = (void*) buf; + int opt_name, err; + struct timeval t = { 100, 0 }; + int buffer; + + data->reset = 0; + data->hw_ptr = 0; + + /* send start */ + memset(start_req, 0, BT_AUDIO_IPC_PACKET_SIZE); + start_req->h.msg_type = BT_STREAMSTART_REQ; + + err = audioservice_send(data->server.fd, &start_req->h); + if (err < 0) + return err; + + err = audioservice_expect(data->server.fd, &rsp_hdr->msg_h, + BT_STREAMSTART_RSP); + if (err < 0) + return err; + + if (rsp_hdr->posix_errno != 0) { + SNDERR("BT_START failed : %s(%d)", + strerror(rsp_hdr->posix_errno), + rsp_hdr->posix_errno); + return -rsp_hdr->posix_errno; + } + + err = audioservice_expect(data->server.fd, &streamfd_ind->h, + BT_STREAMFD_IND); + if (err < 0) + return err; + + if (data->stream.fd >= 0) + close(data->stream.fd); + + data->stream.fd = bt_audio_service_get_data_fd(data->server.fd); + if (data->stream.fd < 0) { + return -errno; + } + + if (setsockopt(data->stream.fd, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t)) < 0) + return -errno; + + /* disable buffering to reduce latency when pausing or changing volume */ + buffer = 0; + if (setsockopt(data->stream.fd, SOL_SOCKET, SO_SNDBUF, &buffer, sizeof(buffer)) < 0) + return -errno; + + return 0; +} + +static uint8_t default_bitpool(uint8_t freq, uint8_t mode) +{ + switch (freq) { + case BT_SBC_SAMPLING_FREQ_16000: + case BT_SBC_SAMPLING_FREQ_32000: + return 53; + case BT_SBC_SAMPLING_FREQ_44100: + switch (mode) { + case BT_A2DP_CHANNEL_MODE_MONO: + case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL: + return 31; + case BT_A2DP_CHANNEL_MODE_STEREO: + case BT_A2DP_CHANNEL_MODE_JOINT_STEREO: + return 53; + default: + DBG("Invalid channel mode %u", mode); + return 53; + } + case BT_SBC_SAMPLING_FREQ_48000: + switch (mode) { + case BT_A2DP_CHANNEL_MODE_MONO: + case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL: + return 29; + case BT_A2DP_CHANNEL_MODE_STEREO: + case BT_A2DP_CHANNEL_MODE_JOINT_STEREO: + return 51; + default: + DBG("Invalid channel mode %u", mode); + return 51; + } + default: + DBG("Invalid sampling freq %u", freq); + return 53; + } +} + +static int bluetooth_a2dp_init(struct bluetooth_data *data, int rate, int channels) +{ + sbc_capabilities_t *cap = &data->a2dp.sbc_capabilities; + unsigned int max_bitpool, min_bitpool; + int dir; + + switch (rate) { + case 48000: + cap->frequency = BT_SBC_SAMPLING_FREQ_48000; + break; + case 44100: + cap->frequency = BT_SBC_SAMPLING_FREQ_44100; + break; + case 32000: + cap->frequency = BT_SBC_SAMPLING_FREQ_32000; + break; + case 16000: + cap->frequency = BT_SBC_SAMPLING_FREQ_16000; + break; + default: + DBG("Rate %d not supported", rate); + return -1; + } + + if (channels == 2) { + if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO) + cap->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO; + else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) + cap->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO; + else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) + cap->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL; + } else { + if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) + cap->channel_mode = BT_A2DP_CHANNEL_MODE_MONO; + } + + if (!cap->channel_mode) { + DBG("No supported channel modes"); + return -1; + } + + if (cap->block_length & BT_A2DP_BLOCK_LENGTH_16) + cap->block_length = BT_A2DP_BLOCK_LENGTH_16; + else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_12) + cap->block_length = BT_A2DP_BLOCK_LENGTH_12; + else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_8) + cap->block_length = BT_A2DP_BLOCK_LENGTH_8; + else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_4) + cap->block_length = BT_A2DP_BLOCK_LENGTH_4; + else { + DBG("No supported block lengths"); + return -1; + } + + if (cap->subbands & BT_A2DP_SUBBANDS_8) + cap->subbands = BT_A2DP_SUBBANDS_8; + else if (cap->subbands & BT_A2DP_SUBBANDS_4) + cap->subbands = BT_A2DP_SUBBANDS_4; + else { + DBG("No supported subbands"); + return -1; + } + + if (cap->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS) + cap->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS; + else if (cap->allocation_method & BT_A2DP_ALLOCATION_SNR) + cap->allocation_method = BT_A2DP_ALLOCATION_SNR; + + min_bitpool = MAX(MIN_BITPOOL, cap->min_bitpool); + max_bitpool = MIN(default_bitpool(cap->frequency, + cap->channel_mode), + cap->max_bitpool); + + cap->min_bitpool = min_bitpool; + cap->max_bitpool = max_bitpool; + +DBG("bluetooth_a2dp_init bottom:\n channel_mode: %d\n frequency: %d\n allocation_method: %d\n subbands: %d\n block_length: %d\n min_bitpool: %d\n max_bitpool: %d\n ", + cap->channel_mode, cap->frequency, cap->allocation_method, cap->subbands, + cap->block_length, cap->min_bitpool, cap->max_bitpool); + + + return 0; +} + +static void bluetooth_a2dp_setup(struct bluetooth_a2dp *a2dp) +{ + sbc_capabilities_t active_capabilities = a2dp->sbc_capabilities; + + if (a2dp->sbc_initialized) + sbc_reinit(&a2dp->sbc, 0); + else + sbc_init(&a2dp->sbc, 0); + a2dp->sbc_initialized = 1; + + if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_16000) + a2dp->sbc.frequency = SBC_FREQ_16000; + + if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_32000) + a2dp->sbc.frequency = SBC_FREQ_32000; + + if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_44100) + a2dp->sbc.frequency = SBC_FREQ_44100; + + if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_48000) + a2dp->sbc.frequency = SBC_FREQ_48000; + + if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_MONO) + a2dp->sbc.mode = SBC_MODE_MONO; + + if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) + a2dp->sbc.mode = SBC_MODE_DUAL_CHANNEL; + + if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) + a2dp->sbc.mode = SBC_MODE_STEREO; + + if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO) + a2dp->sbc.mode = SBC_MODE_JOINT_STEREO; + + a2dp->sbc.allocation = active_capabilities.allocation_method + == BT_A2DP_ALLOCATION_SNR ? SBC_AM_SNR + : SBC_AM_LOUDNESS; + + switch (active_capabilities.subbands) { + case BT_A2DP_SUBBANDS_4: + a2dp->sbc.subbands = SBC_SB_4; + break; + case BT_A2DP_SUBBANDS_8: + a2dp->sbc.subbands = SBC_SB_8; + break; + } + + switch (active_capabilities.block_length) { + case BT_A2DP_BLOCK_LENGTH_4: + a2dp->sbc.blocks = SBC_BLK_4; + break; + case BT_A2DP_BLOCK_LENGTH_8: + a2dp->sbc.blocks = SBC_BLK_8; + break; + case BT_A2DP_BLOCK_LENGTH_12: + a2dp->sbc.blocks = SBC_BLK_12; + break; + case BT_A2DP_BLOCK_LENGTH_16: + a2dp->sbc.blocks = SBC_BLK_16; + break; + } + + a2dp->sbc.bitpool = active_capabilities.max_bitpool; + a2dp->codesize = sbc_get_codesize(&a2dp->sbc); + a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload); +} + +static int bluetooth_a2dp_hw_params(struct bluetooth_data *data, int rate, int channels) +{ + struct bluetooth_a2dp *a2dp = &data->a2dp; + char buf[BT_AUDIO_IPC_PACKET_SIZE]; + bt_audio_rsp_msg_header_t *rsp_hdr = (void*) buf; + struct bt_setconfiguration_req *setconf_req = (void*) buf; + struct bt_setconfiguration_rsp *setconf_rsp = (void*) buf; + int err; + + err = bluetooth_a2dp_init(data, rate, channels); + if (err < 0) + return err; + + memset(setconf_req, 0, BT_AUDIO_IPC_PACKET_SIZE); + setconf_req->h.msg_type = BT_SETCONFIGURATION_REQ; + strncpy(setconf_req->device, data->address, 18); + setconf_req->transport = BT_CAPABILITIES_TRANSPORT_A2DP; + setconf_req->sbc_capabilities = a2dp->sbc_capabilities; + setconf_req->access_mode = BT_CAPABILITIES_ACCESS_MODE_WRITE; + + err = audioservice_send(data->server.fd, &setconf_req->h); + if (err < 0) + return err; + + err = audioservice_expect(data->server.fd, &rsp_hdr->msg_h, + BT_SETCONFIGURATION_RSP); + if (err < 0) + return err; + + if (rsp_hdr->posix_errno != 0) { + SNDERR("BT_SETCONFIGURATION failed : %s(%d)", + strerror(rsp_hdr->posix_errno), + rsp_hdr->posix_errno); + return -rsp_hdr->posix_errno; + } + + data->transport = setconf_rsp->transport; + data->link_mtu = setconf_rsp->link_mtu; + + /* Setup SBC encoder now we agree on parameters */ + bluetooth_a2dp_setup(a2dp); + + DBG("\tallocation=%u\n\tsubbands=%u\n\tblocks=%u\n\tbitpool=%u\n", + a2dp->sbc.allocation, a2dp->sbc.subbands, a2dp->sbc.blocks, + a2dp->sbc.bitpool); + + return 0; +} + + + +static int avdtp_write(struct bluetooth_data *data) +{ + int ret = 0; + struct rtp_header *header; + struct rtp_payload *payload; + struct bluetooth_a2dp *a2dp = &data->a2dp; + + header = (void *) a2dp->buffer; + payload = (void *) (a2dp->buffer + sizeof(*header)); + + memset(a2dp->buffer, 0, sizeof(*header) + sizeof(*payload)); + + payload->frame_count = a2dp->frame_count; + header->v = 2; + header->pt = 1; + header->sequence_number = htons(a2dp->seq_num); + header->timestamp = htonl(a2dp->nsamples); + header->ssrc = htonl(1); + +retry: + ret = send(data->stream.fd, a2dp->buffer, a2dp->count, MSG_DONTWAIT); + if (ret < 0) { + DBG("send returned %d errno %s.", ret, strerror(errno)); + ret = -errno; + if (ret == -EAGAIN) { + struct timespec tv; + DBG("retry"); + tv.tv_sec = 0; + tv.tv_nsec = 100 * 1000; + nanosleep(&tv, NULL); + goto retry; + } + } + + /* Reset buffer of data to send */ + a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload); + a2dp->frame_count = 0; + a2dp->samples = 0; + a2dp->seq_num++; + + return ret; +} + +static long bluetooth_a2dp_write(struct bluetooth_data *data, + const char* buffer, + long size) +{ + struct bluetooth_a2dp *a2dp = &data->a2dp; + long ret = 0; + long frames_to_read, frames_left = size; + int encoded, written; + const char *buff; + + while (frames_left > 0) { + + if ((data->count + frames_left) <= a2dp->codesize) + frames_to_read = frames_left; + else + frames_to_read = a2dp->codesize - data->count; + buff = buffer + ret; + + memcpy(data->buffer + data->count, buff, frames_to_read); + /* Remember we have some frames in the pipe now */ + data->count += frames_to_read; + if (data->count != a2dp->codesize) { + ret = frames_to_read; + goto done; + } + + /* Enough data to encode (sbc wants 1k blocks) */ + encoded = sbc_encode(&(a2dp->sbc), data->buffer, a2dp->codesize, + a2dp->buffer + a2dp->count, + sizeof(a2dp->buffer) - a2dp->count, + &written); + if (encoded <= 0) { + DBG("Encoding error %d", encoded); + goto done; + } + + data->count -= encoded; + a2dp->count += written; + a2dp->frame_count++; + a2dp->samples += encoded; + a2dp->nsamples += encoded; + + /* No space left for another frame then send */ + if (a2dp->count + written >= data->link_mtu) { + DBG("sending packet %d, count %d, link_mtu %u", + a2dp->seq_num, a2dp->count, + data->link_mtu); + avdtp_write(data); + } + + ret += frames_to_read; + frames_left -= frames_to_read; + } + + /* note: some ALSA apps will get confused otherwise */ + if (ret > size) + ret = size; + +done: + DBG("returning %ld", ret); + return ret; +} + + +static int audioservice_send(int sk, const bt_audio_msg_header_t *msg) +{ + int err; + + DBG("sending %s", bt_audio_strmsg(msg->msg_type)); + if (send(sk, msg, BT_AUDIO_IPC_PACKET_SIZE, 0) > 0) + err = 0; + else { + err = -errno; + SNDERR("Error sending data to audio service: %s(%d)", + strerror(errno), errno); + } + + return err; +} + +static int audioservice_recv(int sk, bt_audio_msg_header_t *inmsg) +{ + int err; + const char *type; + + DBG("trying to receive msg from audio service..."); + if (recv(sk, inmsg, BT_AUDIO_IPC_PACKET_SIZE, 0) > 0) { + type = bt_audio_strmsg(inmsg->msg_type); + if (type) { + DBG("Received %s", type); + err = 0; + } else { + err = -EINVAL; + SNDERR("Bogus message type %d " + "received from audio service", + inmsg->msg_type); + } + } else { + err = -errno; + SNDERR("Error receiving data from audio service: %s(%d)", + strerror(errno), errno); + } + + return err; +} + +static int audioservice_expect(int sk, bt_audio_msg_header_t *rsp_hdr, + int expected_type) +{ + int err = audioservice_recv(sk, rsp_hdr); + if (err == 0) { + if (rsp_hdr->msg_type != expected_type) { + err = -EINVAL; + SNDERR("Bogus message %s received while " + "%s was expected", + bt_audio_strmsg(rsp_hdr->msg_type), + bt_audio_strmsg(expected_type)); + } + } + return err; +} + +static int bluetooth_init(struct bluetooth_data *data) +{ + int sk, err; + char buf[BT_AUDIO_IPC_PACKET_SIZE]; + bt_audio_rsp_msg_header_t *rsp_hdr = (void*) buf; + struct bt_getcapabilities_req *getcaps_req = (void*) buf; + struct bt_getcapabilities_rsp *getcaps_rsp = (void*) buf; + + memset(data, 0, sizeof(struct bluetooth_data)); + + data->server.fd = -1; + data->stream.fd = -1; + + sk = bt_audio_service_open(); + if (sk <= 0) { + err = -errno; + goto failed; + } + + data->server.fd = sk; + data->server.events = POLLIN; + + memset(getcaps_req, 0, BT_AUDIO_IPC_PACKET_SIZE); + getcaps_req->h.msg_type = BT_GETCAPABILITIES_REQ; + getcaps_req->flags = 0; + getcaps_req->flags |= BT_FLAG_AUTOCONNECT; + strncpy(getcaps_req->device, data->address, 18); + getcaps_req->transport = BT_CAPABILITIES_TRANSPORT_A2DP; + + err = audioservice_send(data->server.fd, &getcaps_req->h); + if (err < 0) + goto failed; + + err = audioservice_expect(data->server.fd, &rsp_hdr->msg_h, BT_GETCAPABILITIES_RSP); + if (err < 0) + goto failed; + + if (rsp_hdr->posix_errno != 0) { + SNDERR("BT_GETCAPABILITIES failed : %s(%d)", + strerror(rsp_hdr->posix_errno), + rsp_hdr->posix_errno); + return -rsp_hdr->posix_errno; + } + + data->transport = getcaps_rsp->transport; + + if (getcaps_rsp->transport == BT_CAPABILITIES_TRANSPORT_A2DP) { + data->a2dp.sbc_capabilities = getcaps_rsp->sbc_capabilities; + } + + return 0; + +failed: + bt_audio_service_close(sk); + return err; +} + +int a2dp_init(const char* address, int rate, int channels, a2dpData* dataPtr) +{ + int err; + + *dataPtr = NULL; + struct bluetooth_data* data = malloc(sizeof(struct bluetooth_data)); + if (!data) + return -1; + + strncpy(data->address, address, 18); + + err = bluetooth_init(data); + if (err < 0) + goto error; + + err = bluetooth_a2dp_hw_params(data, rate, channels); + if (err < 0) { + printf("bluetooth_a2dp_hw_params failed"); + goto error; + } + + err = bluetooth_prepare(data); + if (err < 0) { + printf("bluetooth_prepare failed"); + goto error; + } + + *dataPtr = data; + return 0; + +error: + bluetooth_exit(data); + free(data); + + return err; +} + +int a2dp_write(a2dpData d, const void* buffer, int count) +{ + struct bluetooth_data* data = (struct bluetooth_data*)d; + return bluetooth_a2dp_write(data, buffer, count); +} + +void a2dp_cleanup(a2dpData d) +{ + struct bluetooth_data* data = (struct bluetooth_data*)d; + bluetooth_exit(data); + free(data); +} diff --git a/utils/audio/liba2dp.h b/utils/audio/liba2dp.h new file mode 100644 index 000000000..051551713 --- /dev/null +++ b/utils/audio/liba2dp.h @@ -0,0 +1,13 @@ +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* a2dpData; + +int a2dp_init(const char* address, int rate, int channels, a2dpData* dataPtr); +int a2dp_write(a2dpData data, const void* buffer, int count); +void a2dp_cleanup(a2dpData data); + +#ifdef __cplusplus +} +#endif diff --git a/utils/common/Android.mk b/utils/common/Android.mk index d1b91bd6a..eba86d1f2 100644 --- a/utils/common/Android.mk +++ b/utils/common/Android.mk @@ -11,22 +11,16 @@ LOCAL_SRC_FILES:= \ textfile.c \ android_bluez.c +LOCAL_CFLAGS+= \ + -O3 \ + -DNEED_DBUS_WATCH_GET_UNIX_FD + LOCAL_C_INCLUDES:= \ - $(LOCAL_PATH) \ $(call include-path-for, bluez-libs) \ - $(call include-path-for, bluez-utils)/eglib/ \ - $(call include-path-for, bluez-utils)/gdbus/ \ - external/expat/lib/ \ + $(call include-path-for, bluez-utils)/eglib \ + $(call include-path-for, bluez-utils)/gdbus \ $(call include-path-for, dbus) -LOCAL_STATIC_LIBRARIES := \ - libeglib_static \ - libgdbus_static - LOCAL_MODULE:=libbluez-utils-common-static -LOCAL_CFLAGS+= \ - -O3 \ - -DNEED_DBUS_WATCH_GET_UNIX_FD - include $(BUILD_STATIC_LIBRARY) diff --git a/utils/dund/Android.mk b/utils/dund/Android.mk index e8aa86162..04a0f0205 100644 --- a/utils/dund/Android.mk +++ b/utils/dund/Android.mk @@ -1,29 +1,25 @@ LOCAL_PATH:= $(call my-dir) -# -# hcid -# - include $(CLEAR_VARS) -LOCAL_C_INCLUDES:= \ - $(call include-path-for, bluez-libs) \ - $(call include-path-for, dbus) \ - $(call include-path-for, bluez-utils)/common +LOCAL_SRC_FILES:= \ + dun.c \ + main.c \ + msdun.c \ + sdp.c LOCAL_CFLAGS:= \ -DVERSION=\"3.36\" \ - -DSTORAGEDIR=\"/data\" \ - -DCONFIGDIR=\"/etc\" \ + -DSTORAGEDIR=\"/data/misc/hcid\" \ + -DCONFIGDIR=\"/etc/bluez\" -LOCAL_SRC_FILES:= \ - dun.c \ - main.c \ - msdun.c \ - sdp.c +LOCAL_C_INCLUDES:= \ + $(call include-path-for, bluez-libs) \ + $(call include-path-for, bluez-utils)/common \ + $(call include-path-for, dbus) LOCAL_SHARED_LIBRARIES := \ - libbluetooth + libbluetooth LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng diff --git a/utils/eglib/Android.mk b/utils/eglib/Android.mk index af1320257..8e219ffe6 100644 --- a/utils/eglib/Android.mk +++ b/utils/eglib/Android.mk @@ -5,11 +5,8 @@ LOCAL_SRC_FILES:= \ gmain.c \ gmodule.c -LOCAL_C_INCLUDES:= \ - $(LOCAL_PATH) +LOCAL_CFLAGS+=-O3 LOCAL_MODULE:=libeglib_static -LOCAL_CFLAGS+=-O3 - include $(BUILD_STATIC_LIBRARY) diff --git a/utils/gdbus/Android.mk b/utils/gdbus/Android.mk index 315688530..b6c4129aa 100644 --- a/utils/gdbus/Android.mk +++ b/utils/gdbus/Android.mk @@ -4,23 +4,18 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ mainloop.c object.c watch.c +LOCAL_CFLAGS+=-O3 -DNEED_DBUS_WATCH_GET_UNIX_FD + LOCAL_C_INCLUDES:= \ $(call include-path-for, bluez-libs) \ - $(call include-path-for, dbus) \ - $(call include-path-for, bluez-utils)/common/ \ - $(call include-path-for, bluez-utils)/eglib/ \ - $(LOCAL_PATH) + $(call include-path-for, bluez-utils)/eglib \ + $(call include-path-for, bluez-utils)/common \ + $(call include-path-for, dbus) LOCAL_SHARED_LIBRARIES := \ libbluetooth \ libdbus -LOCAL_STATIC_LIBRARIES := \ - libeglib_static \ - libbluez-utils-common-static - LOCAL_MODULE:=libgdbus_static -LOCAL_CFLAGS+=-O3 -DNEED_DBUS_WATCH_GET_UNIX_FD - include $(BUILD_STATIC_LIBRARY) diff --git a/utils/hcid/Android.mk b/utils/hcid/Android.mk index 772ff591b..a08f26cfe 100644 --- a/utils/hcid/Android.mk +++ b/utils/hcid/Android.mk @@ -1,31 +1,15 @@ LOCAL_PATH:= $(call my-dir) # -# hcid +# libhcid # include $(CLEAR_VARS) -LOCAL_C_INCLUDES:= \ - $(call include-path-for, bluez-libs) \ - $(call include-path-for, dbus) \ - $(call include-path-for, bluez-utils)/common/ \ - $(call include-path-for, bluez-utils)/eglib/ \ - $(call include-path-for, bluez-utils)/gdbus/ \ - $(call include-path-for, bluez-utils)/sdpd/ - -LOCAL_CFLAGS:= \ - -DVERSION=\"3.36\" \ - -DSTORAGEDIR=\"/data/misc/hcid\" \ - -DCONFIGDIR=\"/etc\" \ - -DSERVICEDIR=\"/system/bin\" \ - -DPLUGINDIR=\"\" \ - -DANDROID_SET_AID_AND_CAP \ - -DANDROID_EXPAND_NAME - LOCAL_SRC_FILES:= \ adapter.c \ agent.c \ + device.c \ dbus-common.c \ dbus-database.c \ dbus-error.c \ @@ -33,7 +17,6 @@ LOCAL_SRC_FILES:= \ dbus-sdp.c \ dbus-security.c \ dbus-service.c \ - device.c \ kword.c \ lexer.c \ main.c \ @@ -44,10 +27,27 @@ LOCAL_SRC_FILES:= \ storage.c \ plugin.c +LOCAL_CFLAGS:= \ + -DVERSION=\"3.36\" \ + -DSTORAGEDIR=\"/data/misc/hcid\" \ + -DCONFIGDIR=\"/etc/bluez\" \ + -DSERVICEDIR=\"/system/bin\" \ + -DPLUGINDIR=\"/system/lib/bluez-plugin\" \ + -DANDROID_SET_AID_AND_CAP \ + -DANDROID_EXPAND_NAME + +LOCAL_C_INCLUDES:= \ + $(call include-path-for, bluez-libs) \ + $(call include-path-for, bluez-utils)/common \ + $(call include-path-for, bluez-utils)/eglib \ + $(call include-path-for, bluez-utils)/gdbus \ + $(call include-path-for, bluez-utils)/sdpd \ + $(call include-path-for, dbus) + LOCAL_SHARED_LIBRARIES := \ + libdl \ libbluetooth \ libdbus \ - libexpat \ libcutils LOCAL_STATIC_LIBRARIES := \ @@ -56,6 +56,19 @@ LOCAL_STATIC_LIBRARIES := \ libgdbus_static \ libbluez-utils-common-static +LOCAL_MODULE:=libhcid + +include $(BUILD_SHARED_LIBRARY) + +# +# hcid +# + +include $(CLEAR_VARS) + +LOCAL_SHARED_LIBRARIES := \ + libhcid + LOCAL_MODULE:=hcid include $(BUILD_EXECUTABLE) diff --git a/utils/hcid/main.c b/utils/hcid/main.c index 77b3912ff..ef9759edf 100644 --- a/utils/hcid/main.c +++ b/utils/hcid/main.c @@ -960,9 +960,7 @@ int main(int argc, char *argv[]) * the plugins might wanna expose some paths on the bus. However the * best order of how to init various subsystems of the Bluetooth * daemon needs to be re-worked. */ -#if 0 plugin_init(config); -#endif init_security_data(); @@ -982,9 +980,7 @@ int main(int argc, char *argv[]) hcid_dbus_unregister(); -#if 0 plugin_cleanup(); -#endif stop_sdp_server(); diff --git a/utils/input/Android.mk b/utils/input/Android.mk new file mode 100644 index 000000000..8b91c4539 --- /dev/null +++ b/utils/input/Android.mk @@ -0,0 +1,39 @@ +LOCAL_PATH:= $(call my-dir) + +# HID plugin + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + device.c \ + fakehid.c \ + main.c \ + manager.c \ + server.c \ + storage.c + +LOCAL_CFLAGS:= \ + -DVERSION=\"3.36\" \ + -DSTORAGEDIR=\"/data/misc/hcid\" \ + -DCONFIGDIR=\"/etc/bluez\" + +LOCAL_C_INCLUDES:= \ + $(call include-path-for, bluez-libs) \ + $(call include-path-for, bluez-utils)/common \ + $(call include-path-for, bluez-utils)/eglib \ + $(call include-path-for, bluez-utils)/hcid \ + $(call include-path-for, bluez-utils)/gdbus \ + $(call include-path-for, dbus) + +LOCAL_SHARED_LIBRARIES := \ + libhcid \ + libbluetooth \ + libdbus \ + libexpat \ + libcutils + +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/bluez-plugin +LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)/bluez-plugin +LOCAL_MODULE := input + +include $(BUILD_SHARED_LIBRARY) diff --git a/utils/input/manager.c b/utils/input/manager.c index 2dfb9b2d3..1b1608161 100644 --- a/utils/input/manager.c +++ b/utils/input/manager.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/utils/rfcomm/Android.mk b/utils/rfcomm/Android.mk index dc4b7b35d..c73000a03 100644 --- a/utils/rfcomm/Android.mk +++ b/utils/rfcomm/Android.mk @@ -1,25 +1,26 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_C_INCLUDES:= \ - $(call include-path-for, bluez-libs) \ - $(call include-path-for, bluez-utils)/common - -LOCAL_CFLAGS:= \ - -DVERSION=\"3.36\" -DCONFIGDIR=\"/etc\" \ - -DNEED_PPOLL - LOCAL_SRC_FILES:= \ kword.c \ lexer.c \ main.c \ - parser.c + parser.c + +LOCAL_CFLAGS:= \ + -DVERSION=\"3.36\" \ + -DCONFIGDIR=\"/etc/bluez\" \ + -DNEED_PPOLL + +LOCAL_C_INCLUDES:= \ + $(call include-path-for, bluez-libs) \ + $(call include-path-for, bluez-utils)/common LOCAL_SHARED_LIBRARIES := \ libbluetooth LOCAL_STATIC_LIBRARIES := \ - libbluez-utils-common-static + libbluez-utils-common-static LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng diff --git a/utils/sbc/sbc.c.arm b/utils/sbc/sbc.c.arm new file mode 100644 index 000000000..dd1c0b845 --- /dev/null +++ b/utils/sbc/sbc.c.arm @@ -0,0 +1,3 @@ +/* Hack to force sbc.c to be compiled as ARM */ + +#include "sbc.c" diff --git a/utils/sdpd/Android.mk b/utils/sdpd/Android.mk index b81ca0e30..23129c4e0 100644 --- a/utils/sdpd/Android.mk +++ b/utils/sdpd/Android.mk @@ -6,13 +6,6 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_C_INCLUDES:= \ - $(call include-path-for, bluez-libs) \ - $(call include-path-for, bluez-utils)/common/ \ - $(call include-path-for, bluez-utils)/eglib/ - -LOCAL_CFLAGS:=-DVERSION=\"3.36\" - LOCAL_SRC_FILES:= \ cstate.c \ request.c \ @@ -20,6 +13,13 @@ LOCAL_SRC_FILES:= \ server.c \ servicedb.c +LOCAL_CFLAGS:=-DVERSION=\"3.36\" + +LOCAL_C_INCLUDES:= \ + $(call include-path-for, bluez-libs) \ + $(call include-path-for, bluez-utils)/common \ + $(call include-path-for, bluez-utils)/eglib + LOCAL_MODULE:=libsdpserver_static include $(BUILD_STATIC_LIBRARY) diff --git a/utils/tools/Android.mk b/utils/tools/Android.mk index 6b027052b..5e70ddecf 100644 --- a/utils/tools/Android.mk +++ b/utils/tools/Android.mk @@ -1,8 +1,3 @@ -BUILD_HCICONFIG:=1 -BUILD_HCITOOL:=1 -BUILD_L2PING:=1 -BUILD_HCIATTACH:=1 - LOCAL_PATH:= $(call my-dir) # @@ -11,18 +6,18 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_SRC_FILES:= \ + sdptool.c + LOCAL_C_INCLUDES:= \ $(call include-path-for, bluez-libs) \ - $(call include-path-for, bluez-utils)/common/ + $(call include-path-for, bluez-utils)/common/ LOCAL_CFLAGS:= \ -DVERSION=\"3.36\" -fpermissive -LOCAL_SRC_FILES:= \ - sdptool.c - LOCAL_SHARED_LIBRARIES := \ - libbluetooth + libbluetooth LOCAL_STATIC_LIBRARIES := \ libbluez-utils-common-static @@ -31,14 +26,17 @@ LOCAL_MODULE:=sdptool include $(BUILD_EXECUTABLE) -ifeq ($(BUILD_HCICONFIG),1) - # -# hciconfig +# hciconfig # include $(CLEAR_VARS) +LOCAL_SRC_FILES:= \ + csr.c \ + csr_h4.c \ + hciconfig.c + LOCAL_C_INCLUDES:= \ $(call include-path-for, bluez-libs) \ $(call include-path-for, bluez-utils)/common/ @@ -47,34 +45,27 @@ LOCAL_CFLAGS:= \ -DSTORAGEDIR=\"/tmp\" \ -DVERSION=\"3.36\" -LOCAL_SRC_FILES:= \ - csr.c \ - csr_h4.c \ - hciconfig.c - LOCAL_SHARED_LIBRARIES := \ - libbluetooth + libbluetooth LOCAL_STATIC_LIBRARIES := \ libbluez-utils-common-static LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng - LOCAL_MODULE:=hciconfig include $(BUILD_EXECUTABLE) -endif # BUILD_HCICONFIG - -ifeq ($(BUILD_HCITOOL),1) - # -# hcitool +# hcitool # include $(CLEAR_VARS) +LOCAL_SRC_FILES:= \ + hcitool.c + LOCAL_C_INCLUDES:= \ $(call include-path-for, bluez-libs) \ $(call include-path-for, bluez-utils)/common/ @@ -83,9 +74,6 @@ LOCAL_CFLAGS:= \ -DSTORAGEDIR=\"/tmp\" \ -DVERSION=\"3.36\" -LOCAL_SRC_FILES:= \ - hcitool.c - LOCAL_SHARED_LIBRARIES := \ libbluetooth @@ -94,17 +82,12 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng - LOCAL_MODULE:=hcitool include $(BUILD_EXECUTABLE) -endif # hcitool - -ifeq ($(BUILD_L2PING),1) - # -# l2ping +# l2ping # include $(CLEAR_VARS) @@ -116,7 +99,7 @@ LOCAL_SRC_FILES:= \ l2ping.c LOCAL_SHARED_LIBRARIES := \ - libbluetooth + libbluetooth LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := eng @@ -124,32 +107,27 @@ LOCAL_MODULE:=l2ping include $(BUILD_EXECUTABLE) -endif # l2ping - - # # hciattach # -ifeq ($(BUILD_HCIATTACH),1) - include $(CLEAR_VARS) +LOCAL_SRC_FILES:= \ + hciattach.c \ + hciattach_st.c \ + hciattach_tialt.c + LOCAL_C_INCLUDES:= \ $(call include-path-for, bluez-libs) \ - $(call include-path-for, bluez-utils)/common/ + $(call include-path-for, bluez-utils)/common/ LOCAL_CFLAGS:= \ -DVERSION=\"3.36\" \ - -D__BSD_VISIBLE=1 - -LOCAL_SRC_FILES:= \ - hciattach.c \ - hciattach_st.c \ - hciattach_tialt.c + -D__BSD_VISIBLE=1 LOCAL_SHARED_LIBRARIES := \ - libbluetooth + libbluetooth LOCAL_STATIC_LIBRARIES := \ libbluez-utils-common-static @@ -157,5 +135,3 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_MODULE:=hciattach include $(BUILD_EXECUTABLE) - -endif # hciattach diff --git a/utils/tools/hciattach.c b/utils/tools/hciattach.c index c373607ad..d4f8b153a 100644 --- a/utils/tools/hciattach.c +++ b/utils/tools/hciattach.c @@ -146,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)); @@ -347,7 +347,7 @@ static int texas(int fd, struct uart_t *u, struct termios *ti) extern int texasalt_init(int fd, int speed); int texasalt(int fd, struct uart_t *u, struct termios *ti) { - texasalt_init(fd, u->speed); + return texasalt_init(fd, u->speed); } static int read_check(int fd, void *buf, int count) @@ -1230,7 +1230,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 = 5; int init_speed = 0; int send_break = 0; pid_t pid; diff --git a/utils/tools/hciattach_tialt.c b/utils/tools/hciattach_tialt.c index 34e27bfff..4df91f658 100644 --- a/utils/tools/hciattach_tialt.c +++ b/utils/tools/hciattach_tialt.c @@ -26,13 +26,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include #include @@ -61,16 +61,17 @@ typedef struct { } __attribute__((packed)) command_complete_t; extern int read_hci_event(int fd, unsigned char* buf, int size); +extern int set_speed(int fd, struct termios *ti, int speed); -static int read_command_complete(int fd, unsigned short opcode, unsigned char len) { +static int read_command_complete(int fd, uint16_t opcode) { command_complete_t resp; /* Read reply. */ - FAILIF(read_hci_event(fd, (char *)&resp, sizeof(resp)) < 0, - "Failed to read response"); + FAILIF(read_hci_event(fd, (unsigned char *)&resp, sizeof(resp)) < 0, + "Failed to read response for opcode %#04x\n", opcode); /* Parse speed-change reply */ FAILIF(resp.uart_prefix != HCI_EVENT_PKT, - "Error in response: not an event packet, but 0x%02x!\n", + "Error in response: not an event packet, but %#02X!\n", resp.uart_prefix); FAILIF(resp.hci_hdr.evt != EVT_CMD_COMPLETE, /* event must be event-complete */ @@ -78,14 +79,18 @@ static int read_command_complete(int fd, unsigned short opcode, unsigned char le "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", + "Error in response: plen is not >= 4, but %#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!", + "Error in response: opcode is %#04X, not %#04X!", resp.cmd_complete.opcode, opcode); + FAILIF(resp.status != 0, + "Error in response: status is %x for opcode %#04x\n", resp.status, + opcode); + return resp.status == 0 ? 0 : -1; } @@ -95,12 +100,9 @@ typedef struct { uint32_t speed; } __attribute__((packed)) texas_speed_change_cmd_t; -static int texas_change_speed(int fd, uint32_t speed) { - - return 0; +static int texas_change_speed(int fd, struct termios *ti, uint32_t speed) { /* Send a speed-change request */ - texas_speed_change_cmd_t cmd; int n; @@ -109,18 +111,13 @@ static int texas_change_speed(int fd, uint32_t speed) { cmd.hci_hdr.plen = sizeof(uint32_t); cmd.speed = speed; - fprintf(stdout, "Setting speed to %d\n", speed); + printf("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); @@ -128,66 +125,60 @@ static int texas_change_speed(int fd, uint32_t speed) { } /* Parse speed-change reply */ - if (read_command_complete(fd, 0xff36, 4) < 0) { + if (read_command_complete(fd, 0xff36) < 0) { + return -1; + } + + if (set_speed(fd, ti, speed) < 0) { + perror("Can't set baud rate"); return -1; } - fprintf(stdout, "Speed changed to %d.\n", speed); + + printf("Texas speed changed to %d.\n", speed); + return 0; } static int texas_load_firmware(int fd, const char *firmware) { + int fw; - 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", + printf("Loading firmware from %s...\n", firmware); + 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) { + while (1) { + unsigned char cmd[1024]; + hci_command_hdr *hci_cmd; + unsigned int n; + + /* read in H4 packets from firmware file */ + n = read(fw, cmd, sizeof(hci_command_hdr) + 1); + if (!n) break; + FAILIF(n != sizeof(hci_command_hdr) + 1, + "Could not read H4 + HCI header!\n"); + FAILIF(cmd[0] != HCI_COMMAND_PKT, + "Command is not an H4 command packet!\n"); + hci_cmd = (hci_command_hdr *)&cmd[1]; + + FAILIF(read(fw, &cmd[sizeof(hci_command_hdr) + 1], hci_cmd->plen) + != hci_cmd->plen, + "Could not read %d bytes of data for opcode %#04X!\n", + hci_cmd->plen, hci_cmd->opcode); + + /* write h4 packet to chip */ +// printf("opcode %#04X (%d bytes data)\n", hci_cmd->opcode, hci_cmd->plen); + n = write(fd, cmd, sizeof(hci_command_hdr) + 1 + hci_cmd->plen); + FAILIF(n != sizeof(hci_command_hdr) + 1 + hci_cmd->plen, + "Could not send entire command (sent only %d bytes)!\n", + n); + if (read_command_complete(fd, hci_cmd->opcode) < 0) { return -1; } - - } while(1); - fprintf(stdout, "Firmware upload successful.\n"); - + } close(fw); + + printf("Firmware load successful.\n"); + return 0; } @@ -195,12 +186,12 @@ int texasalt_init(int fd, int speed, struct termios *ti) { struct timespec tm = {0, 50000}; char cmd[4]; - unsigned char resp[100]; /* Response */ + unsigned char resp[100]; /* Response */ int n; memset(resp,'\0', 100); - /* It is possible to get software version with manufacturer specific + /* 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 */ @@ -235,12 +226,12 @@ int texasalt_init(int fd, int speed, struct termios *ti) 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); + fprintf(stderr, "Texas module LMP version : %#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; + uint16_t lmp_subv = resp[13] | (resp[14] << 8); + uint16_t brf_chip = (lmp_subv & 0x7c00) >> 10; static const char *c_brf_chip[5] = { "unknown", "unknown", @@ -249,7 +240,7 @@ int texasalt_init(int fd, int speed, struct termios *ti) "brf6300" }; - fprintf(stderr, "Texas module LMP sub-version : 0x%04x\n", lmp_subv); + fprintf(stderr, "Texas module LMP sub-version : %#04X\n", lmp_subv); fprintf(stderr, "\tinternal version freeze: %d\n" @@ -262,9 +253,10 @@ int texasalt_init(int fd, int speed, struct termios *ti) char fw[100]; sprintf(fw, "/etc/firmware/%s.bin", c_brf_chip[brf_chip]); - texas_load_firmware(fd, fw); - texas_change_speed(fd, speed); + texas_change_speed(fd, ti, speed); + + texas_load_firmware(fd, fw); } nanosleep(&tm, NULL); return 0; diff --git a/utils/tools/l2ping.c b/utils/tools/l2ping.c index 1e2aab6d1..4229de754 100644 --- a/utils/tools/l2ping.c +++ b/utils/tools/l2ping.c @@ -232,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] [-r] \n"); + printf("\tl2ping [-i device] [-s size] [-c count] [-t timeout] [-d delay] [-f] [-r] \n"); } int main(int argc, char *argv[]) @@ -242,7 +242,7 @@ int main(int argc, char *argv[]) /* Default options */ bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"i:s:c:t:fr")) != EOF) { + while ((opt=getopt(argc,argv,"i:d:s:c:t:fr")) != EOF) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -251,6 +251,10 @@ int main(int argc, char *argv[]) str2ba(optarg, &bdaddr); break; + case 'd': + delay = atoi(optarg); + break; + case 'f': /* Kinda flood ping */ delay = 0; diff --git a/utils/tools/sdptool.c b/utils/tools/sdptool.c index 712c62b6b..9c54ca036 100644 --- a/utils/tools/sdptool.c +++ b/utils/tools/sdptool.c @@ -1478,7 +1478,8 @@ static int add_headset_ag(sdp_session_t *session, svc_info_t *si) sdp_list_t *aproto, *proto[2]; sdp_record_t record; uint8_t u8 = si->channel ? si->channel : 7; - uint16_t u16 = 0x17; + /* Set the bits for the supported features in the SDP records */ + uint16_t u16 = 0x07; 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); @@ -1614,7 +1615,8 @@ static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) sdp_list_t *aproto, *proto[2]; sdp_record_t record; uint8_t u8 = si->channel ? si->channel : 7; - uint16_t u16 = 0x17; + /* Set bits for supported features. */ + uint16_t u16 = 0x07; 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); -- 2.11.0