Archive for the ‘Uncategorized’ Category.

Android related work happening in BlueZ

To avoid unnecessary questions and confusion I thought it’d be good to give a quick overview of Android related code that will be going into bluez.git in the near future.

Since Android 4.2 there exists a well standardized HAL interface that the Bluetooth stack is expected to provide and which enables the easy replacement of the stack of choice on Android. What’s now happening in BlueZ is that we’re working on making BlueZ a drop-in replacement to Android by ensuring that the required HAL interfaces are available straight out of the BlueZ source tree.

Most of the work has little or  no impact on existing BlueZ functionality and architecture and the code will be going under a separate “android” subdirectory. However, since we’re trying to reuse as much code with the rest of BlueZ as possible this also means that some refactoring will be happening elsewhere in the tree to create reusable library-like modules from parts of the code.

One of the intentions of this work is to avoid multiple companies doing their own Android adaptation for BlueZ by having the work done in a central place upstream.

BlueZ 5 API introduction and porting guide

The BlueZ 5 D-Bus API contains significant changes compared to BlueZ 4. The bulk of the changes are due to the following features in BlueZ 5:

  • Transformation to use standard D-Bus Properties and ObjectManager interfaces (available in the D-Bus specification document)
  • Introduction of interface versions (e.g. org.bluez.Adapter1). When new versions are introduced we’ll try to keep supporting at least the two latest versions simultaneously.
  • The simplification or removal of per-profile interfaces and the addition of a general org.bluez.Device1.Connect method to connect profiles.
  • The removal of the org.bluez.Service interface (used for registering SDP records and authorization) and the introduction of a new org.bluez.Profile1 interface
  • Dynamic device object creation during device discovery
  • Introduction of an AgentManager1 interface
  • Base path moved to “/org/bluez”. This shouldn’t make much difference though as the main entry point to any interaction through D-Bus is the ObjectManager.GetManagedObjects call.

D-Bus Properties

The D-Bus Properties interface generalizes access to object/interface properties. BlueZ 4 implemented properties with custom GetProperties and SetProperty methods and PropertyChanged signals on each interface that needed them. Since the release of BlueZ 4 a standard Properties interface has been completed and instead of having these methods and signal on specific interfaces there exists a generic org.freedesktop.DBus.Properties interface on each object with methods such as Set, Get and GetAll as well as a PropertiesChanged signal. These methods and signals contain the specific interface the property belongs to as part of the message parameters. One feature which the standard properties interface exposes that didn’t exist in BlueZ 4 is the invalidation of a property. This is particularly convenient to relay the information that a property doesn’t exist any more.

D-Bus ObjectManager

The D-Bus ObjectManager interface is a generic way of accessing the the entire object hierarchy of a D-Bus service. It includes signals for interface addition and removal and a single GetManagedObjects method which returns all available objects in a service, including interfaces of the objects as well as all properties on all interfaces. The actual ObjectManager interface can be found on the root (“/”) path of the BlueZ service.

Because most tasks of managing and discovering objects can be done through ObjectManager many methods, signals and properties in BlueZ 4 became redundant and were decided to be removed. One of the most notable of these removals is the old org.bluez.Manager interface. In BlueZ 5 there does not exist anything that would correspond to this. Instead, an application would discover the available adapters by performing a ObjectManager.GetManagedObjects call and look for any returned objects with an “org.bluez.Adapter1″ interface. The concept of a default adapter was always a bit fuzzy and the value could’t be changed, so if applications need something like it they could e.g. just pick the first adapter they encounter in the GetManagedObjects reply.

There’s a test/get-managed-objects test script in the source tree that can be used to see the bluetoothd objects exported by ObjectManager.

Device discovery

Bluetooth Low Energy essentially extended Bluetooth addresses with one extra bit, requiring one to always know whether an address is “random” or “public”. This caused issues with the BlueZ 4 API where the address was given to BlueZ in the CreateDevice and CreatePairedDevice calls. Since the parameter didn’t contain any of this extra random/public information bluetoothd had to maintain an internal cache to look up the necessary info. Another complication to the matter is that the BlueZ D-Bus API doesn’t differentiate between traditional BR/EDR devices and LE devices so there are essentially three possible address types: BR/EDR, LE public and LE random.

