summaryrefslogtreecommitdiffstats
path: root/bluez-le-howto.tex
diff options
context:
space:
mode:
Diffstat (limited to 'bluez-le-howto.tex')
-rw-r--r--bluez-le-howto.tex760
1 files changed, 760 insertions, 0 deletions
diff --git a/bluez-le-howto.tex b/bluez-le-howto.tex
new file mode 100644
index 0000000..0ce9ca5
--- /dev/null
+++ b/bluez-le-howto.tex
@@ -0,0 +1,760 @@
+\documentclass[11pt]{article}
+\usepackage[utf8]{inputenc}
+\usepackage[english]{babel}
+\usepackage{graphicx}
+\usepackage{fancyhdr}
+
+\pagestyle{fancy}
+\lhead{}
+\chead{}
+\rhead{}
+\fancyfoot[C] {This document is confidential}
+\fancyfoot[R] {\thepage}
+\fancyhead[C] {BlueZ BTLE How-To}
+\fancyhead[R] {\thepage}
+
+\setlength{\parskip}{10pt}
+
+\title{BlueZ BTLE How-To}
+\author{Claudio Takahasi \\ claudio.takahasi@openbossa.org \and
+ João Paulo Rechi Vita \\ jprvita@openbossa.org \and
+ Paulo Alcantara \\ paulo.alcantara@openbossa.org}
+
+\begin{document}
+
+
+\maketitle
+\newpage
+
+
+\tableofcontents
+\newpage
+
+
+\section{Introduction}
+
+This document describes how to test and use Bluetooth Low-Energy on Linux
+systems, using the most recent implementation available at the moment of this
+writing. The instructions are based on an
+Ubuntu\footnote{http://www.ubuntu.com/download/ubuntu/download} Linux 11.10,
+since its the most widely deployed Linux distribution nowadays. Nonetheless,
+the process for other distributions should be very similar.
+
+
+\section{Dependencies}
+
+Bellow are listed the libraries and tools needed to compile BlueZ for BTLE
+development. The list uses the packages name on Ubuntu 11.10.
+
+\begin{itemize}
+ \item git
+ \item automake
+ \item byacc
+ \item flex
+ \item libtool
+ \item libdbus-1-dev
+ \item libglib2.0-dev
+ \item libcap-ng-dev
+ \item libusb-dev
+ \item libudev-dev
+ \item libreadline-dev
+\end{itemize}
+
+To install packages on Ubuntu, use \verb|apt-get|, like shown bellow.
+
+\begin{verbatim}
+$ sudo apt-get install <package>
+\end{verbatim}
+
+Make sure you have {\em libreadline-dev} installed, otherwise \verb|gatttool| is not
+built.
+
+
+\section{Getting the source code}
+
+
+\subsection{Linux kernel}
+
+BTLE development is focused on the new Management API, which requires a very
+recent kernel tree. The most up-to-date kernel tree with several LE-specific
+fixes can be found on the {\em integration} branch of the following tree on
+github. Eventually this branch will be integrated on the official kernel trees.
+Don't bother trying to compile other branches, since they have experimental
+changes. To access this code, clone the tree and checkout the branch:
+
+\begin{verbatim}
+$ git clone -b integration git://github.com/aguedes/linux.git
+\end{verbatim}
+
+Additionally, one should take special care when doing changes on top of this
+branch, since it's going to be constantly rebased on top of the {\em
+bluetooth-next} kernel tree.
+
+To update the local branch with the latest version of the remote {\em
+integration} branch (make sure you're on the {\em linux} directory and {\em
+integration} branch):
+
+\begin{verbatim}
+$ git fetch origin
+$ git reset --hard origin/integration
+\end{verbatim}
+
+Note that all local changes to tracked files will be lost.
+
+
+\subsection{Userspace}
+
+The upstream BlueZ tree has all the code necessary for testing and do further
+BTLE development on Linux.
+
+\begin{verbatim}
+$ git clone -b integration \
+ git://git.infradead.org/users/cktakahasi/bluez.git
+\end{verbatim}
+
+
+\section{Building and running}
+
+
+\subsection{Linux kernel}
+
+Now, copy the Linux kernel configuration file from Ubuntu as \verb|.config| to
+the Linux kernel sources directory, and generate a new configuration based on
+the Ubuntu configuration file. Just press {\em Enter} for each question until
+\verb|make oldconfig| returns.
+
+\begin{verbatim}
+$ cd linux
+$ cp /boot/config-`uname -r` .config
+$ make oldconfig
+\end{verbatim}
+
+Ubuntu doesn't enable {\em dynamic debug} on its stock kernel, so it should be
+manually enabled to make possible to obtain debug information from the kernel
+later. Edit the \verb|.config| file with your favorite editor, find the line
+that says \verb|# CONFIG_DYNAMIC_DEBUG is not set| and substitute the whole
+line with \verb|CONFIG_DYNAMIC_DEBUG=y|.
+
+Now you're ready to compile your kernel. To build and generate a Debian package
+that can be installed on Ubuntu the packages {\em fakeroot} and {\em dpkg-dev}
+are needed. Make sure they're installed and run:
+
+\begin{verbatim}
+$ make deb-pkg
+\end{verbatim}
+
+Then install the new kernel packages with {\em dpkg}:
+
+\begin{verbatim}
+$ cd ..
+$ sudo dpkg -i linux-image* linux-headers*
+\end{verbatim}
+
+After the installation is complete, reboot to use the new kernel. To enable LE
+discovery a parameter should be passed to the {\em bluetooth} kernel module. After
+unloading all bluetooth adapters ({\em hci0} to {\em hciN}) and bluetooth
+kernel modules, the {\em bluetooth} module should be reloaded with {\em
+enable\_le=1} (make sure you substitute {\em hciX} with the name of the
+adapter, for all bluetooth adapters on the system).
+
+\begin{verbatim}
+$ sudo service bluetooth stop
+$ sudo hciconfig hciX down
+$ sudo rmmod bnep rfcomm btusb bluetooth
+$ sudo modprobe bluetooth enable_le=1
+$ sudo modprobe btusb
+\end{verbatim}
+
+To check if the {\em bluetooth} module has been loaded with correct parameters,
+refer to Section \ref{sec:test-mgmt}.
+
+
+\subsection{Userspace}
+
+BlueZ has a script that does the {\em bootstrap} and {\em configure} phases
+with the recommended options for developers. Using it will ease the test and
+development processes and is highly recommended. After downloading the source
+code, run this script to prepare for compilation.
+
+\begin{verbatim}
+$ cd bluez
+$ ./bootstrap-configure
+\end{verbatim}
+
+Due to a bug in Debian (thus Ubuntu) packaging, if you have the {\em check}
+package installed you have to pass the link flag for the correct version of
+{\em libcheck}. {\em Libcheck} is an optional dependency.
+
+\begin{verbatim}
+CHECK_LIBS="-lcheck_pic" ./bootstrap-configure
+\end{verbatim}
+
+And then build the binaries with {\em make}.
+
+\begin{verbatim}
+$ make
+\end{verbatim}
+
+Now you're ready to run the Bluetooth daemon you've just compiled. First stop
+the one that came with you distribution:
+
+\begin{verbatim}
+$ sudo service bluetooth stop
+\end{verbatim}
+
+And then manually start it from the source tree, without forking into a daemon
+(n) and with debug enabled (d).
+
+\begin{verbatim}
+$ sudo src/bluetoothd -nd
+\end{verbatim}
+
+
+% \subsection{Reporting errors}
+% FIXME: Add here instructions to report errors: hcidump logs, kernel logs,
+% bluetoothd traces, valgrind
+
+
+\section{Testing management interface} \label{sec:test-mgmt}
+
+The Bluetooth Management Interface is a new kernel-userspace API, which
+replaces the traditional HCI interface. It aims to move some core host features
+inside the kernel, hiding from the userspace some hardware or controller
+specific features. It doesn't aim to expose every HCI command, but to group
+them in meaningful commands.
+
+Management interface usage is transparent to the userspace. BlueZ supports an
+abstraction to hide the active interface from the user, through a plugin called
+{\em adapter\_ops}. There is one plugin implementation that uses the management
+interface, with higher priority, and another one that uses the HCI. If the MGMT
+interface is not enabled in the kernel, the plugin system will fallback to HCI
+plugin.
+
+To check if the MGMT interface and LE discovery are enabled in the kernel, the
+following command should return a \verb|Y|.
+
+\begin{verbatim}
+$ cat /sys/module/bluetooth/parameters/enable_le
+Y
+\end{verbatim}
+
+
+% \subsection{btmgmt}
+% describe here how to pair and start discovery using btmgmt
+
+
+\section{Enabling debug}
+
+
+\subsection{Enabling kernel debug}
+
+Is possible to collect Bluetooth debug information from the kernel through {\em
+debugfs}. It is a virtual file system that allows debug to be enabled on a
+per-file base.
+
+First check if dynamic debug and debugfs are enabled in the kernel settings
+(.config file). If not, recompile you kernel with that features enabled.
+
+\begin{verbatim}
+CONFIG_DEBUG_FS=y
+CONFIG_DYNAMIC_DEBUG=y
+\end{verbatim}
+
+Dynamic debugging is controlled via the {\em dynamic\_debug/control} file.
+Bluetooth files that you wanna track should be added to that file, with {\em
+root} privileges.
+
+\begin{verbatim}
+$ sudo su -
+# FILES="net/bluetooth/hci_sock.c \
+> net/bluetooth/hci_conn.c \
+> net/bluetooth/hci_event.c \
+> net/bluetooth/l2cap_core.c \
+> net/bluetooth/l2cap.c \
+> net/bluetooth/smp.c \
+> net/bluetooth/hci_core.c \
+> net/bluetooth/mgmt.c"
+
+# for f in $FILES
+> do
+> echo "file $f +pf" >> /sys/kernel/debug/dynamic_debug/control
+> done
+# exit
+\end{verbatim}
+
+And finally, to see the messages through \verb|dmesg|, the level of messages
+printed to console should be set to {\em debug}:
+
+\begin{verbatim}
+$ sudo dmesg -n debug
+\end{verbatim}
+
+
+\section{Testing using Python scripts}
+
+BlueZ (bluetoothd) exposes a D-Bus \footnote{http://dbus.freedesktop.org/} API
+to allow the applications to configure Bluetooth adapters, manage discovery,
+pair with devices and interact with services.
+
+D-Bus is widely used in Linux distributions as interprocess communication
+mechanism. Python offers language bindings for D-Bus, exposing a simple syntax
+to create {\em proxy objects} to interact with remote applications.
+
+On the BlueZ API, there is a D-Bus object to represent each paired remote
+Bluetooth device. {\em CreateDevice} or {\em CreatePairedDevice} are the
+starting point to access remote device's services. Bluetooth Low Energy support
+in BlueZ aligns with BR/EDR, device discovery and pairing operations share the
+same API.
+
+There are a bunch of python scripts available under the \verb|test| directory
+which use the D-Bus API and are good examples of its usage.
+
+
+\subsection{Discovering devices}
+
+Device discovery can be executed through management interface or the
+standard HCI interface. The difference is where the code is implemented:
+for Management, the discovery is in the kernel instead of userspace
+plugin (HCI {\em adapter\_ops} plugin).
+
+When using the MGMT interface, if LE discovery has been enabled through the
+{\em enable\_le} module parameter, interleaved (LE + BR/EDR) discovery will be
+performed. Otherwise only BR/EDR inquiry will be executed.
+
+Start Discovery command in MGMT interface has a bit-wise parameter to inform
+which remote address type is expected. At the moment, interleaved discovery is
+the default method hard-coded in bluetoothd LE is enabled and the adapter used
+is dual-mode. The \verb|btmgmt| tool can be used to test discovery instead,
+filtering per address type. The following values are allowed:
+
+\begin{verbatim}
+1 BR/EDR
+6 LE (public & random)
+7 BR/EDR/LE (interleaved discovery)
+\end{verbatim}
+
+Testing discovery using the D-Bus API:
+
+\begin{verbatim}
+$ ./test-discovery
+\end{verbatim}
+
+Testing discovery directly through MGMT socket, finding LE devices, both public
+and random addresses:
+
+\begin{verbatim}
+$ sudo ./btmgmt find -l
+\end{verbatim}
+
+Finding BR/EDR devices through the MGMT socket:
+
+\begin{verbatim}
+$ sudo ./btmgmt find -b
+\end{verbatim}
+
+Without any parameter \verb|btmgmt find| will perform interleaved discovery:
+5.12s of LE scanning followed by 5.12s of inquiry.
+
+
+\subsection{Managing devices}
+
+
+\subsubsection{Pairing}
+
+The \verb|simple-agent| is a script that acts as an UI agent for Bluetooth
+adapters, handling \verb|bluetoothd| requests for UI actions, like presenting a
+PIN prompt and similar operations.
+
+To start pairing with a specific device ({\em hciX} should be changed with the
+correct adapter name):
+
+\begin{verbatim}
+$ simple-agent hciX <device address>
+\end{verbatim}
+
+The \verb|--capability| (short form \verb|-c|) option can be used to change how
+the host will present itself to the remote device, regarding the capabilities
+it have to present or request input of PIN codes during the pairing process.
+
+The default value is {\em KeyboardDisplay}, and other possible values are {\em
+DisplayOnly}, {\em DisplayYesNo}, {\em KeyboardOnly}, and {\em
+NoInputNoOutput}.
+
+It's also possible to register an agent to handle UI operations of incoming
+pairing requests:
+
+\begin{verbatim}
+$ simple-agent hciX
+\end{verbatim}
+
+If it all works, the message {\em Agent registered} will be printed on the
+console. Note that the agent doesn't set the adapter as {\em Discoverable} or
+{\em Connectable}, this should be done via the MGMT interface.
+
+Pairing can now be started on the remote device and \verb|simple-agent| will
+ask for the PIN code, if needed. After entering it followed by Enter, if no
+error occurs, the device will be paired with the adapter it is handling.
+
+
+\subsubsection{Managing paired devices}
+
+After pairing with a new device, the \verb|test-device| script can be used to
+interact with the remote device. The possible actions are listed bellow:
+
+\begin{enumerate}
+
+\item List all known Bluetooth devices.
+
+\begin{verbatim}
+$ test-device list
+\end{verbatim}
+
+\item List GATT services from a given device.
+
+\begin{verbatim}
+$ test-device services <device address>
+\end{verbatim}
+
+\item Create a remote device from a given Bluetooth address. Triggers the SDP
+or discover all primary services.
+
+\begin{verbatim}
+$ test-device create <device address>
+\end{verbatim}
+
+\item Remove all the information related to a device on the local storage. This
+information includes settings, SDP information, cached attributes and
+characteristics, and linkkeys. The argument can be either the device address or
+D-Bus object path.
+
+\begin{verbatim}
+$ test-device remove <device address or object path>
+\end{verbatim}
+
+\item Disconnect a remote device.
+
+\begin{verbatim}
+$ test-device disconnect <device address>
+\end{verbatim}
+
+\item Discover a device from a given Bluetooth address and also an optional
+pattern string. If this option argument is the string {\em yes}, for example,
+then the {\em DiscoverDevices} method of the {\em org.bluez.Device} interface
+will be called and find presumably the device that matches this pattern. Method
+used to update the service list using SDP or discover all primary services.
+
+\begin{verbatim}
+$ test-device discover <device address> [pattern]
+\end{verbatim}
+
+\item Return the device class (retrieved using {\em
+org.bluez.Device.GetProperties} method which returns all the properties of the
+attached Bluetooth adapter) from a given Bluetooth address.
+
+\begin{verbatim}
+$ test-device class <device address>
+\end{verbatim}
+
+\item Return the device name (retrieved using {\em
+org.bluez.Device.GetProperties} method which returns all the properties of the
+attached Bluetooth adapter) from a given Bluetooth address.
+
+\begin{verbatim}
+$ test-device name <device address>
+\end{verbatim}
+
+\item Return the alias name (retrieved using {\em
+org.bluez.Device.GetProperties} method which returns all the properties of the
+attached Bluetooth adapter) from a given Bluetooth address.
+
+\begin{verbatim}
+$ test-device alias <device address> [alias]
+\end{verbatim}
+
+\item Set the value of the property named {\em Trusted} by passing as third
+argument with either the values {\em yes} or {\em no}. Marking a device as
+trusted for the adapter means that no authorization will be asked for the user
+(through the user-agent) on an incoming connection from that device. This
+applies to BR/EDR devices only.
+
+\begin{verbatim}
+$ test-device trusted <device addres> [yes/no]
+\end{verbatim}
+
+\item Set the value of the property named {\em Blocked} by passing as third
+argument either the values {\em yes} or {\em no} (this command also requires an
+address to be passed as second argument).
+
+\begin{verbatim}
+$ test-device blocked <device address> [yes/no]
+\end{verbatim}
+
+\end{enumerate}
+
+
+\subsection{Generic Attribute API}
+
+Generic Attribute API documentation is available at {\em
+doc/attribute-api.txt}. It's still an experimental API. GATT based services
+have different requirements regarding (re)connection behaviour, making
+abstractions difficult. The idea behind this API is to provide a generic method
+so external GATT client applications can handle characteristics directly.
+
+Applications can use the Generic Attribute API or use profile specific APIs.
+Currently available profile APIs are {\em Proximity}, {\em Find Me}, and {\em
+Thermometer}.
+
+The \verb|test-attrib| is a script which tests the Generic Attribute D-Bus API.
+Before using \verb|test-attrib| the remote device needs to be paired using
+\verb|test-device|, \verb|simple-agent| or any other client.
+
+Usage example:
+
+\begin{enumerate}
+
+\item For each Bluetooth LE device, return its address, as well for each
+service of such Bluetooth LE device, and then return the service object path,
+UUID, and all characteristics of it, respectively.
+
+\begin{verbatim}
+$ test-attrib list
+\end{verbatim}
+
+\item Return all GATT services supported by the device.
+
+\begin{verbatim}
+$ test-attrib services <Bluetooth address>
+\end{verbatim}
+
+\item Return all discovered characteristics that belongs to a given service
+object path (primary service).
+
+\begin{verbatim}
+$ test-attrib discover <Service object path>
+\end{verbatim}
+
+\item Return all properties that belongs to a given GATT characteristic.
+
+\begin{verbatim}
+$ test-attrib chars <Service object path>
+\end{verbatim}
+
+\end{enumerate}
+
+
+\subsection{Managing local Bluetooth adapter}
+
+The \verb|test-adapter| script will make use of the Adapter D-Bus API to handle
+Bluetooth adapters.
+
+\begin{enumerate}
+
+\item Retrieve Bluetooth adapter's address.
+
+\begin{verbatim}
+$ test-adapter address
+\end{verbatim}
+
+\item List all available Bluetooth adapters, as well as their object path, and
+pair of key and value for all their properties.
+
+\begin{verbatim}
+$ test-adapter list
+\end{verbatim}
+
+\item Retrieve Bluetooth adapter's name (if no argument specified), otherwise
+set the property named {\em Name} to the value passed as argument. Once it's
+got its new name set, all other Bluetooth devices will see this new name when
+looking for Bluetooth devices to pair with.
+
+\begin{verbatim}
+$ test-adapter name [name]
+\end{verbatim}
+
+\item Set the property named {\em Powered} to the value passed as argument (if
+any), otherwise return the value that was previously set in it.
+
+\begin{verbatim}
+$ test-adapter powered [on/off]
+\end{verbatim}
+
+\item Set the property named {\em Pairable} to the value passed as argument (if
+any), otherwise return the value that was previously set in it.
+
+\begin{verbatim}
+$ test-adapter pairable [on/off]
+\end{verbatim}
+
+\item Set the property named {\em PairableTimeout} to the value passed as
+argument (if any), otherwise return the value that was previously set in it.
+Note also that the value passed as argument must be an unsigned integer.
+
+\begin{verbatim}
+$ test-adapter pairabletimeout [timeout]
+\end{verbatim}
+
+\item Set the property named {\em Discoverable} to the value passed as argument
+(if any), otherwise return the value that was previously set in it.
+
+\begin{verbatim}
+$ test-adapter discoverable [on/off]
+\end{verbatim}
+
+\item Set the property named {\em DiscoverableTimeout} to the value passed as
+argument (if any), otherwise return the value that was previously set in it.
+Note also that the value passed as argument must be an unsigned integer.
+
+\begin{verbatim}
+$ test-adapter discoverabletimeout [timeout]
+\end{verbatim}
+
+\item Return the current value of the property named {\em Discovering}.
+
+\begin{verbatim}
+$ test-adapter discovering
+\end{verbatim}
+
+\end{enumerate}
+
+
+\subsection{Proximity API}
+
+The Proximity API is available at {\em doc/proximity-api.txt}. The
+\verb|test-proximity| Python script uses the Proximity Monitor D-Bus API. It
+can be used to set values for LinkLossAlertLevel and ImmediateAlertLevel. The
+values permitted are "none", "mild" and "high".
+
+First, pair with remote device using \verb|simple-agent| or any other BlueZ
+pairing tool. After this, \verb|test-proximity| can be used.
+
+\begin{enumerate}
+
+\item The LinkLossAlertLevel operation only takes effect when link is lost, at which
+point the device will alert at the specified intensity level. For example, to
+set LinkLossAlertLevel to "mild":
+
+\begin{verbatim}
+$ ./test-proximity -b <device address> LinkLossAlertLevel mild
+Proximity SetProperty('LinkLossAlertLevel', 'mild')
+PropertyChanged('LinkLossAlertLevel', 'mild')
+\end{verbatim}
+
+\item Using the ImmediateAlertLevel for any value other than "none" will make the
+remote device alert as soon as possible at the specified intensity level. For
+example, to set ImmediateAlertLevel to "high":
+
+\begin{verbatim}
+$ ./test-proximity -b <device address> ImmediateAlertLevel high
+Proximity SetProperty('ImmediateAlertLevel', 'high')
+PropertyChanged('ImmediateAlertLevel', 'high')
+\end{verbatim}
+
+\end{enumerate}
+
+\subsection{Thermometer API}
+
+After connected with a {\em Thermometer}, the daemon of BlueZ will export a new
+interface \verb|org.bluez.Thermometer| under \verb|org.bluez| service in D-Bus.
+Each {\em Thermometer} device will appear with object path as \\
+\verb|[prefix]/{hciX}/dev_XX_XX_XX_XX_XX_XX|.
+The device path can be found using \verb|FindDevice| method under adapter path.
+
+With device path, we just need to register a {\em Watcher} to listen measures
+updates. For this, we create a {\em Watcher} object that implements \\
+\verb|MeasurementReceived| method.
+
+\begin{enumerate}
+
+\item For testing purposes, there is a Python named \verb|test-thermometer| in BlueZ.
+To get temperature information, run:
+
+\begin{verbatim}
+$ ./test-thermometer -b <device address>
+Final measurement received
+Exponent: -1
+Mantissa: 372
+Unit: Celsius
+Time: 943934599
+Type: Mouth
+\end{verbatim}
+
+\item To get {\em Intermediate Temperature} characteristic, we need to enable
+in test script:
+
+\begin{verbatim}
+$ ./test-thermometer EnableIntermediateMeasurement -b <device address>
+Intermediate measurement received
+Exponent: -1
+Mantissa: 372
+Unit: Celsius
+Time: 943934590
+Type: Mouth
+Final measurement received
+Exponent: -1
+Mantissa: 372
+Unit: Celsius
+Time: 943934599
+Type: Mouth
+\end{verbatim}
+
+\end{enumerate}
+
+%\section{Low Level GATT client API}
+
+\section{Low Level GATT server API}
+
+BlueZ doesn't allow external applications to register new GATT services.
+The developer needs to write new service plugins following the GNU General
+Public License premises.
+
+GATT server functions declarations to manage services and characteristics
+can be found in the following 'c' header files:
+
+\begin{enumerate}
+\item{\em attrib/gatt-service.h}: abstraction functions to add new service
+ based on low level attrib server functions
+\item{\em src/attrib-server.h}: functions to manage attributes directly in
+ in the attribute server
+\end{enumerate}
+
+Current Time service is one simple example of how to use the internal GATT
+server API.
+
+% \section{Supporting tools}
+%
+%
+% \subsection{L2CAP testing}
+%
+% The l2test is a tool which is part of the BlueZ package.
+%
+% \begin{verbatim}
+% $ TODO: example goes here
+% \end{verbatim}
+%
+%
+% \subsection{GATT testing}
+%
+% The gatttool is a tool which is part of the BlueZ package.
+%
+% \begin{verbatim}
+% $ TODO: example goes here
+% \end{verbatim}
+%
+%
+% \subsection{Dump raw HCI data}
+%
+% The hcidump is a tool which is part of the BlueZ package. It's the
+% BlueZ project Bluetooth HCI data dumper which lets you view raw HCI
+% data to and from a Bluetooth device in a human readable way.
+%
+% Start hcidump like this and create a Bluetooth connection to your
+% device:
+% \begin{verbatim}
+% $ hcidump -V -x
+% \end{verbatim}
+%
+% You will see a lot of verbose messages of the data and state of the connection.
+%
+% explain here l2test, gatttool, hcidump
+
+\end{document}