Almost 9 years ago, I wrote a series of blog posts about Bluetooth and the J2ME based “Java APIs for Bluetooth Wireless Technology” (JABWT). JABWT and J2ME haven’t survived the advent of the mobile age, but Bluetooth has evolved quite well: The 2010 introduced Low Energy standard highly optimizes battery performance by sacrifing data throughput and latency. The standard has seen a rapid adoption rate: iOS supports Bluetooth LE since Version 5.0 and Android since Version 4.3. The official page shows an overview of supported devices and peripherals.
Bluetooth LE is not backward compatible to classical Bluetooth profiles or protocols. Instead of a stream based protocol (like RFCOMM) it provides a high level data exchange profile called GATT (Generic Attribute Profile) which stores data using hierarchical structured attributes. Conceptually GATT defines two roles: client and server. Typically a smartphone acts as a client while a peripheral (e.g. a temperature sensor) plays the server role. The server groups attributes into services, each of which can contain zero or more characteristics. A characteristic is a container for user data in a specific format (e.g. uint_32). So called “properties” define whether the characteristic is readable, writable and observable.
A characteristic may contain zero or more descriptors which store metadata. An important descriptor is the CCCD (Client Characteristic Configuration Descriptor) which enables or disables server-initiated updates. So the client can decide if he wants to get notified when the data of the characteristic changes.
The services and characteristics are identified with UUIDs. In order to optimize space in the data packages the Bluetooth specification supports shortened 16 and 32 bit UUIDs for predefined standard UUIDs. Otherwise custom 128 bit UUIDs have to be used. But still, the Bluetooth SIG offers the possibility to register own 16 bit UUIDs (see this registration form).
The following picture shows the (slightly simplified) structure of the standardized Battery Service which exposes the level of a battery within a device.
The service provides only one characteristic offering a CCCD descriptor so that clients may register for notifications. The format type is set to uint8 because the possible values of the characteristic range from 0 to 100. Due to the fact that the service and the characteristic is standardized by the Bluetooth SIG, 16 bit UUIDs are used.
The simplicity of the GATT profile was surely a key factor for the success of Bluetooth LE, but when you start building an application you’ll encounter some small glitches. For example the maximum amount of services and characteristics may be very limited on some chipsets (e.g. max. 7 characteristics per service). Although the specification defines a maximum size of 512 bytes for a characteristic value, some hardware implementations only allow a fraction of that size. So you should prototype your service very early against the Bluetooth LE chip you want to use.