To solve this issue we decided to simply get rid of explicit CreateDevice/CreatePairedDevice methods and instead dynamically create device objects as they are discovered during device discovery. Since ObjectManager is available this also means that a separate DeviceFound signal is no longer needed. Instead an application doing discovery can simply track newly created device objects through the usual ObjectManager signals. To pair a device (identical to the old CreatePairedDevice) a new Device1.Pair method was added, and to skip pairing and just connect a Device1.Connect method was added (similar, but not quite the same as the old CreateDevice). Once the discovery stops, devices neither connected to or paired will be automatically removed by bluetoothd within three minutes.

There’s a test/test-discovery test script in the source tree that can both be used for testing discovery as well as an example of how to implement device discovery support to an application (which methods and signals are involved, etc)

General device connection procedure

BlueZ 4 had a general Device.Disconnect method but no general Connect. The closest you would get was the Connect method on the Audio interface which grouped together all audio profiles into a single coordinated connection procedure.

Through internal re-factoring and creation of a cleaner internal profile interface BlueZ 5 has been able to generalize this for all profiles and introduce a Device1.Connect method. Any implemented profile can elect to participate in this general connection procedure and will get connected when the user calls the method. Internally this method contains some special knowledge about the recommended connection order for profiles and will sort the profiles based on that. One example is the audio profiles where it’s desirable to have HFP connected first, then A2DP and finally AVRCP.

What this interface means to applications is that instead of trying to discover supported profiles of a device and then deciding exactly which interface’s Connect method needs to be called (org.bluez.Input, org.bluez.Audio, etc. in BlueZ 4) the application can straight proceed to call Device1.Connect and not worry about the details.

To test the Device1.Connect() functionality you can e.g. use the test/test-device script: test-device connect <remote addr>

The new Profile1 interface (and removal of org.bluez.Service)

BlueZ 5 introduces a new generic D-Bus interface for implementing external profiles. The profile (residing in a separate process) implements a org.bluez.Profile1 interface and registers an object implementing it through a new ProfileManager1 interface on the BlueZ side. In the RegisterProfile method (on the ProfileManager1 interface) the profile needs to at least provide the UUID for the profile to be registered. BlueZ has internally a table of defaults for common profiles so no other information is necessarily needed. However, if the profile desires to it can provide information such as the full SDP record (XML encoded), desired security level, enable/disable authorization, version, features, role, name, etc.

Once the profile is registered bluetoothd will take over all tasks needing to be done until the point of a fully created connection for the profile. This includes registering an SDP record (for server-side profiles), starting server sockets or connecting client sockets, and performing authorization (for server-side profiles). Once bluetoothd has completed these tasks it will pass the new connection to the external profile object through a Profile1.NewConnection method call. The method call contains the file descriptor (socket) for the connection as well as a dictionary of properties for the connection. These properties can include things like Version and Features (fetches from the remote SDP record) or even profile-specific entries which bluetoothd internally provides a mechanism to register hooks for.

Since this interface fulfills the same tasks (and more) than the org.bluez.Service interface in BlueZ 4 the old interface has been removed. At the time of BlueZ 5 release, existing projects that have been converted to use the new Profile interface include obexd (all OBEX profiles) as well as oFono (for HFP).

There are a few test scripts in the source tree like test/test-profile and test/test-hfp that can be used as examples for interacting with the ProfileManager1 interface.

The new AgentManager1 interface

BlueZ requires the registration of Agent objects to handle pairing and incoming connection authorization. BlueZ 5 does away with the old Adapter.RegisterAgent method and the agent parameter of the CreatePairedDevice method (Device1.Pair in BlueZ 5) in favor of a more generic AgentManager1 inteface. All agents need to be registered through this interface and BlueZ will automatically pick the agent of same application that called Device1.Pair (assuming that application also owns an agent). An AgentManager1.RequestDefault method exists for an agent to request to become the default one, in which case it will be assigned to handle all incoming (remotely initiated) requests. An agent that previously registered itself with Adapter.RegisterAgent should register itself as the default agent in BlueZ 5.

