
Reading the GATT characteristics of a Bluetooth device
Hi, habrauzers!
While working on his ANE library for working with Bluetooth LE in the AIR application for iOS + OSX, I discovered that in addition to your own services and features for exchanging information, bluetooth devices have standard ones. An article on how to read information from these characteristics. I’ll say right away I’m not a big connoisseur of bluetooth and everything connected with it, and for me all this is new :) Let's go ...
Scanning the services and features of my macbook, I saw the following services:
Continuity service is used to transfer data between devices connected by Apple, more details here: www.apple.com/en/ios/whats-new/continuity . If there is time to understand the format of the transmitted data - I will write a separate post about this.
Consider a 180A service — device information. This service is part of the GATT profile. We open the page of GATT services , we find the service by identifier 180A . The list of available indicates various characteristics:
Specifically, my device showed only two available characteristics:
We open the page of GATT characteristics , we find there the necessary characteristic on uuid, for example 2A29 . The description says that the characteristic has one single field and it has the utf8s format :

This means that you can read the value in the AIR application in the following way:
In my case, I got the values:
With these characteristics, everything was simple, move on.
Now let's try to scan the iOS device and look at what data it provides. My iPhone showed me the following services:
The 7905F431-B5CE-4E99-A40F-4B1E122D00D0 service, this is the Apple notification center service, more details here: developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html . There will be time, I’ll try to figure out the data format and write a separate post on working with the bluetooth services of Apple devices.
The 180F service is battery information. This service has one single characteristic 2A19 , the description of which says that the characteristic has one single uint8 format field :

You can read this information in an AIR application like this:
We get a value from 0 to 100, corresponding to the battery level of the device.
As you can see from the description of the service 1805 - this is information about the current time. My iOS device showed only two characteristics of this service:
The 2A0F characteristic has two fields:

We open the description of the first Time Zone field and see that it contains one field of the sint8 format .
The second field of 2A0F service is Daylight Saving Time - information about daylight saving time, format: uint8 .
So, to read the 2A0F characteristic in an AIR application, use the following code:
In my case, I got the values:
The value 12 in the TimeZone field corresponds to the UTC + 3: 00 time zone , according to the XML file:
you can download it in the description of the Time Zone field by clicking the Download / View button opposite the field name.
The 2A2B characteristic represents the current time on the device, and it has a multi-level nesting of fields, you can familiarize yourself with the descriptions and formats of them yourself. I will give only the code to read the complete information about the current time of the device:
There are several important points here.
First: all GATT specification notes say:
This means that in ByteArray the low byte comes first, in AIR this can be specified using the endian property :
Second: the fraction field , as follows from the description, is 1 / 256th of a second, i.e. to get milliseconds write the code:
And the third: I still did not understand what Adjust Reason is . Who knows - share information :).
While working on his ANE library for working with Bluetooth LE in the AIR application for iOS + OSX, I discovered that in addition to your own services and features for exchanging information, bluetooth devices have standard ones. An article on how to read information from these characteristics. I’ll say right away I’m not a big connoisseur of bluetooth and everything connected with it, and for me all this is new :) Let's go ...
Services and features of the OSX device
Scanning the services and features of my macbook, I saw the following services:
- UUID: 180A - Device Information
- UUID: D0611E78-BBB4-4591-A5F8-487910AE4366 - Continuity
- ...
Continuity Service
Continuity service is used to transfer data between devices connected by Apple, more details here: www.apple.com/en/ios/whats-new/continuity . If there is time to understand the format of the transmitted data - I will write a separate post about this.
Service 180A (Device Information)
Consider a 180A service — device information. This service is part of the GATT profile. We open the page of GATT services , we find the service by identifier 180A . The list of available indicates various characteristics:
- Manufacturer Name String
- Model Number String
- ... and much more
Specifically, my device showed only two available characteristics:
- UUID: 2A29 - Manufacturer Name String
- UUID: 2A24 - Model Number String
We open the page of GATT characteristics , we find there the necessary characteristic on uuid, for example 2A29 . The description says that the characteristic has one single field and it has the utf8s format :

