Merge branch 'honeycomb_branch' into tmp1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..62a4201
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+*.o
+.deps
+.dirstamp
+Makefile
+Makefile.in
+aclocal.m4
+config.h
+config.h.in
+config.log
+config.status
+configure
+depcomp
+compile
+install-sh
+missing
+stamp-h1
+autom4te.cache
+
+src/hcidump
+src/bpasniff
+src/csrsniff
diff --git a/Android.mk b/Android.mk
index 276b043..661ebba 100755
--- a/Android.mk
+++ b/Android.mk
@@ -8,9 +8,10 @@
$(call include-path-for,bluez)/lib/ \
LOCAL_CFLAGS:= \
- -DVERSION=\"1.42\"
+ -DVERSION=\"2.0\"
LOCAL_SRC_FILES:= \
+ parser/att.c \
parser/avctp.c \
parser/avdtp.c \
parser/bnep.c \
diff --git a/ChangeLog b/ChangeLog
index 198c46b..9b975bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+ver 2.0:
+ Add support for decoding AMP events.
+ Add support for decoding AMP commands.
+ Add support for decoding LE advertising reports.
+ Add support for L2CAP fixed channel information.
+ Add support for L2CAP ERTM and Streaming Mode.
+ Make BT-Snoop format the default file format.
+ Make verbose parsing the default option.
+
ver 1.42:
Decode the Read Link Policy Settings command.
Decode Default Link Policy Settings commands
diff --git a/Makefile.am b/Makefile.am
index ee3bba3..99dd422 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,48 @@
-SUBDIRS = parser src
+AM_MAKEFLAGS = --no-print-directory
+
+parser_sources = parser/parser.h parser/parser.c \
+ parser/lmp.c \
+ parser/hci.c \
+ parser/l2cap.c \
+ parser/att.c \
+ parser/sdp.h parser/sdp.c \
+ parser/rfcomm.h parser/rfcomm.c \
+ parser/bnep.c \
+ parser/cmtp.c \
+ parser/hidp.c \
+ parser/hcrp.c \
+ parser/avdtp.c \
+ parser/avctp.c \
+ parser/obex.c \
+ parser/capi.c \
+ parser/ppp.c \
+ parser/tcpip.c \
+ parser/ericsson.c \
+ parser/csr.c \
+ parser/bpa.c
+
+
+sbin_PROGRAMS = src/hcidump
+
+src_hcidump_SOURCES = src/hcidump.c $(parser_sources)
+src_hcidump_LDADD = @BLUEZ_LIBS@
+
+
+noinst_PROGRAMS = src/bpasniff src/csrsniff
+
+src_bpasniff_SOURCES = src/bpasniff.c $(parser_sources)
+src_bpasniff_LDADD = @BLUEZ_LIBS@
+
+src_csrsniff_SOURCES = src/csrsniff.c $(parser_sources)
+src_csrsniff_LDADD = @BLUEZ_LIBS@
+
+
+AM_CFLAGS = @BLUEZ_CFLAGS@
+
+dist_man_MANS = src/hcidump.8
+
+EXTRA_DIST = src/magic.btsnoop
MAINTAINERCLEANFILES = Makefile.in \
aclocal.m4 configure config.h.in \
diff --git a/README b/README
index 46b411e..68fb17d 100644
--- a/README
+++ b/README
@@ -2,7 +2,7 @@
******************************************
Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
-Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
Bluetooth packet analyzer
@@ -16,8 +16,8 @@
To configure run:
./configure --prefix=/usr --mandir=/usr/share/man
-
-Configure automatically searches for all required components and packages.
+
+Configure automatically searches for all required components and packages.
To compile and install run:
make && make install
@@ -27,8 +27,7 @@
===========
Mailing lists:
- bluez-users@lists.sf.net - BlueZ general questions and discussions
- bluez-devel@lists.sf.net - BlueZ development
+ linux-bluetooth@vger.kernel.org
For additional information about the project visit BlueZ web site:
http://www.bluez.org
diff --git a/acinclude.m4 b/acinclude.m4
index fa328e4..a2d0d4f 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -10,73 +10,17 @@
])
])
-AC_DEFUN([AC_INIT_BLUEZ], [
- AC_PREFIX_DEFAULT(/usr/local)
-
+AC_DEFUN([COMPILER_FLAGS], [
if (test "${CFLAGS}" = ""); then
- CFLAGS="-Wall -O2"
+ CFLAGS="-Wall -O2 -D_FORTIFY_SOURCE=2"
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], [
- debug_enable=no
- fortify_enable=yes
- pie_enable=yes
-
- AC_ARG_ENABLE(fortify, AC_HELP_STRING([--disable-fortify], [disable compile time buffer checks]), [
- fortify_enable=${enableval}
- ])
-
- AC_ARG_ENABLE(pie, AC_HELP_STRING([--disable-pie], [enable position independent executables flag]), [
- pie_enable=${enableval}
- ])
-
- AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [
- debug_enable=${enableval}
- ])
-
- if (test "${fortify_enable}" = "yes"); then
- CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2"
- fi
-
- if (test "${pie_enable}" = "yes" && test "${ac_cv_prog_cc_pie}" = "yes"); then
- CFLAGS="$CFLAGS -fPIE"
- LDFLAGS="$LDFLAGS -pie"
- fi
-
- if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then
- CFLAGS="$CFLAGS -g -O0"
+ if (test "$USE_MAINTAINER_MODE" = "yes"); then
+ CFLAGS+=" -Wextra"
+ CFLAGS+=" -Wno-unused-parameter"
+ CFLAGS+=" -Wno-missing-field-initializers"
+ CFLAGS+=" -Wdeclaration-after-statement"
+ CFLAGS+=" -Wmissing-declarations"
+ CFLAGS+=" -Wredundant-decls"
+ CFLAGS+=" -Wcast-align"
fi
])
diff --git a/bootstrap-configure b/bootstrap-configure
index 44e7ee8..5b7b88f 100755
--- a/bootstrap-configure
+++ b/bootstrap-configure
@@ -8,4 +8,4 @@
./configure --enable-maintainer-mode \
--enable-debug \
--prefix=/usr \
- --mandir=/usr/share/man
+ --mandir=/usr/share/man $*
diff --git a/configure.in b/configure.in
index 963e201..86e9652 100644
--- a/configure.in
+++ b/configure.in
@@ -1,22 +1,41 @@
-AC_PREREQ(2.50)
-AC_INIT()
+AC_PREREQ(2.60)
+AC_INIT(bluez-hcidump, 2.0)
-AM_INIT_AUTOMAKE(bluez-hcidump, 1.42)
+AM_INIT_AUTOMAKE([foreign subdir-objects])
AM_CONFIG_HEADER(config.h)
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
AM_MAINTAINER_MODE
-AC_INIT_BLUEZ
+AC_PREFIX_DEFAULT(/usr/local)
+
+COMPILER_FLAGS
AC_LANG_C
AC_PROG_CC
AC_PROG_CC_PIE
AC_PROG_INSTALL
-AC_PROG_RANLIB
-AC_PATH_BLUEZ
+PKG_CHECK_MODULES(BLUEZ, bluez, dummy=yes,
+ AC_MSG_ERROR(libbluetooth is required))
+AC_SUBST(BLUEZ_CFLAGS)
+AC_SUBST(BLUEZ_LIBS)
-AC_ARG_BLUEZ
+AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization],
+ [disable code optimization through compiler]), [
+ if (test "${enableval}" = "no"); then
+ CFLAGS="$CFLAGS -O0"
+ fi
+])
-AC_OUTPUT(Makefile src/Makefile parser/Makefile)
+AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],
+ [enable compiling with debugging information]), [
+ if (test "${enableval}" = "yes" &&
+ test "${ac_cv_prog_cc_g}" = "yes"); then
+ CFLAGS="$CFLAGS -g"
+ fi
+])
+
+AC_OUTPUT(Makefile)
diff --git a/parser/Makefile.am b/parser/Makefile.am
deleted file mode 100644
index cfaa048..0000000
--- a/parser/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-
-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/parser/att.c b/parser/att.c
new file mode 100644
index 0000000..a0fb135
--- /dev/null
+++ b/parser/att.c
@@ -0,0 +1,448 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 André Dieb Martins <andre.dieb@gmail.com>
+ *
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "parser.h"
+
+#define GATT_PRIM_SVC_UUID 0x2800
+#define GATT_SND_SVC_UUID 0x2801
+#define GATT_INCLUDE_UUID 0x2802
+#define GATT_CHARAC_UUID 0x2803
+
+#define GATT_CHARAC_DEVICE_NAME 0x2A00
+#define GATT_CHARAC_APPEARANCE 0x2A01
+#define GATT_CHARAC_PERIPHERAL_PRIV_FLAG 0x2A02
+#define GATT_CHARAC_RECONNECTION_ADDRESS 0x2A03
+#define GATT_CHARAC_PERIPHERAL_PREF_CONN 0x2A04
+#define GATT_CHARAC_SERVICE_CHANGED 0x2A05
+
+#define GATT_CHARAC_EXT_PROPER_UUID 0x2900
+#define GATT_CHARAC_USER_DESC_UUID 0x2901
+#define GATT_CLIENT_CHARAC_CFG_UUID 0x2902
+#define GATT_SERVER_CHARAC_CFG_UUID 0x2903
+#define GATT_CHARAC_FMT_UUID 0x2904
+#define GATT_CHARAC_AGREG_FMT_UUID 0x2905
+
+
+
+/* Attribute Protocol Opcodes */
+#define ATT_OP_ERROR 0x01
+#define ATT_OP_MTU_REQ 0x02
+#define ATT_OP_MTU_RESP 0x03
+#define ATT_OP_FIND_INFO_REQ 0x04
+#define ATT_OP_FIND_INFO_RESP 0x05
+#define ATT_OP_FIND_BY_TYPE_REQ 0x06
+#define ATT_OP_FIND_BY_TYPE_RESP 0x07
+#define ATT_OP_READ_BY_TYPE_REQ 0x08
+#define ATT_OP_READ_BY_TYPE_RESP 0x09
+#define ATT_OP_READ_REQ 0x0A
+#define ATT_OP_READ_RESP 0x0B
+#define ATT_OP_READ_BLOB_REQ 0x0C
+#define ATT_OP_READ_BLOB_RESP 0x0D
+#define ATT_OP_READ_MULTI_REQ 0x0E
+#define ATT_OP_READ_MULTI_RESP 0x0F
+#define ATT_OP_READ_BY_GROUP_REQ 0x10
+#define ATT_OP_READ_BY_GROUP_RESP 0x11
+#define ATT_OP_WRITE_REQ 0x12
+#define ATT_OP_WRITE_RESP 0x13
+#define ATT_OP_WRITE_CMD 0x52
+#define ATT_OP_PREP_WRITE_REQ 0x16
+#define ATT_OP_PREP_WRITE_RESP 0x17
+#define ATT_OP_EXEC_WRITE_REQ 0x18
+#define ATT_OP_EXEC_WRITE_RESP 0x19
+#define ATT_OP_HANDLE_NOTIFY 0x1B
+#define ATT_OP_HANDLE_IND 0x1D
+#define ATT_OP_HANDLE_CNF 0x1E
+#define ATT_OP_SIGNED_WRITE_CMD 0xD2
+
+/* Error codes for Error response PDU */
+#define ATT_ECODE_INVALID_HANDLE 0x01
+#define ATT_ECODE_READ_NOT_PERM 0x02
+#define ATT_ECODE_WRITE_NOT_PERM 0x03
+#define ATT_ECODE_INVALID_PDU 0x04
+#define ATT_ECODE_INSUFF_AUTHEN 0x05
+#define ATT_ECODE_REQ_NOT_SUPP 0x06
+#define ATT_ECODE_INVALID_OFFSET 0x07
+#define ATT_ECODE_INSUFF_AUTHO 0x08
+#define ATT_ECODE_PREP_QUEUE_FULL 0x09
+#define ATT_ECODE_ATTR_NOT_FOUND 0x0A
+#define ATT_ECODE_ATTR_NOT_LONG 0x0B
+#define ATT_ECODE_INSUFF_ENCR_KEY_SIZE 0x0C
+#define ATT_ECODE_INVAL_ATTR_VALUE_LEN 0x0D
+#define ATT_ECODE_UNLIKELY 0x0E
+#define ATT_ECODE_INSUFF_ENC 0x0F
+#define ATT_ECODE_UNSUPP_GRP_TYPE 0x10
+#define ATT_ECODE_INSUFF_RESOURCES 0x11
+#define ATT_ECODE_IO 0xFF
+
+
+/* Attribute Protocol Opcodes */
+static const char *attop2str(uint8_t op)
+{
+ switch (op) {
+ case ATT_OP_ERROR:
+ return "Error";
+ case ATT_OP_MTU_REQ:
+ return "MTU req";
+ case ATT_OP_MTU_RESP:
+ return "MTU resp";
+ case ATT_OP_FIND_INFO_REQ:
+ return "Find Information req";
+ case ATT_OP_FIND_INFO_RESP:
+ return "Find Information resp";
+ case ATT_OP_FIND_BY_TYPE_REQ:
+ return "Find By Type req";
+ case ATT_OP_FIND_BY_TYPE_RESP:
+ return "Find By Type resp";
+ case ATT_OP_READ_BY_TYPE_REQ:
+ return "Read By Type req";
+ case ATT_OP_READ_BY_TYPE_RESP:
+ return "Read By Type resp";
+ case ATT_OP_READ_REQ:
+ return "Read req";
+ case ATT_OP_READ_RESP:
+ return "Read resp";
+ case ATT_OP_READ_BLOB_REQ:
+ return "Read Blob req";
+ case ATT_OP_READ_BLOB_RESP:
+ return "Read Blob resp";
+ case ATT_OP_READ_MULTI_REQ:
+ return "Read Multi req";
+ case ATT_OP_READ_MULTI_RESP:
+ return "Read Multi resp";
+ case ATT_OP_READ_BY_GROUP_REQ:
+ return "Read By Group req";
+ case ATT_OP_READ_BY_GROUP_RESP:
+ return "Read By Group resp";
+ case ATT_OP_WRITE_REQ:
+ return "Write req";
+ case ATT_OP_WRITE_RESP:
+ return "Write resp";
+ case ATT_OP_WRITE_CMD:
+ return "Write cmd";
+ case ATT_OP_PREP_WRITE_REQ:
+ return "Prepare Write req";
+ case ATT_OP_PREP_WRITE_RESP:
+ return "Prepare Write resp";
+ case ATT_OP_EXEC_WRITE_REQ:
+ return "Exec Write req";
+ case ATT_OP_EXEC_WRITE_RESP:
+ return "Exec Write resp";
+ case ATT_OP_HANDLE_NOTIFY:
+ return "Handle notify";
+ case ATT_OP_HANDLE_IND:
+ return "Handle indicate";
+ case ATT_OP_HANDLE_CNF:
+ return "Handle CNF";
+ case ATT_OP_SIGNED_WRITE_CMD:
+ return "Signed Write Cmd";
+ default:
+ return "Unknown";
+ }
+}
+
+static const char * atterror2str(uint8_t err)
+{
+ switch (err) {
+ case ATT_ECODE_INVALID_HANDLE:
+ return "Invalid handle";
+ case ATT_ECODE_READ_NOT_PERM:
+ return "Read not permitted";
+ case ATT_ECODE_WRITE_NOT_PERM:
+ return "Write not permitted";
+ case ATT_ECODE_INVALID_PDU:
+ return "Invalid PDU";
+ case ATT_ECODE_INSUFF_AUTHEN:
+ return "Insufficient authentication";
+ case ATT_ECODE_REQ_NOT_SUPP:
+ return "Request not supported";
+ case ATT_ECODE_INVALID_OFFSET:
+ return "Invalid offset";
+ case ATT_ECODE_INSUFF_AUTHO:
+ return "Insufficient authorization";
+ case ATT_ECODE_PREP_QUEUE_FULL:
+ return "Prepare queue full";
+ case ATT_ECODE_ATTR_NOT_FOUND:
+ return "Attribute not found";
+ case ATT_ECODE_ATTR_NOT_LONG:
+ return "Attribute not long";
+ case ATT_ECODE_INSUFF_ENCR_KEY_SIZE:
+ return "Insufficient encryption key size";
+ case ATT_ECODE_INVAL_ATTR_VALUE_LEN:
+ return "Invalid attribute value length";
+ case ATT_ECODE_UNLIKELY:
+ return "Unlikely error";
+ case ATT_ECODE_INSUFF_ENC:
+ return "Insufficient encryption";
+ case ATT_ECODE_UNSUPP_GRP_TYPE:
+ return "Unsupported group type";
+ case ATT_ECODE_INSUFF_RESOURCES:
+ return "Insufficient resources";
+ case ATT_ECODE_IO:
+ return "Application Error";
+ default:
+ return "Reserved";
+ }
+}
+
+static const char *uuid2str(uint16_t uuid)
+{
+ switch (uuid) {
+ case GATT_PRIM_SVC_UUID:
+ return "GATT Primary Service";
+ case GATT_SND_SVC_UUID:
+ return "GATT Secondary Service";
+ case GATT_INCLUDE_UUID:
+ return "GATT Include";
+ case GATT_CHARAC_UUID:
+ return "GATT Characteristic";
+ case GATT_CHARAC_DEVICE_NAME:
+ return "GATT(type) Device Name";
+ case GATT_CHARAC_APPEARANCE:
+ return "GATT(type) Appearance";
+ case GATT_CHARAC_PERIPHERAL_PRIV_FLAG:
+ return "GATT(type) Peripheral Privacy Flag";
+ case GATT_CHARAC_RECONNECTION_ADDRESS:
+ return "GATT(type) Characteristic Reconnection Address";
+ case GATT_CHARAC_PERIPHERAL_PREF_CONN:
+ return "GATT(type) Characteristic Preferred Connection Parameters";
+ case GATT_CHARAC_SERVICE_CHANGED:
+ return "GATT(type) Characteristic Service Changed";
+ case GATT_CHARAC_EXT_PROPER_UUID:
+ return "GATT(desc) Characteristic Extended Properties";
+ case GATT_CHARAC_USER_DESC_UUID:
+ return "GATT(desc) User Description";
+ case GATT_CLIENT_CHARAC_CFG_UUID:
+ return "GATT(desc) Client Characteristic Configuration";
+ case GATT_SERVER_CHARAC_CFG_UUID:
+ return "GATT(desc) Server Characteristic Configuration";
+ case GATT_CHARAC_FMT_UUID:
+ return "GATT(desc) Format";
+ case GATT_CHARAC_AGREG_FMT_UUID:
+ return "GATT(desc) Aggregate Format";
+ default:
+ return "Unknown";
+ }
+}
+
+static void att_error_dump(int level, struct frame *frm)
+{
+ uint8_t op = get_u8(frm);
+ uint16_t handle = btohs(htons(get_u16(frm)));
+ uint8_t err = get_u8(frm);
+
+ p_indent(level, frm);
+ printf("Error: %s (%d)\n", atterror2str(err), err);
+
+ p_indent(level, frm);
+ printf("%s (0x%.2x) on handle 0x%2.2x\n", attop2str(op), op, handle);
+}
+
+static void att_mtu_req_dump(int level, struct frame *frm)
+{
+ uint16_t client_rx_mtu = btohs(htons(get_u16(frm)));
+
+ p_indent(level, frm);
+ printf("client rx mtu %d\n", client_rx_mtu);
+}
+
+static void att_mtu_resp_dump(int level, struct frame *frm)
+{
+ uint16_t server_rx_mtu = btohs(htons(get_u16(frm)));
+
+ p_indent(level, frm);
+ printf("server rx mtu %d\n", server_rx_mtu);
+}
+
+static void att_find_info_req_dump(int level, struct frame *frm)
+{
+ uint16_t start = btohs(htons(get_u16(frm)));
+ uint16_t end = btohs(htons(get_u16(frm)));
+
+ p_indent(level, frm);
+ printf("start 0x%2.2x, end 0x%2.2x\n", start, end);
+}
+
+static void att_find_info_resp_dump(int level, struct frame *frm)
+{
+ uint8_t fmt = get_u8(frm);
+
+ p_indent(level, frm);
+
+ if (fmt == 0x01) {
+ printf("format: uuid-16\n");
+
+ while (frm->len > 0) {
+ uint16_t handle = btohs(htons(get_u16(frm)));
+ uint16_t uuid = btohs(htons(get_u16(frm)));
+ p_indent(level + 1, frm);
+ printf("handle 0x%2.2x, uuid 0x%2.2x (%s)\n", handle, uuid,
+ uuid2str(uuid));
+ }
+ } else {
+ printf("format: uuid-128\n");
+
+ while (frm->len > 0) {
+ uint16_t handle = btohs(htons(get_u16(frm)));
+ int i;
+
+ p_indent(level + 1, frm);
+ printf("handle 0x%2.2x, uuid ", handle);
+ for (i = 0; i < 16; i++) {
+ printf("%02x", get_u8(frm));
+ if (i == 3 || i == 5 || i == 7 || i == 9)
+ printf("-");
+ }
+ printf("\n");
+ }
+ }
+}
+
+static void att_read_by_type_req_dump(int level, struct frame *frm)
+{
+ uint16_t start = btohs(htons(get_u16(frm)));
+ uint16_t end = btohs(htons(get_u16(frm)));
+ int i;
+
+ p_indent(level, frm);
+ printf("start 0x%2.2x, end 0x%2.2x\n", start, end);
+
+ p_indent(level, frm);
+ if (frm->len == 2) {
+ printf("type-uuid 0x%2.2x\n", btohs(htons(get_u16(frm))));
+ } else if (frm->len == 16) {
+ printf("type-uuid ");
+ for (i = 0; i < 16; i++) {
+ printf("%02x", get_u8(frm));
+ if (i == 3 || i == 5 || i == 7 || i == 9)
+ printf("-");
+ }
+ printf("\n");
+ } else {
+ printf("malformed uuid (expected 2 or 16 octets)\n");
+ p_indent(level, frm);
+ raw_dump(level, frm);
+ }
+}
+
+static void att_read_by_type_resp_dump(int level, struct frame *frm)
+{
+ uint8_t length = get_u8(frm);
+
+ p_indent(level, frm);
+ printf("length: %d\n", length);
+
+ while (frm->len > 0) {
+ uint16_t handle = btohs(htons(get_u16(frm)));
+ int val_len = length - 2;
+ int i;
+
+ p_indent(level + 1, frm);
+ printf("handle 0x%2.2x, value ", handle);
+ for (i = 0; i < val_len; i++) {
+ printf("0x%.2x ", get_u8(frm));
+ }
+ printf("\n");
+ }
+}
+
+static void att_read_req_dump(int level, struct frame *frm)
+{
+ uint16_t handle = btohs(htons(get_u16(frm)));
+
+ p_indent(level, frm);
+ printf("handle 0x%2.2x\n", handle);
+}
+
+static void att_handle_notify_dump(int level, struct frame *frm)
+{
+ uint16_t handle = btohs(htons(get_u16(frm)));
+
+ p_indent(level, frm);
+ printf("handle 0x%2.2x\n", handle);
+
+ p_indent(level, frm);
+ printf("value ");
+ while (frm->len > 0) {
+ printf("0x%.2x ", get_u8(frm));
+ }
+ printf("\n");
+}
+
+void att_dump(int level, struct frame *frm)
+{
+ uint8_t op;
+
+ op = get_u8(frm);
+
+ p_indent(level, frm);
+ printf("ATT: %s (0x%.2x)\n", attop2str(op), op);
+
+ switch (op) {
+ case ATT_OP_ERROR:
+ att_error_dump(level + 1, frm);
+ break;
+ case ATT_OP_MTU_REQ:
+ att_mtu_req_dump(level + 1, frm);
+ break;
+ case ATT_OP_MTU_RESP:
+ att_mtu_resp_dump(level + 1, frm);
+ break;
+ case ATT_OP_FIND_INFO_REQ:
+ att_find_info_req_dump(level + 1, frm);
+ break;
+ case ATT_OP_FIND_INFO_RESP:
+ att_find_info_resp_dump(level + 1, frm);
+ break;
+ case ATT_OP_READ_BY_TYPE_REQ:
+ att_read_by_type_req_dump(level + 1, frm);
+ break;
+ case ATT_OP_READ_BY_TYPE_RESP:
+ att_read_by_type_resp_dump(level + 1, frm);
+ break;
+ case ATT_OP_READ_REQ:
+ att_read_req_dump(level + 1, frm);
+ break;
+ case ATT_OP_READ_RESP:
+ raw_dump(level + 1, frm);
+ break;
+ case ATT_OP_HANDLE_NOTIFY:
+ att_handle_notify_dump(level + 1, frm);
+ break;
+ default:
+ raw_dump(level, frm);
+ break;
+ }
+}
diff --git a/parser/avctp.c b/parser/avctp.c
index d9eb4f1..4a8876c 100644
--- a/parser/avctp.c
+++ b/parser/avctp.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/avdtp.c b/parser/avdtp.c
index 22c128a..2dd2477 100644
--- a/parser/avdtp.c
+++ b/parser/avdtp.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -61,6 +61,10 @@
return "Abort";
case 0x0b:
return "Security";
+ case 0x0c:
+ return "All Capabilities";
+ case 0x0d:
+ return "Delay Report";
default:
return "Unknown";
}
@@ -166,6 +170,8 @@
return "Multiplexing";
case 7:
return "Media Codec";
+ case 8:
+ return "Delay Reporting";
default:
return "Reserved";
}
@@ -420,6 +426,25 @@
}
}
+static inline void delay_report(int level, uint8_t hdr, struct frame *frm)
+{
+ uint8_t seid;
+ uint16_t delay;
+
+ switch (hdr & 0x03) {
+ case 0x00:
+ p_indent(level, frm);
+ seid = get_u8(frm);
+ delay = get_u16(frm);
+ printf("ACP SEID %d delay %u.%ums\n", seid >> 2,
+ delay / 10, delay % 10);
+ break;
+ case 0x03:
+ errorcode(level, frm);
+ break;
+ }
+}
+
void avdtp_dump(int level, struct frame *frm)
{
uint8_t hdr, sid, nsp, type;
@@ -442,6 +467,7 @@
discover(level + 1, hdr, frm);
break;
case 0x02:
+ case 0x0c:
get_capabilities(level + 1, hdr, frm);
break;
case 0x03:
@@ -471,6 +497,9 @@
case 0x0b:
security(level + 1, hdr, frm);
break;
+ case 0x0d:
+ delay_report(level + 1, hdr, frm);
+ break;
}
break;
diff --git a/parser/bnep.c b/parser/bnep.c
index 4ab5aa4..d368abe 100644
--- a/parser/bnep.c
+++ b/parser/bnep.c
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2002-2003 Takashi Sasai <sasai@sm.sony.co.jp>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/bpa.c b/parser/bpa.c
index fa7974c..291d4ca 100644
--- a/parser/bpa.c
+++ b/parser/bpa.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/capi.c b/parser/capi.c
index 36d57aa..788f4bd 100644
--- a/parser/capi.c
+++ b/parser/capi.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/cmtp.c b/parser/cmtp.c
index bdc2024..7c4eb08 100644
--- a/parser/cmtp.c
+++ b/parser/cmtp.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2002-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2002-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/csr.c b/parser/csr.c
index 6cce85b..47954e2 100644
--- a/parser/csr.c
+++ b/parser/csr.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -146,7 +146,7 @@
static inline void commands_dump(int level, char *str, struct frame *frm)
{
unsigned char commands[64];
- int i;
+ unsigned int i;
memcpy(commands, frm->ptr, frm->len);
diff --git a/parser/ericsson.c b/parser/ericsson.c
index a9546d6..a401959 100644
--- a/parser/ericsson.c
+++ b/parser/ericsson.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/hci.c b/parser/hci.c
index ee4fdb0..f6ed1d3 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -50,7 +50,7 @@
return (manufacturer == DEFAULT_COMPID ? parser.defcompid : manufacturer);
}
-#define EVENT_NUM 61
+#define EVENT_NUM 76
static char *event_str[EVENT_NUM + 1] = {
"Unknown",
"Inquiry Complete",
@@ -114,9 +114,34 @@
"User Passkey Notification",
"Keypress Notification",
"Remote Host Supported Features Notification",
+ "LE Meta Event",
+ "Physical Link Complete",
+ "Channel Selected",
+ "Disconnection Physical Link Complete",
+ "Physical Link Loss Early Warning",
+ "Physical Link Recovery",
+ "Logical Link Complete",
+ "Disconnection Logical Link Complete",
+ "Flow Spec Modify Complete",
+ "Number Of Completed Data Blocks",
+ "AMP Start Test",
+ "AMP Test End",
+ "AMP Receiver Report",
+ "Short Range Mode Change Complete",
+ "AMP Status Change",
};
-#define CMD_LINKCTL_NUM 52
+#define LE_EV_NUM 5
+static char *ev_le_meta_str[LE_EV_NUM + 1] = {
+ "Unknown",
+ "LE Connection Complete",
+ "LE Advertising Report",
+ "LE Connection Update Complete",
+ "LE Read Remote Used Features Complete",
+ "LE Long Term Key Request",
+};
+
+#define CMD_LINKCTL_NUM 60
static char *cmd_linkctl_str[CMD_LINKCTL_NUM + 1] = {
"Unknown",
"Inquiry",
@@ -171,6 +196,14 @@
"Unknown",
"Remote OOB Data Request Negative Reply",
"IO Capability Request Negative Reply",
+ "Create Physical Link",
+ "Accept Physical Link",
+ "Disconnect Physical Link",
+ "Create Logical Link",
+ "Accept Logical Link",
+ "Disconnect Logical Link",
+ "Logical Link Cancel",
+ "Flow Spec Modify",
};
#define CMD_LINKPOL_NUM 17
@@ -195,7 +228,7 @@
"Sniff Subrating",
};
-#define CMD_HOSTCTL_NUM 95
+#define CMD_HOSTCTL_NUM 109
static char *cmd_hostctl_str[CMD_HOSTCTL_NUM + 1] = {
"Unknown",
"Set Event Mask",
@@ -286,14 +319,27 @@
"Write Simple Pairing Mode",
"Read Local OOB Data",
"Read Inquiry Response Transmit Power Level",
- "Write Inquiry Response Transmit Power Level",
+ "Write Inquiry Transmit Power Level",
"Read Default Erroneous Data Reporting",
"Write Default Erroneous Data Reporting",
"Unknown",
"Unknown",
"Unknown",
- "Enhanced Flush"
+ "Enhanced Flush",
"Unknown",
+ "Read Logical Link Accept Timeout",
+ "Write Logical Link Accept Timeout",
+ "Set Event Mask Page 2",
+ "Read Location Data",
+ "Write Location Data",
+ "Read Flow Control Mode",
+ "Write Flow Control Mode",
+ "Read Enhanced Transmit Power Level",
+ "Read Best Effort Flush Timeout",
+ "Write Best Effort Flush Timeout",
+ "Short Range Mode",
+ "Read LE Host Supported",
+ "Write LE Host Supported",
};
#define CMD_INFO_NUM 9
@@ -310,7 +356,7 @@
"Read BD ADDR",
};
-#define CMD_STATUS_NUM 7
+#define CMD_STATUS_NUM 11
static char *cmd_status_str[CMD_STATUS_NUM + 1] = {
"Unknown",
"Read Failed Contact Counter",
@@ -320,6 +366,10 @@
"Read RSSI",
"Read AFH Channel Map",
"Read Clock",
+ "Read Encryption Key Size",
+ "Read Local AMP Info",
+ "Read Local AMP ASSOC",
+ "Write Remote AMP ASSOC"
};
#define CMD_TESTING_NUM 4
@@ -331,6 +381,42 @@
"Unknown",
};
+#define CMD_LE_NUM 31
+static char *cmd_le_str[CMD_LE_NUM + 1] = {
+ "Unknown",
+ "LE Set Event Mask",
+ "LE Read Buffer Size",
+ "LE Read Local Supported Features",
+ "Unknown",
+ "LE Set Random Address",
+ "LE Set Advertising Parameters",
+ "LE Read Advertising Channel Tx Power",
+ "LE Set Advertising Data",
+ "LE Set Scan Response Data",
+ "LE Set Advertise Enable",
+ "LE Set Scan Parameters",
+ "LE Set Scan Enable",
+ "LE Create Connection",
+ "LE Create Connection Cancel",
+ "LE Read White List Size",
+ "LE Clear White List",
+ "LE Add Device To White List",
+ "LE Remove Device From White List",
+ "LE Connection Update",
+ "LE Set Host Channel Classification",
+ "LE Read Channel Map",
+ "LE Read Remote Used Features",
+ "LE Encrypt",
+ "LE Rand",
+ "LE Start Encryption",
+ "LE Long Term Key Request Reply",
+ "LE Long Term Key Request Negative Reply",
+ "LE Read Supported States",
+ "LE Receiver Test",
+ "LE Transmitter Test",
+ "LE Test End",
+};
+
#define ERROR_CODE_NUM 56
static char *error_code_str[ERROR_CODE_NUM + 1] = {
"Success",
@@ -453,6 +539,13 @@
cmd = "Unknown";
break;
+ case OGF_LE_CTL:
+ if (ocf <= CMD_LE_NUM)
+ cmd = cmd_le_str[ocf];
+ else
+ cmd = "Unknown";
+ break;
+
case OGF_VENDOR_CMD:
cmd = "Vendor";
break;
@@ -523,6 +616,36 @@
}
}
+static const char *bdaddrtype2str(uint8_t type)
+{
+ switch (type) {
+ case 0x00:
+ return "Public";
+ case 0x01:
+ return "Random";
+ default:
+ return "Reserved";
+ }
+}
+
+static const char *evttype2str(uint8_t type)
+{
+ switch (type) {
+ case 0x00:
+ return "ADV_IND - Connectable undirected advertising";
+ case 0x01:
+ return "ADV_DIRECT_IND - Connectable directed advertising";
+ case 0x02:
+ return "ADV_SCAN_IND - Scannable undirected advertising";
+ case 0x03:
+ return "ADV_NONCONN_IND - Non connectable undirected advertising";
+ case 0x04:
+ return "SCAN_RSP - Scan Response";
+ default:
+ return "Reserved";
+ }
+}
+
static char *keytype2str(uint8_t type)
{
switch (type) {
@@ -581,67 +704,136 @@
}
}
+static char *eventmask2str(const uint8_t mask[8])
+{
+ int i;
+
+ for (i = 0; i < 7; i++) {
+ if (mask[i] != 0x00)
+ return "Reserved";
+ }
+
+ switch (mask[7]) {
+ case 0x00:
+ return "No LE events specified";
+ case 0x01:
+ return "LE Connection Complete Event";
+ case 0x02:
+ return "LE Advertising Report Event";
+ case 0x04:
+ return "LE Connection Update Complete Event";
+ case 0x08:
+ return "LE Read Remote Used Features Complete Event";
+ case 0x10:
+ return "LE Long Term Key Request Event";
+ case 0x1F:
+ return "Default";
+ default:
+ return "Reserved";
+ }
+}
+
+static char *lefeatures2str(const uint8_t features[8])
+{
+ if (features[0] & 0x01)
+ return "Link Layer supports LE Encryption";
+
+ return "RFU";
+}
+
+static char *filterpolicy2str(uint8_t policy)
+{
+ switch (policy) {
+ case 0x00:
+ return "Allow scan from any, connection from any";
+ case 0x01:
+ return "Allow scan from white list, connection from any";
+ case 0x02:
+ return "Allow scan from any, connection from white list";
+ case 0x03:
+ return "Allow scan and connection from white list";
+ default:
+ return "Reserved";
+ }
+}
+
+static inline void ext_inquiry_data_dump(int level, struct frame *frm,
+ uint8_t *data)
+{
+ uint8_t len = data[0];
+ uint8_t type;
+ char *str;
+ int i;
+
+ if (len == 0)
+ return;
+
+ type = data[1];
+ data += 2;
+ len -= 1;
+
+ switch (type) {
+ case 0x01:
+ p_indent(level, frm);
+ printf("Flags:");
+ for (i = 0; i < len; i++)
+ printf(" 0x%2.2x", data[i]);
+ printf("\n");
+ break;
+
+ case 0x02:
+ case 0x03:
+ p_indent(level, frm);
+ printf("%s service classes:",
+ type == 0x02 ? "Shortened" : "Complete");
+
+ for (i = 0; i < len / 2; i++) {
+ uint16_t val;
+
+ val = btohs(bt_get_unaligned(((uint16_t *) (data + i * 2))));
+ printf(" 0x%4.4x", val);
+ }
+ printf("\n");
+ break;
+
+ case 0x08:
+ case 0x09:
+ str = malloc(len + 1);
+ if (str) {
+ snprintf(str, len + 1, "%s", (char *) data);
+ for (i = 0; i < len; 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 *) data));
+ break;
+
+ default:
+ p_indent(level, frm);
+ printf("Unknown type 0x%02x with %d bytes data\n",
+ type, len);
+ break;
+ }
+}
+
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;
+ uint8_t length;
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;
- }
+ ext_inquiry_data_dump(level, frm, frm->ptr);
frm->ptr += length;
frm->len -= length;
@@ -649,8 +841,10 @@
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);
+ 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)
@@ -917,11 +1111,44 @@
setup_sync_conn_cp *cp = frm->ptr;
p_indent(level, frm);
- printf("handle %d voice setting 0x%4.4x pkt_type 0x%4.4x\n",
+ printf("handle %d voice setting 0x%4.4x ptype 0x%4.4x\n",
btohs(cp->handle), btohs(cp->voice_setting),
btohs(cp->pkt_type));
}
+static inline void create_physical_link_dump(int level, struct frame *frm)
+{
+ create_physical_link_cp *cp = frm->ptr;
+ int i;
+
+ p_indent(level, frm);
+
+ printf("handle %d key length %d key type %d\n",
+ cp->handle, cp->key_length, cp->key_type);
+ printf("key ");
+
+ for (i = 0; i < cp->key_length && cp->key_length < 32; i++)
+ printf("%2.2x", cp->key[i]);
+ printf("\n");
+}
+
+static inline void create_logical_link_dump(int level, struct frame *frm)
+{
+ create_logical_link_cp *cp = frm->ptr;
+ int i;
+
+ p_indent(level, frm);
+
+ printf("handle %d\n", cp->handle);
+ printf("tx_flow ");
+ for (i = 0; i < 16; i++)
+ printf("%2.2x", cp->tx_flow[i]);
+ printf("\nrx_flow ");
+ for (i = 0; i < 16; i++)
+ printf("%2.2x", cp->rx_flow[i]);
+ printf("\n");
+}
+
static inline void accept_sync_conn_req_dump(int level, struct frame *frm)
{
accept_sync_conn_req_cp *cp = frm->ptr;
@@ -1344,6 +1571,97 @@
}
}
+static inline void le_create_connection_dump(int level, struct frame *frm)
+{
+ char addr[18];
+ le_create_connection_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ p_ba2str(&cp->peer_bdaddr, addr);
+ printf("bdaddr %s type %d\n", addr, cp->peer_bdaddr_type);
+}
+
+static inline void le_set_event_mask_dump(int level, struct frame *frm)
+{
+ int i;
+ le_set_event_mask_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("mask 0x");
+ for (i = 0; i < 8; i++)
+ printf("%.2x", cp->mask[i]);
+
+ printf(" (%s)\n", eventmask2str(cp->mask));
+}
+
+static inline void le_set_random_address_dump(int level, struct frame *frm)
+{
+ char addr[18];
+ le_set_random_address_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ p_ba2str(&cp->bdaddr, addr);
+ printf("bdaddr %s\n", addr);
+}
+
+
+static inline void le_set_advertising_parameters_dump(int level, struct frame *frm)
+{
+ char addr[18];
+ le_set_advertising_parameters_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("min %.3fms, max %.3fms\n", btohs(cp->min_interval) * 0.625,
+ btohs(cp->max_interval) * 0.625);
+
+ p_indent(level, frm);
+ printf("type 0x%02x (%s) ownbdaddr 0x%02x (%s)\n", cp->advtype,
+ evttype2str(cp->advtype), cp->own_bdaddr_type,
+ bdaddrtype2str(cp->own_bdaddr_type));
+
+ p_indent(level, frm);
+ p_ba2str(&cp->direct_bdaddr, addr);
+ printf("directbdaddr 0x%02x (%s) %s\n", cp->direct_bdaddr_type,
+ bdaddrtype2str(cp->direct_bdaddr_type), addr);
+
+ p_indent(level, frm);
+ printf("channelmap 0x%02x filterpolicy 0x%02x (%s)\n",
+ cp->chan_map, cp->filter, filterpolicy2str(cp->filter));
+}
+
+static inline void le_set_scan_parameters_dump(int level, struct frame *frm)
+{
+ le_set_scan_parameters_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("type 0x%02x (%s)\n", cp->type,
+ cp->type == 0x00 ? "passive" : "active");
+
+ p_indent(level, frm);
+ printf("interval %.3fms window %.3fms\n", btohs(cp->interval) * 0.625,
+ btohs(cp->window) * 0.625);
+
+ p_indent(level, frm);
+ printf("own address: 0x%02x (%s) policy: %s\n", cp->own_bdaddr_type,
+ bdaddrtype2str(cp->own_bdaddr_type),
+ (cp->filter == 0x00 ? "All" :
+ (cp->filter == 0x01 ? "white list only" : "reserved")));
+}
+
+static inline void le_set_scan_enable_dump(int level, struct frame *frm)
+{
+ le_set_scan_enable_cp *cp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("value 0x%02x (%s)\n", cp->enable,
+ (cp->enable == 0x00 ? "scanning disabled" :
+ "scanning enabled"));
+
+ p_indent(level, frm);
+ printf("filter duplicates 0x%02x (%s)\n", cp->filter_dup,
+ (cp->filter_dup == 0x00 ? "disabled" : "enabled"));
+}
+
static inline void command_dump(int level, struct frame *frm)
{
hci_command_hdr *hdr = frm->ptr;
@@ -1445,6 +1763,7 @@
case OCF_READ_REMOTE_VERSION:
case OCF_READ_CLOCK_OFFSET:
case OCF_READ_LMP_HANDLE:
+ case OCF_DISCONNECT_LOGICAL_LINK:
generic_command_dump(level + 1, frm);
return;
case OCF_MASTER_LINK_KEY:
@@ -1459,6 +1778,14 @@
case OCF_SETUP_SYNC_CONN:
setup_sync_conn_dump(level + 1, frm);
return;
+ case OCF_CREATE_PHYSICAL_LINK:
+ case OCF_ACCEPT_PHYSICAL_LINK:
+ create_physical_link_dump(level + 1, frm);
+ return;
+ case OCF_CREATE_LOGICAL_LINK:
+ case OCF_ACCEPT_LOGICAL_LINK:
+ create_logical_link_dump(level + 1, frm);
+ return;
}
break;
@@ -1503,6 +1830,7 @@
case OCF_CREATE_NEW_UNIT_KEY:
return;
case OCF_SET_EVENT_MASK:
+ case OCF_SET_EVENT_MASK_PAGE_2:
set_event_mask_dump(level + 1, frm);
return;
case OCF_SET_EVENT_FLT:
@@ -1535,6 +1863,7 @@
case OCF_SET_CONTROLLER_TO_HOST_FC:
write_scan_enable_dump(level + 1, frm);
return;
+ case OCF_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT:
case OCF_WRITE_CONN_ACCEPT_TIMEOUT:
case OCF_WRITE_PAGE_TIMEOUT:
write_page_timeout_dump(level + 1, frm);
@@ -1566,6 +1895,7 @@
case OCF_FLUSH:
case OCF_READ_LINK_SUPERVISION_TIMEOUT:
case OCF_REFRESH_ENCRYPTION_KEY:
+ case OCF_READ_BEST_EFFORT_FLUSH_TIMEOUT:
generic_command_dump(level + 1, frm);
return;
case OCF_WRITE_LINK_SUPERVISION_TIMEOUT:
@@ -1575,6 +1905,7 @@
write_ext_inquiry_response_dump(level + 1, frm);
return;
case OCF_WRITE_SIMPLE_PAIRING_MODE:
+ case OCF_WRITE_FLOW_CONTROL_MODE:
generic_write_mode_dump(level + 1, frm);
return;
case OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL:
@@ -1621,6 +1952,33 @@
return;
}
break;
+
+ case OGF_LE_CTL:
+ switch (ocf) {
+ case OCF_LE_SET_EVENT_MASK:
+ le_set_event_mask_dump(level + 1, frm);
+ return;
+ case OCF_LE_READ_BUFFER_SIZE:
+ case OCF_LE_READ_LOCAL_SUPPORTED_FEATURES:
+ case OCF_LE_READ_ADVERTISING_CHANNEL_TX_POWER:
+ return;
+ case OCF_LE_SET_RANDOM_ADDRESS:
+ le_set_random_address_dump(level + 1, frm);
+ return;
+ case OCF_LE_SET_ADVERTISING_PARAMETERS:
+ le_set_advertising_parameters_dump(level + 1, frm);
+ return;
+ case OCF_LE_SET_SCAN_PARAMETERS:
+ le_set_scan_parameters_dump(level + 1, frm);
+ return;
+ case OCF_LE_SET_SCAN_ENABLE:
+ le_set_scan_enable_dump(level + 1, frm);
+ return;
+ case OCF_LE_CREATE_CONN:
+ le_create_connection_dump(level + 1, frm);
+ return;
+ }
+ break;
}
raw_dump(level, frm);
@@ -2216,6 +2574,115 @@
}
}
+static inline void read_local_amp_info_dump(int level, struct frame *frm)
+{
+ read_local_amp_info_rp *rp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x amp status 0x%2.2x\n",
+ rp->status, rp->amp_status);
+ if (rp->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(rp->status));
+ } else {
+ p_indent(level, frm);
+ printf("total bandwidth %d, max guaranteed bandwidth %d\n",
+ btohl(rp->total_bandwidth),
+ btohl(rp->max_guaranteed_bandwidth));
+ p_indent(level, frm);
+ printf("min latency %d, max PDU %d, controller type 0x%2.2x\n",
+ btohl(rp->min_latency), btohl(rp->max_pdu_size),
+ rp->controller_type);
+ p_indent(level, frm);
+ printf("pal caps 0x%4.4x, max assoc len %d\n",
+ btohs(rp->pal_caps), btohs(rp->max_amp_assoc_length));
+ p_indent(level, frm);
+ printf("max flush timeout %d, best effort flush timeout %d\n",
+ btohl(rp->max_flush_timeout),
+ btohl(rp->best_effort_flush_timeout));
+ }
+}
+
+static inline void read_local_amp_assoc_dump(int level, struct frame *frm)
+{
+ read_local_amp_assoc_rp *rp = frm->ptr;
+ uint16_t len = btohs(rp->length);
+ int i;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x handle 0x%2.2x length %d\n",
+ rp->status, rp->handle, len);
+ if (rp->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(rp->status));
+ } else {
+ for (i = 0; i < len; i++) {
+ if (!(i % 16)) {
+ printf("\n");
+ p_indent(level, frm);
+ }
+ printf("%2.2x ", rp->fragment[i]);
+ }
+ printf("\n");
+ }
+}
+
+static inline void write_remote_amp_assoc_dump(int level, struct frame *frm)
+{
+ write_remote_amp_assoc_rp *rp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x handle 0x%2.2x\n", rp->status, rp->handle);
+ if (rp->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(rp->status));
+ }
+}
+
+static inline void le_read_buffer_size_response_dump(int level, struct frame *frm)
+{
+ le_read_buffer_size_rp *rp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x pktlen 0x%4.4x maxpkt 0x%2.2x\n", rp->status,
+ rp->pkt_len, rp->max_pkt);
+
+ if (rp->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(rp->status));
+ }
+}
+
+static inline void le_read_local_supported_features_dump(int level, struct frame *frm)
+{
+ int i;
+ le_read_local_supported_features_rp *rp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x features 0x", rp->status);
+ for (i = 0; i < 8; i++)
+ printf("%2.2x", rp->features[i]);
+ printf(" (%s)\n", lefeatures2str(rp->features));
+
+ if (rp->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(rp->status));
+ }
+}
+
+static inline void le_read_advertising_channel_tx_power_dump(int level, struct frame *frm)
+{
+ le_read_advertising_channel_tx_power_rp *rp = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x level 0x%x (dBm)\n", rp->status, rp->level);
+
+ 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;
@@ -2316,6 +2783,7 @@
return;
case OCF_READ_CONN_ACCEPT_TIMEOUT:
case OCF_READ_PAGE_TIMEOUT:
+ case OCF_READ_LOGICAL_LINK_ACCEPT_TIMEOUT:
read_page_timeout_dump(level, frm);
return;
case OCF_READ_PAGE_ACTIVITY:
@@ -2349,6 +2817,7 @@
read_local_oob_data_dump(level, frm);
return;
case OCF_READ_SIMPLE_PAIRING_MODE:
+ case OCF_READ_FLOW_CONTROL_MODE:
status_mode_dump(level, frm);
return;
case OCF_FLUSH:
@@ -2383,6 +2852,12 @@
case OCF_HOST_BUFFER_SIZE:
case OCF_REFRESH_ENCRYPTION_KEY:
case OCF_SEND_KEYPRESS_NOTIFY:
+ case OCF_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT:
+ case OCF_SET_EVENT_MASK_PAGE_2:
+ case OCF_WRITE_LOCATION_DATA:
+ case OCF_WRITE_FLOW_CONTROL_MODE:
+ case OCF_READ_BEST_EFFORT_FLUSH_TIMEOUT:
+ case OCF_WRITE_BEST_EFFORT_FLUSH_TIMEOUT:
status_response_dump(level, frm);
return;
}
@@ -2429,6 +2904,15 @@
case OCF_READ_CLOCK:
read_clock_dump(level, frm);
return;
+ case OCF_READ_LOCAL_AMP_INFO:
+ read_local_amp_info_dump(level, frm);
+ return;
+ case OCF_READ_LOCAL_AMP_ASSOC:
+ read_local_amp_assoc_dump(level, frm);
+ return;
+ case OCF_WRITE_REMOTE_AMP_ASSOC:
+ write_remote_amp_assoc_dump(level, frm);
+ return;
}
break;
@@ -2444,6 +2928,37 @@
return;
}
break;
+
+ case OGF_LE_CTL:
+ switch (ocf) {
+ case OCF_LE_SET_EVENT_MASK:
+ case OCF_LE_SET_RANDOM_ADDRESS:
+ case OCF_LE_SET_ADVERTISING_PARAMETERS:
+ case OCF_LE_SET_ADVERTISING_DATA:
+ case OCF_LE_SET_SCAN_RESPONSE_DATA:
+ case OCF_LE_SET_ADVERTISE_ENABLE:
+ case OCF_LE_SET_SCAN_PARAMETERS:
+ case OCF_LE_SET_SCAN_ENABLE:
+ case OCF_LE_CREATE_CONN:
+ case OCF_LE_CLEAR_WHITE_LIST:
+ case OCF_LE_ADD_DEVICE_TO_WHITE_LIST:
+ case OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST:
+ case OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION:
+ case OCF_LE_RECEIVER_TEST:
+ case OCF_LE_TRANSMITTER_TEST:
+ status_response_dump(level, frm);
+ return;
+ case OCF_LE_READ_BUFFER_SIZE:
+ le_read_buffer_size_response_dump(level, frm);
+ return;
+ case OCF_LE_READ_LOCAL_SUPPORTED_FEATURES:
+ le_read_local_supported_features_dump(level, frm);
+ return;
+ case OCF_LE_READ_ADVERTISING_CHANNEL_TX_POWER:
+ le_read_advertising_channel_tx_power_dump(level, frm);
+ return;
+ }
+ break;
}
raw_dump(level, frm);
@@ -3008,6 +3523,190 @@
printf("\n");
}
+static inline void evt_le_conn_complete_dump(int level, struct frame *frm)
+{
+ evt_le_connection_complete *evt = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x handle %d, role %s\n",
+ evt->status, btohs(evt->handle),
+ evt->role ? "slave" : "master");
+}
+
+static inline void evt_le_advertising_report_dump(int level, struct frame *frm)
+{
+ uint8_t num_reports = get_u8(frm);
+ const uint8_t RSSI_SIZE = 1;
+
+ while (num_reports--) {
+ char addr[18];
+ le_advertising_info *info = frm->ptr;
+
+ p_ba2str(&info->bdaddr, addr);
+
+ p_indent(level, frm);
+ printf("%s (%d)\n", evttype2str(info->evt_type), info->evt_type);
+
+ p_indent(level, frm);
+ printf("bdaddr %s (%s)\n", addr,
+ bdaddrtype2str(info->bdaddr_type));
+
+ if (info->length > 0) {
+ ext_inquiry_data_dump(level, frm,
+ ((uint8_t *) &info->length) + 1);
+ }
+
+ frm->ptr += LE_ADVERTISING_INFO_SIZE + info->length;
+ frm->len -= LE_ADVERTISING_INFO_SIZE + info->length;
+
+ p_indent(level, frm);
+ printf("RSSI: %d\n", ((int8_t *) frm->ptr)[frm->len - 1]);
+
+ frm->ptr += RSSI_SIZE;
+ frm->len -= RSSI_SIZE;
+ }
+}
+
+static inline void evt_le_conn_update_complete_dump(int level,
+ struct frame *frm)
+{
+ evt_le_connection_update_complete *uevt = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x handle %d\n", uevt->status, btohs(uevt->handle));
+
+ p_indent(level, frm);
+ printf("interval %.2fms, latency %.2fms, superv. timeout %.2fms\n",
+ btohs(uevt->interval) * 1.25, btohs(uevt->latency) * 1.25,
+ btohs(uevt->supervision_timeout) * 10.0);
+}
+
+static inline void evt_le_read_remote_used_features_complete_dump(int level, struct frame *frm)
+{
+ int i;
+ evt_le_read_remote_used_features_complete *revt = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x handle %d\n", revt->status, btohs(revt->handle));
+
+ if (revt->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(revt->status));
+ } else {
+ p_indent(level, frm);
+ printf("Features:");
+ for (i = 0; i < 8; i++)
+ printf(" 0x%2.2x", revt->features[i]);
+ printf("\n");
+ }
+}
+
+static inline void le_meta_ev_dump(int level, struct frame *frm)
+{
+ evt_le_meta_event *mevt = frm->ptr;
+ uint8_t subevent;
+
+ subevent = mevt->subevent;
+
+ frm->ptr += EVT_LE_META_EVENT_SIZE;
+ frm->len -= EVT_LE_META_EVENT_SIZE;
+
+ p_indent(level, frm);
+ printf("%s\n", ev_le_meta_str[subevent]);
+
+ switch (mevt->subevent) {
+ case EVT_LE_CONN_COMPLETE:
+ evt_le_conn_complete_dump(level + 1, frm);
+ break;
+ case EVT_LE_ADVERTISING_REPORT:
+ evt_le_advertising_report_dump(level + 1, frm);
+ break;
+ case EVT_LE_CONN_UPDATE_COMPLETE:
+ evt_le_conn_update_complete_dump(level + 1, frm);
+ break;
+ case EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE:
+ evt_le_read_remote_used_features_complete_dump(level + 1, frm);
+ break;
+ default:
+ raw_dump(level, frm);
+ break;
+ }
+}
+
+static inline void phys_link_complete_dump(int level, struct frame *frm)
+{
+ evt_physical_link_complete *evt = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x handle %d\n", evt->status, evt->handle);
+
+ if (evt->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(evt->status));
+ }
+}
+
+static inline void disconn_phys_link_complete_dump(int level, struct frame *frm)
+{
+ evt_disconn_physical_link_complete *evt = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x handle %d reason 0x%2.2x\n",
+ evt->status, 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 phys_link_loss_warning_dump(int level, struct frame *frm)
+{
+ evt_physical_link_loss_warning *evt = frm->ptr;
+
+ p_indent(level, frm);
+ printf("handle %d reason 0x%2.2x\n", evt->handle, evt->reason);
+}
+
+static inline void phys_link_handle_dump(int level, struct frame *frm)
+{
+ evt_physical_link_recovery *evt = frm->ptr;
+
+ p_indent(level, frm);
+ printf("handle %d\n", evt->handle);
+}
+
+static inline void logical_link_complete_dump(int level, struct frame *frm)
+{
+ evt_logical_link_complete *evt = frm->ptr;
+
+ p_indent(level, frm);
+ printf("status 0x%2.2x log_handle %d handle %d tx_flow_id %d\n",
+ evt->status, btohs(evt->log_handle), evt->handle,
+ evt->tx_flow_id);
+
+ if (evt->status > 0) {
+ p_indent(level, frm);
+ printf("Error: %s\n", status2str(evt->status));
+ }
+}
+
+static inline void flow_spec_modify_dump(int level, struct frame *frm)
+{
+ evt_flow_spec_modify_complete *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 event_dump(int level, struct frame *frm)
{
hci_event_hdr *hdr = frm->ptr;
@@ -3104,6 +3803,7 @@
conn_request_dump(level + 1, frm);
break;
case EVT_DISCONN_COMPLETE:
+ case EVT_DISCONNECT_LOGICAL_LINK_COMPLETE:
disconn_complete_dump(level + 1, frm);
break;
case EVT_AUTH_COMPLETE:
@@ -3211,6 +3911,28 @@
case EVT_REMOTE_HOST_FEATURES_NOTIFY:
remote_host_features_notify_dump(level + 1, frm);
break;
+ case EVT_LE_META_EVENT:
+ le_meta_ev_dump(level + 1, frm);
+ break;
+ case EVT_PHYSICAL_LINK_COMPLETE:
+ phys_link_complete_dump(level + 1, frm);
+ break;
+ case EVT_DISCONNECT_PHYSICAL_LINK_COMPLETE:
+ disconn_phys_link_complete_dump(level + 1, frm);
+ break;
+ case EVT_PHYSICAL_LINK_LOSS_EARLY_WARNING:
+ phys_link_loss_warning_dump(level + 1, frm);
+ break;
+ case EVT_PHYSICAL_LINK_RECOVERY:
+ case EVT_CHANNEL_SELECTED:
+ phys_link_handle_dump(level + 1, frm);
+ break;
+ case EVT_LOGICAL_LINK_COMPLETE:
+ logical_link_complete_dump(level + 1, frm);
+ break;
+ case EVT_FLOW_SPEC_MODIFY_COMPLETE:
+ flow_spec_modify_dump(level + 1, frm);
+ break;
default:
raw_dump(level, frm);
break;
diff --git a/parser/hcrp.c b/parser/hcrp.c
index e7ada69..45afc25 100644
--- a/parser/hcrp.c
+++ b/parser/hcrp.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/hidp.c b/parser/hidp.c
index 16aef85..0d72f3e 100644
--- a/parser/hidp.c
+++ b/parser/hidp.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/l2cap.c b/parser/l2cap.c
index a906f42..673c6b5 100644
--- a/parser/l2cap.c
+++ b/parser/l2cap.c
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -306,6 +306,22 @@
return "Retransmission";
case 0x02:
return "Flow control";
+ case 0x03:
+ return "Enhanced Retransmission";
+ case 0x04:
+ return "Streaming";
+ default:
+ return "Reserved";
+ }
+}
+
+static char *fcs2str(uint8_t fcs)
+{
+ switch (fcs) {
+ case 0x00:
+ return "No FCS";
+ case 0x01:
+ return "CRC16 Check";
default:
return "Reserved";
}
@@ -336,8 +352,9 @@
case 0x01:
return "Reject (REJ)";
case 0x02:
+ return "Receiver Not Ready (RNR)";
case 0x03:
- return "Reserved Supervisory";
+ return "Select Reject (SREJ)";
default:
return "Bad Supervisory";
}
@@ -428,7 +445,7 @@
set_mode(in, cid, mode);
printf("RFC 0x%02x (%s", mode, mode2str(mode));
- if (mode == 0x01 || mode == 0x02) {
+ if (mode >= 0x01 && mode <= 0x04) {
uint8_t txwin, maxtrans;
uint16_t rto, mto, mps;
txwin = *((uint8_t *) (ptr + 1));
@@ -442,6 +459,16 @@
printf(")");
}
+static void conf_fcs(void *ptr, int len)
+{
+ uint8_t fcs;
+
+ fcs = *((uint8_t *) ptr);
+ printf("FCS Option");
+ if (len > 0)
+ printf(" 0x%2.2x (%s)", fcs, fcs2str(fcs));
+}
+
static void conf_opt(int level, void *ptr, int len, int in, uint16_t cid)
{
p_indent(level, 0);
@@ -478,6 +505,10 @@
conf_rfc(h->val, h->len, in, cid);
break;
+ case L2CAP_CONF_FCS:
+ conf_fcs(h->val, h->len);
+ break;
+
default:
printf("Unknown (type %2.2x, len %d)", h->type & 0x7f, h->len);
break;
@@ -510,6 +541,9 @@
case L2CAP_CONF_RFC:
printf("RFC ");
break;
+ case L2CAP_CONF_FCS:
+ printf("FCS ");
+ break;
default:
printf("%2.2x ", list[i] & 0x7f);
break;
@@ -634,6 +668,9 @@
}
}
break;
+ case 0x0003:
+ printf("Fixed channel list\n");
+ break;
default:
printf("Unknown (len %d)\n", len);
break;
@@ -810,7 +847,9 @@
}
printf(" ReqSeq %d", (ctrl & 0x3f00) >> 8);
if (ctrl & 0x80)
- printf(" Retransmission Disable");
+ printf(" F-bit");
+ if (ctrl & 0x10)
+ printf(" P-bit");
printf("\n");
}
}
@@ -859,6 +898,13 @@
raw_dump(level + 1, frm);
break;
+ case 0x1f:
+ if (!p_filter(FILT_ATT))
+ att_dump(level, frm);
+ else
+ raw_dump(level + 1, frm);
+ break;
+
default:
proto = get_proto(frm->handle, psm, 0);
@@ -895,11 +941,11 @@
l2cap_hdr *hdr;
uint16_t dlen;
- if (frm->flags & ACL_START) {
+ if ((frm->flags & ACL_START) || frm->flags == ACL_START_NO_FLUSH) {
hdr = frm->ptr;
dlen = btohs(hdr->len);
- if (frm->len == (dlen + L2CAP_HDR_SIZE)) {
+ if ((int) frm->len == (dlen + L2CAP_HDR_SIZE)) {
/* Complete frame */
l2cap_parse(level, frm);
return;
diff --git a/parser/lmp.c b/parser/lmp.c
index d80b5bf..ed2ff5c 100644
--- a/parser/lmp.c
+++ b/parser/lmp.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/obex.c b/parser/obex.c
index 0f68443..1767efd 100644
--- a/parser/obex.c
+++ b/parser/obex.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -200,27 +200,55 @@
printf("%s (0x%02x)", hi2str(hi), hi);
switch (hi & 0xc0) {
case 0x00: /* Unicode */
+ if (frm->len < 2) {
+ printf("\n");
+ return;
+ }
+
len = get_u16(frm) - 3;
printf(" = Unicode length %d\n", len);
+
+ if (frm->len < len)
+ return;
+
raw_ndump(level, frm, len);
frm->ptr += len;
frm->len -= len;
break;
case 0x40: /* Byte sequence */
+ if (frm->len < 2) {
+ printf("\n");
+ return;
+ }
+
len = get_u16(frm) - 3;
printf(" = Sequence length %d\n", len);
+
+ if (frm->len < len)
+ return;
+
raw_ndump(level, frm, len);
frm->ptr += len;
frm->len -= len;
break;
case 0x80: /* One byte */
+ if (frm->len < 1) {
+ printf("\n");
+ return;
+ }
+
hv8 = get_u8(frm);
printf(" = %d\n", hv8);
break;
case 0xc0: /* Four bytes */
+ if (frm->len < 4) {
+ printf("\n");
+ return;
+ }
+
hv32 = get_u32(frm);
printf(" = %u\n", hv32);
break;
@@ -236,12 +264,12 @@
frm = add_frame(frm);
- while (frm->len > 0) {
+ while (frm->len > 2) {
opcode = get_u8(frm);
length = get_u16(frm);
status = opcode & 0x7f;
- if (frm->len < length - 3) {
+ if ((int) frm->len < length - 3) {
frm->ptr -= 3;
frm->len += 3;
return;
@@ -276,6 +304,11 @@
switch (opcode & 0x7f) {
case 0x00: /* Connect */
+ if (frm->len < 4) {
+ printf("\n");
+ return;
+ }
+
version = get_u8(frm);
flags = get_u8(frm);
pktlen = get_u16(frm);
@@ -284,17 +317,19 @@
break;
case 0x05: /* SetPath */
- if (length > 3) {
- flags = get_u8(frm);
- constants = get_u8(frm);
- printf(" flags %d constants %d\n",
- flags, constants);
- } else
+ if (frm->len < 2) {
printf("\n");
+ return;
+ }
+
+ flags = get_u8(frm);
+ constants = get_u8(frm);
+ printf(" flags %d constants %d\n", flags, constants);
break;
default:
printf("\n");
+ break;
}
if ((status & 0x70) && (parser.flags & DUMP_VERBOSE)) {
diff --git a/parser/parser.c b/parser/parser.c
index e50590e..f91b63b 100644
--- a/parser/parser.c
+++ b/parser/parser.c
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -254,7 +254,7 @@
unsigned char *buf = frm->ptr;
register int i, n;
- if ((num < 0) || (num > frm->len))
+ if ((num < 0) || (num > (int) frm->len))
num = frm->len;
for (i = 0, n = 1; i < num; i++, n++) {
@@ -275,7 +275,7 @@
unsigned char *buf = frm->ptr;
register int i, n;
- if ((num < 0) || (num > frm->len))
+ if ((num < 0) || (num > (int) frm->len))
num = frm->len;
for (i = 0, n = 1; i < num; i++, n++) {
@@ -296,7 +296,7 @@
unsigned char *buf = frm->ptr;
register int i, n = 0, size;
- if ((num < 0) || (num > frm->len))
+ if ((num < 0) || (num > (int) frm->len))
num = frm->len;
while (num > 0) {
diff --git a/parser/parser.h b/parser/parser.h
index d3a0397..f093b6b 100644
--- a/parser/parser.h
+++ b/parser/parser.h
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -77,6 +77,7 @@
#define FILT_HCRP 0x0200
#define FILT_AVDTP 0x0400
#define FILT_AVCTP 0x0800
+#define FILT_ATT 0x1000
#define FILT_OBEX 0x00010000
#define FILT_CAPI 0x00020000
@@ -229,6 +230,7 @@
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 att_dump(int level, struct frame *frm);
void obex_dump(int level, struct frame *frm);
void capi_dump(int level, struct frame *frm);
diff --git a/parser/ppp.c b/parser/ppp.c
index 6ef24e9..875e5df 100644
--- a/parser/ppp.c
+++ b/parser/ppp.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -46,7 +46,7 @@
static inline int check_for_ppp_traffic(unsigned char *data, int size)
{
- int i;
+ unsigned int i;
for (i = 0; i < size - sizeof(ppp_magic1); i++)
if (!memcmp(data + i, ppp_magic1, sizeof(ppp_magic1))) {
diff --git a/parser/rfcomm.c b/parser/rfcomm.c
index b85df91..c2a278d 100644
--- a/parser/rfcomm.c
+++ b/parser/rfcomm.c
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2001-2002 Wayne Lee <waynelee@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -93,7 +93,7 @@
print_mcc(mcc_head);
}
-static inline void mcc_msc(int level, uint8_t *ptr, int len,
+static inline void mcc_msc(int level, uint8_t *ptr, unsigned int len,
long_frame_head *head, mcc_long_frame_head *mcc_head)
{
msc_msg *msc = (void*) (ptr - STRUCT_END(msc_msg, mcc_s_head));
@@ -116,7 +116,7 @@
printf("\n");
}
-static inline void mcc_rpn(int level, uint8_t *ptr, int len,
+static inline void mcc_rpn(int level, uint8_t *ptr, unsigned int len,
long_frame_head *head, mcc_long_frame_head *mcc_head)
{
rpn_msg *rpn = (void *) (ptr - STRUCT_END(rpn_msg, mcc_s_head));
diff --git a/parser/rfcomm.h b/parser/rfcomm.h
index 4824842..a9faa0b 100644
--- a/parser/rfcomm.h
+++ b/parser/rfcomm.h
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2001-2002 Wayne Lee <waynelee@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/parser/sdp.c b/parser/sdp.c
index f0ffea3..e3a65e3 100644
--- a/parser/sdp.c
+++ b/parser/sdp.c
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2001-2002 Ricky Yuen <ryuen@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -194,8 +194,8 @@
{ 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_ADDITIONAL_PROTOCOL_DESC_LISTS, "AdditionalProtocolDescLists" },
{ SDP_ATTR_ID_SERVICE_NAME, "SrvName" },
{ SDP_ATTR_ID_SERVICE_DESCRIPTION, "SrvDesc" },
{ SDP_ATTR_ID_PROVIDER_NAME, "ProviderName" },
@@ -222,7 +222,7 @@
char* get_uuid_name(int uuid)
{
- int i;
+ unsigned int i;
for (i = 0; i < SDP_UUID_NAM_LOOKUP_TABLE_SIZE; i++) {
if (sdp_uuid_nam_lookup_table[i].uuid == uuid)
@@ -234,7 +234,7 @@
static inline char* get_attr_id_name(int attr_id)
{
- int i;
+ unsigned 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)
@@ -399,7 +399,7 @@
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)
+ while (len - (int) frm->len < n && (int) frm->len > 0)
print_de(level, frm, split, psm, channel);
}
@@ -455,7 +455,7 @@
if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) {
len = frm->len;
- while (len - frm->len < n1 && frm->len > 0) {
+ while (len - (int) frm->len < n1 && (int) frm->len > 0) {
if (parse_de_hdr(frm, &n2) == SDP_DE_UUID) {
print_uuid(n2, frm, NULL, NULL);
} else {
@@ -481,7 +481,7 @@
if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) {
len = frm->len;
- while (len - frm->len < n1 && frm->len > 0) {
+ while (len - (int) frm->len < n1 && (int) frm->len > 0) {
/* Print AttributeID */
if (parse_de_hdr(frm, &n2) == SDP_DE_UINT) {
char *name;
@@ -520,7 +520,7 @@
if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) {
len = frm->len;
- while (len - frm->len < n1 && frm->len > 0) {
+ while (len - (int) frm->len < n1 && (int) frm->len > 0) {
/* Print AttributeID */
if (parse_de_hdr(frm, &n2) == SDP_DE_UINT && n2 == sizeof(attr_id)) {
char *name;
@@ -558,7 +558,7 @@
int count = frm->len;
if (parse_de_hdr(frm, &n) == SDP_DE_SEQ) {
- while (count - frm->len < n && frm->len > 0) {
+ while (count - (int) frm->len < n && (int) frm->len > 0) {
p_indent(level, 0);
printf("record #%d\n", cnt++);
print_attr_list(level + 2, frm);
diff --git a/parser/sdp.h b/parser/sdp.h
index 914bdb6..41fc209 100644
--- a/parser/sdp.h
+++ b/parser/sdp.h
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2001-2002 Ricky Yuen <ryuen@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -129,8 +129,8 @@
#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_ICON_URL 0x000C
+#define SDP_ATTR_ID_ADDITIONAL_PROTOCOL_DESC_LISTS 0x000D
#define SDP_ATTR_ID_SERVICE_NAME 0x0100
#define SDP_ATTR_ID_SERVICE_DESCRIPTION 0x0101
#define SDP_ATTR_ID_PROVIDER_NAME 0x0102
diff --git a/parser/tcpip.c b/parser/tcpip.c
index 7e29b3f..22b68f9 100644
--- a/parser/tcpip.c
+++ b/parser/tcpip.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644
index c66a1aa..0000000
--- a/src/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-
-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/src/bpasniff.c b/src/bpasniff.c
index 43f6d51..64805e0 100644
--- a/src/bpasniff.c
+++ b/src/bpasniff.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/csrsniff.c b/src/csrsniff.c
index c32ca87..7542861 100644
--- a/src/csrsniff.c
+++ b/src/csrsniff.c
@@ -2,7 +2,7 @@
*
* BlueZ - Bluetooth protocol stack for Linux
*
- * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/hcidump.8 b/src/hcidump.8
index 0bd4ec4..aa91b81 100644
--- a/src/hcidump.8
+++ b/src/hcidump.8
@@ -102,18 +102,9 @@
.BR -A ", " "\-\^\-audio=" "<file>"
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
diff --git a/src/hcidump.c b/src/hcidump.c
index 9a2429d..af086c7 100644
--- a/src/hcidump.c
+++ b/src/hcidump.c
@@ -3,7 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2000-2002 Maxim Krasnyansky <maxk@qualcomm.com>
- * Copyright (C) 2003-2007 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -74,8 +74,6 @@
PARSE,
READ,
WRITE,
- RECEIVE,
- SEND,
SERVER,
PPPDUMP,
AUDIO
@@ -85,7 +83,6 @@
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;
@@ -181,9 +178,6 @@
if (sock < 0)
return -1;
- if (mode == SERVER)
- flags |= DUMP_BTSNOOP;
-
if (snap_len < SNAP_LEN)
snap_len = SNAP_LEN;
@@ -305,10 +299,11 @@
while (cmsg) {
switch (cmsg->cmsg_type) {
case HCI_CMSG_DIR:
- frm.in = *((int *) CMSG_DATA(cmsg));
+ memcpy(&frm.in, CMSG_DATA(cmsg), sizeof(int));
break;
case HCI_CMSG_TSTAMP:
- frm.ts = *((struct timeval *) CMSG_DATA(cmsg));
+ memcpy(&frm.ts, CMSG_DATA(cmsg),
+ sizeof(struct timeval));
break;
}
cmsg = CMSG_NXTHDR(&msg, cmsg);
@@ -319,7 +314,6 @@
switch (mode) {
case WRITE:
- case SEND:
case SERVER:
/* Save or send dump */
if (flags & DUMP_BTSNOOP) {
@@ -476,12 +470,9 @@
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
+ if (mode == WRITE || mode == PPPDUMP || mode == AUDIO)
+ open_flags = O_WRONLY | O_CREAT | O_TRUNC;
+ else
open_flags = O_RDONLY;
fd = open(file, open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
@@ -612,6 +603,7 @@
}
/* Bind socket to the HCI device */
+ memset(&addr, 0, sizeof(addr));
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = dev;
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
@@ -623,71 +615,6 @@
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;
-#ifdef HAS_INET6
- case AF_INET6:
- memcpy(&((struct sockaddr_in6 *) &ss)->sin6_addr,
- &in6addr_any, sizeof(in6addr_any));
- ((struct sockaddr_in6 *) &ss)->sin6_port = 0;
- break;
-#endif
- }
- 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;
@@ -744,7 +671,8 @@
struct addrinfo *ai, *runp;
struct addrinfo hints;
struct pollfd fds[3];
- int err, opt, datagram, nfds = 0;
+ unsigned int nfds = 0;
+ int err, opt, datagram;
memset(&hints, 0, sizeof (hints));
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
@@ -816,7 +744,8 @@
freeaddrinfo(ai);
while (1) {
- int i, n = poll(fds, nfds, -1);
+ unsigned int i;
+ int n = poll(fds, nfds, -1);
if (n <= 0)
continue;
@@ -845,7 +774,7 @@
printf("client: %s:%s snap_len: %d filter: 0x%lx\n",
hname, hport, snap_len, parser.filter);
- for (n = 0; n < nfds; n++)
+ for (n = 0; n < (int) nfds; n++)
close(fds[n].fd);
return sk;
@@ -895,6 +824,7 @@
{ "cmtp", FILT_CMTP },
{ "hidp", FILT_HIDP },
{ "hcrp", FILT_HCRP },
+ { "att", FILT_ATT },
{ "avdtp", FILT_AVDTP },
{ "avctp", FILT_AVCTP },
{ "obex", FILT_OBEX },
@@ -932,8 +862,6 @@
" -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"
@@ -946,13 +874,11 @@
" -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"
+ " -v, --version Give version information\n"
" --usage Give a short usage message\n"
);
}
@@ -964,8 +890,6 @@
{ "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' },
@@ -978,14 +902,12 @@
{ "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' },
+ { "version", 0, 0, 'v' },
{ 0 }
};
@@ -998,9 +920,7 @@
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) {
+ while ((opt=getopt_long(argc, argv, "i:l:p:m:w:r:d:taxXRC:H:O:P:D:A:YZ46hv", main_options, NULL)) != -1) {
switch(opt) {
case 'i':
if (strcasecmp(optarg, "none") && strcasecmp(optarg, "system"))
@@ -1031,16 +951,6 @@
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;
@@ -1090,14 +1000,6 @@
audio_file = strdup(optarg);
break;
- case 'B':
- flags |= DUMP_BTSNOOP;
- break;
-
- case 'V':
- flags |= DUMP_VERBOSE;
- break;
-
case 'Y':
flags |= DUMP_NOVENDOR;
break;
@@ -1106,10 +1008,6 @@
permcheck = 0;
break;
- case 'N':
- noappend = 1;
- break;
-
case '4':
af = AF_INET;
break;
@@ -1118,6 +1016,10 @@
af = AF_INET6;
break;
+ case 'v':
+ printf("%s\n", VERSION);
+ exit(0);
+
case 'h':
default:
usage();
@@ -1129,6 +1031,8 @@
argv += optind;
optind = 0;
+ printf("HCI sniffer - Bluetooth packet analyzer ver %s\n", VERSION);
+
if (argc > 0)
filter = parse_filter(argc, argv);
@@ -1144,31 +1048,25 @@
switch (mode) {
case PARSE:
+ flags |= DUMP_VERBOSE;
init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
process_frames(device, open_socket(device, flags), -1, flags);
break;
case READ:
+ flags |= DUMP_VERBOSE;
init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
read_dump(open_file(dump_file, mode, flags));
break;
case WRITE:
+ flags |= DUMP_BTSNOOP;
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:
+ flags |= DUMP_BTSNOOP;
init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
run_server(device, dump_addr, dump_port, flags);
break;