There are also a few changes for the Agent1 interface (in addition to the rename from Agent to Agent1). Firstly, the ConfirmModeChange method has been removed as this was tied in to the Adapter.RequestSession functionality which was also removed (due to not adding much value). Secondly, there is a new RequestAuthorization method used for requesting authorization for pairing requests which would otherwise not trigger any action for the user. The main situation where this would occur is an incoming SSP pairing request that would trigger the just-works model.

There’s a test/simple-agent test script for testing the AgentManager1 interface as well as giving an example of how agent registration is done.

 

Proximity (Link Loss) and Find Me

by: INdT/OpenBossa BlueZ team

Proximity (PXP) and Find Me (FMP) profiles are publicly available since second half of June. BlueZ does not officially support LE GATT profiles yet. There are pending kernel patches related to interleaved BR/LE discovery, security manager and passive scanning that require more feedback from the community and review. This process takes time, in the meanwhile we would like to share the status and reference to the source code.

First of all, it needs to be clear that Proximity and Find Me are distinct profiles located under the same proximity/ sub-directory, only because they share a common GATT service: Immediate Alert Service.

Proximity’s Link Loss is functional, Path Loss requires tuning and real hardware to test against it, and thus is disabled by default in the configuration file (proximity.conf). After creating a device D-Bus object which supports Link Loss (i.e. a LE device on the Proximity Reporter role), the “high” alert level is automatically written on the remote device, meaning that UI is not necessary to enable alert level (unless you want change it to “mild” or “none”). The “test-proximity” script (under the test/ sub-directory) can be used to change alert levels and also test Find Me (which basically consists of writing some alert level to a characteristic of the Immediate Alert Service).

For LE profiles, the new Bluetooth Management kernel interface (mgmt) is required, mainly due to Security Manager requirements. Even though device discovery works on both interfaces (HCI and Management), only mgmt can be used for current LE GATT profiles, because they require at least security mode 1 level 2.

For re-connections, it is planned to trigger automatic connections based on user (or platform specific) events. For instance, automatic connections would be enabled during a configurable time when the user unlocks the screen (Desktop, phone, tablet, …). The idea is to control connections based on profile requirements and user input. Power saving mode (when scanning) is not being addressed since automatic connection has a small active period.

Much of the code is still under development. While it is not upstream, it can be found in the repositories below.

userspace: git://git.infradead.org/users/cktakahasi/bluez.git proximity-devel
kernel: git://github.com/aguedes/linux-2.6.git proximity-devel

Bluetooth changes for 2.6.38

2.6.38 was a quiet release cycle for the Bluetooth subsystem, the biggest changes came from Johan Hedberg for the HCI management Interface, a under development code. Besides that we added support for two Atheros devices (AR9285 and AR5BBU12). Fixed a regression with the USB autosuspend and lot of other fixes and clean ups.

On the other hand 2.6.39 is being a very busy release cycle, stay tuned to see all the new stuff we will add to the Linux Bluetooth stack.

The upcoming Management Interface

I thought I’d write some things about the upcoming Management Interface, since what it is and the reasons for its existence might be unclear to people. In short, it’s a new interface for user space Bluetooth components (like bluetoothd) to talk to the kernel and it aims to replace the existing raw HCI sockets.

Issues with the current solution

Probably a good starting point is to look at problems with the existing interface to the kernel.

Command queues and synchronization

So far both the kernel and user space have been involved in receiving HCI events and sending HCI commands. However, neither one knows exactly what the other one is doing. The kernel has a proper HCI command queue which makes sure it doesn’t send commands to the controller when the controller is unable to receive them. User space doesn’t have such a mechanism, nor is it aware of the kernels queue. HCI commands sent from user space will bypass the kernel queue as they use the “raw data” queue instead of the command queue.