This means that you can read the value in the AIR application in the following way:
var bytes:ByteArray = ...;
var string:String = bytes.readUTFBytes(bytes.bytesAvailable);
In my case, I got the values:
2A29 - Apple Inc
2A24 - MacBookPro10,2
With these characteristics, everything was simple, move on.
Services and features of iOS device
Now let's try to scan the iOS device and look at what data it provides. My iPhone showed me the following services:
- UUID: 180F
- UUID: 1805
- UUID: 7905F431-B5CE-4E99-A40F-4B1E122D00D0
- ...
The 7905F431-B5CE-4E99-A40F-4B1E122D00D0 service, this is the Apple notification center service, more details here: developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html . There will be time, I’ll try to figure out the data format and write a separate post on working with the bluetooth services of Apple devices.
Service 180F (Battery Service)
The 180F service is battery information. This service has one single characteristic 2A19 , the description of which says that the characteristic has one single uint8 format field :

You can read this information in an AIR application like this:
var bytes:ByteArray = ...;
var level:int = bytes.readByte();
We get a value from 0 to 100, corresponding to the battery level of the device.
Service 1805 (Current Time Service)
As you can see from the description of the service 1805 - this is information about the current time. My iOS device showed only two characteristics of this service:
- UUID: 2A0F - Local Time Information
- UUID: 2A2B - Current Time
Feature 2A0F (Local Time Information)
The 2A0F characteristic has two fields:

We open the description of the first Time Zone field and see that it contains one field of the sint8 format .
The second field of 2A0F service is Daylight Saving Time - information about daylight saving time, format: uint8 .
So, to read the 2A0F characteristic in an AIR application, use the following code:
var bytes:ByteArray = ...;
var timeZoneValue:int = bytes.readByte(); // считываем Time Zone
var dstValue:int = bytes.readUnsignedByte(); // считываем Daylight Saving Time
In my case, I got the values:
TimeZone: 12
Daylight Saving Time: 0
The value 12 in the TimeZone field corresponds to the UTC + 3: 00 time zone , according to the XML file:
List of time zones in XML
Mandatory sint8 -48 56
you can download it in the description of the Time Zone field by clicking the Download / View button opposite the field name.
Feature 2A2B (Current Time)
The 2A2B characteristic represents the current time on the device, and it has a multi-level nesting of fields, you can familiarize yourself with the descriptions and formats of them yourself. I will give only the code to read the complete information about the current time of the device:
var bytes:ByteArray = ...;
bytes.endian = Endian.LITTLE_ENDIAN;
//
var year:int = b.readUnsignedShort(); // год
var month:int = b.readUnsignedByte(); // месяц (начинается с 1)
var day:int = b.readUnsignedByte(); // день (начинается с 1)
var hours:int = b.readUnsignedByte(); // часы
var minutes:int = b.readUnsignedByte(); // минуты
var seconds:int = b.readUnsignedByte(); // секунды
//
var dayOfWeek:int = b.readUnsignedByte(); // день недели (начинается с 0)
var fraction:int = b.readUnsignedByte(); // миллисекунды
var adjustReason:int = b.readUnsignedByte(); // ???
There are several important points here.
First: all GATT specification notes say:
The fields in the above table are in the order of LSO to MSO. Where LSO = Least Significant Octet and MSO = Most Significant Octet.
This means that in ByteArray the low byte comes first, in AIR this can be specified using the endian property :
bytes.endian = Endian.LITTLE_ENDIAN;
Second: the fraction field , as follows from the description, is 1 / 256th of a second, i.e. to get milliseconds write the code:
var milliseconds:int = Math.floor(fraction/256*1000);
And the third: I still did not understand what Adjust Reason is . Who knows - share information :).
References:
- GATT services
- GATT specifications
- Videos showing reading GATT features from OSX and iOS devices in an AIR application
- ANE library for working with Bluetooth in an AIR application. There are also ready-made iOS and OSX applications for scanning services and obtaining information from available characteristics