What this missing synchronization means is that it’s possible for user space to send commands when the controller can’t receive them and we’ve seen several controllers behaving badly in such circumstances. One common case when this can happen is when establishing connections: it’s cheap to update information (e.g. the friendly name) about the remote device when there’s already a link to it so both user space and the kernel try to do it when they see a new link becoming available.

Blocking operations

Powering a Bluetooth adapter on or off from user space has so far been accomplished using the HCIDEVDOWN & HCIDEVUP ioctl’s. Nothing wrong with it as such, except that the ioctl interface is blocking. This isn’t so nice for a single threaded process with an asynchronous mainloop like bluetoothd. The issue has been worked around so far by forking off a child process that does the ioctl, but it’s not a very nice or clean solution.

Extra (unnecessary) processing of HCI events

When there’s one or more raw HCI sockets in user space a special promisc flag is set for the corresponding adapter on the kernel side. When this flag is set the kernel needs to do extra processing to figure out whether an HCI event packet needs to be forwarded to user space or not.

Distributed security policy and logic

With pre-2.1 adapters the Bluetooth security model was rather simple and well understood. The worksplit between the kernel and userspace was also rather simple: user space would take care of storing link keys and responding to PIN and link key requests while the kernel would enforce authentication for sockets that had it as a requirement. With Bluetooth 2.1 and Secure Simple Pairing (SSP) this changed.

With SSP there are several different possible authentication methods and the link key type becomes much more relevant for the security policy. For example, if a socket requires Man In The Middle (MITM) attack protection (aka high security level in BlueZ speak) an unauthenticated link key is not enough but a link key with the type “authenticated” is needed. This is not a problem per-se, but the kernel-user space worksplit has an issue: the kernel knows all sockets and their security requirements while userspace knows the stored link keys and their types. However, the link key response (which the kernel could potentially try to catch) does not contain the key type information. This means that the kernel has no idea of the level of security that a link key provides when user space responds to a link key request.

Lack of early-tracing capability

There’s a nice tool for doing HCI level tracing called hcidump. However, if one desires to catch the early traffic going to and from an adapter right after the adapter has been plugged in there’s a problem: hcidump can only be started once the adapter is available. It’d be nice to have some sort of a higher-level socket that could be used to catch traffic from all existing adapters as well as newly plugged ones.

Cue the Management interface

The idea of the management interface is to remove the need to have raw HCI sockets in user space. It solves most of the issues raised above:

Command queues and synchronization

Since the kernel is now responsible for all HCI traffic there’s no risk of conflicts between kernel and userspace.

Blocking operations

With the management interface there are simple asynchronous messages that are used to power on and off adapters: blocking problem solved.

Unnecessary HCI event processing

No raw HCI sockets means no promisc flag on the kernel side. So extra processing of these packets isn’t needed anymore.

Distributed security policy and logic

With the management interface only user interaction (PIN code/pass key requests, etc) and link key storage is handled on the user space side. User space will feed the kernel with all stored link keys, including the key types, upon adapter initialization. After that the kernel is responsible for handling link key requests.

An additional benefit with having an abstracted interface for security is that it can be used for the Security Manager Protocol (SMP) that’s part of the Bluetooth Low Energy (LE) specification. SMP has a similar user interaction model as SSP so the same messages between user space and the kernel can be reused.

As long as SMP is implemented on the kernel side there’d be a big problem with dealing with it from user space using the existing kernel interface since unlike SSP, SMP uses L2CAP and not HCI for messaging.

Lack of early-tracing capability

The management interface will offer a special type of tracing socket which can be used to get the HCI traffic of all connected adapters. This will allow a userspace process to catch all traffic to and from an adapter from the first moment that it is plugged in.

Current status

During the last few months bluetoothd has gone through considerable refactoring to move the user space – kernel interface to a single place and create an abstraction which doesn’t depend on the techincal details of this interface. This interface is called “adapter operations” and there’s a adapter_ops struct in src/adapter.c that describes it. For the legacy raw HCI socket based solution there’s a plugin called hciops (plugins/hciops.c) which implements the adapter_ops interface. For the management interface there is plugins/mgmtops.c. bluetoothd will automatically select mgmtops if it is running on top of a kernel with that capability and if not it will wall back to hciops.

The exact definition of the management interface is still evolving, but the latest one can always be found in doc/mgmt-api.txt.

On the kernel side some management patches have already gone into the bluetooth-next-2.6 tree [0] and the very latest ones can be found in my own kernel tree [1] (which is rebased periodically on top of bluetooth-next-2.6). Since the code cannot fully replace the existing raw HCI socket based solution it is disabled by default and needs to be explicitly enabled using a enable_mgmt=1 option to the bluetooth module (or “echo 1 > /sys/module/bluetooth/parameters/enable_mgmt”).

[0] http://git.kernel.org/?p=linux/kernel/git/padovan/bluetooth-next-2.6.git;a=summary
[1] http://git.kernel.org/?p=linux/kernel/git/jh/linux-2.6.git;a=summary

What works

  • Adapter enumeration
  • Powering on/off adapters (no blocking ioctls anymore!)
  • Setting adapters as discoverable
  • Basic Class of Device value control
  • Legacy pairing (PIN request)
  • Link key handling
  • just-works SSP pairing

What doesn’t work (but will in a few weeks)

  • Device discovery
  • Full pairing support (legacy, SSP & SMP)
  • LE support (both SMP and device discovery)
  • Some minor features of adapter_ops.

The future of hciops

Originally our plans were to drop the raw HCI socket based approach completely with BlueZ 5.x and require a kernel that has the management interface. This plan was based on the assumption that the user space code base wouldn’t be maintainable with both kernel interfaces. However, as the mgmtops/hciops abstraction seems to have proceeded rather successfully there really isn’t a need to drop support for old kernels anymore (it remains to be seen if this will still be done though). Some things however, like LE SMP support, will not be available with hciops.

BlueZ Low Energy support status

2010 was a busy year for BlueZ developers. In the first day of the new year I decided to write my first post in the BlueZ blog to provide initial guidance to everyone interested on Low Energy support in BlueZ. The Low Energy support is on heavy development, so feel free to report bugs and contribute.


There are three major pieces:
- BLE controller abstraction
- Attribute protocol
- Security Manager


Our goal is to hide BLE technology details from the applications. BlueZ will expose the same interface for device discovery operations, meaning that the applications do not need to know the hardware capabilities/features. BlueZ will use the same abstraction(D-Bus signals) to report found devices and services. Internally, BlueZ will manage the interleaved BLE scanning and BR/EDR inquiry.
The logic to “create” a device is still the same, an application needs to call StartDiscovery() to find the MAC address and call CreateDevice or CreatePairedDevice to “create” the device representation. bluetoothd identifies the remote type based on the advertising data and triggers the SDP or GATT primary service discovery.
ATT(Attribute Protocol) is a very simple protocol to discover/exchange characteristics. GATT is basically procedures descriptions of how ATT should be used to discover services and read/write characteristics. ATT can be considered transport agnostic, we implemented GATT/ATT first over BR/EDR due the BLE hardware unavailability, extend to BLE was just a minor surgery in the BlueZ code. Nowadays, both are supported, the BlueZ attribute server/client supports both transports, there are some restrictions in the Bluetooth Specification to avoid interoperability problems, some of them are already implemented in BlueZ but minor hacks in the code allows anyone to test ATT/GATT over BR/EDR.
Security Manager: Only Just Works method is supported at the moment. LE kernel is not in the bluetooth-next tree yet.
It is available at: git.infradead.org/users/vcgomes/linux-2.6.git


Issues that still open:
- Random address support
- Privacy
- GATT server API
- Register Application API
- Better connection management
- Characteristic descriptors
More issues can be found in the TODO file(BlueZ source)


What is currently implemented:
- Attribute server example
- gatttool: command line tool to run common GATT procedures
- Generic Attribute Client: over BR/EDR and LE
- General Discovery Procedure: interleaved discovery
- Just works method for Security Manager


Contributions are welcome!
Happy New Year!