📜 ⬆️ ⬇️

Reading GATT-characteristics of a Bluetooth device

Hi, habrayuzer!

Working on my ANE library for working with Bluetooth LE in an AIR application for iOS + OSX, I found out that in addition to your own services and features for sharing information, bluetooth devices have standard ones. An article on how to read information from these characteristics. I will say right away that I am not a great connoisseur of bluetooth and everything connected with it, and all this is new to me :) Let's go ...


OSX device services and features


Scanning the services and characteristics of your macbook, I saw the following services:

')

Continuity service


The Continuity service is used to transfer data between Apple-connected devices, read more here: www.apple.com/ru/ios/whats-new/continuity . If there is time to understand the format of the transmitted data - I will write about this a separate post.

Service 180A (Device Information)


Consider service 180A — device information. This service is part of the GATT profile. Open the GATT services page, find the service by identifier 180A . In the list of available there are various characteristics:

Specifically, my device showed only two available characteristics:

Open the page GATT-characteristics , we find there the desired characteristic for uuid, for example 2A29 . The description says that the characteristic has one single field and it has the format utf8s :

This means that you can read the value in the AIR application as follows:
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 it was all simple, go ahead.

IOS device services and features


Now let's try to scan the iOS device and see what data it provides. My iPhone showed me the following services:


Service 7905F431-B5CE-4E99-A40F-4B1E122D00D0 is an Apple notification center service, read more here: developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html . There will be time, I will try to understand the data format and write a separate post on working with bluetooth services of Apple devices.

Service 180F (Battery Service)


Service 180F is a battery charge information. This service has one single characteristic 2A19 , in the description of which it is said that the characteristic has one single field of the uint8 format:

You can read this information in the AIR application as follows:
 var bytes:ByteArray = ...; var level:int = bytes.readByte(); 

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:


Characteristic 2A0F (Local Time Information)


Characteristic 2A0F has two fields:


Open the description of the first Time Zone field and see that it contains one sint8 format field .

The second field for the 2A0F service is Daylight Saving Time - information on 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
 <?xml version="1.0" encoding="UTF-8"?> <!-- Copyright 2011 Bluetooth SIG, Inc. All rights reserved. --> <Characteristic xsi:noNamespaceSchemaLocation="http://schemas.bluetooth.org/Documents/characteristic.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Time Zone" type="org.bluetooth.characteristic.time_zone" uuid="2A0E"> <InformativeText> </InformativeText> <Value> <Field name="Time Zone"> <Requirement>Mandatory</Requirement> <Format>sint8</Format> <Minimum>-48</Minimum> <Maximum>56</Maximum> <Enumerations> <Enumeration key="-48" value="UTC-12:00" /> <Enumeration key="-44" value="UTC-11:00" /> <Enumeration key="-40" value="UTC-10:00" /> <Enumeration key="-38" value="UTC-9:30" /> <Enumeration key="-36" value="UTC-9:00" /> <Enumeration key="-32" value="UTC-8:00" /> <Enumeration key="-28" value="UTC-7:00" /> <Enumeration key="-24" value="UTC-6:00" /> <Enumeration key="-20" value="UTC-5:00" /> <Enumeration key="-18" value="UTC-4:30" /> <Enumeration key="-16" value="UTC-4:00" /> <Enumeration key="-14" value="UTC-3:30" /> <Enumeration key="-12" value="UTC-3:00" /> <Enumeration key="-8" value="UTC-2:00" /> <Enumeration key="-4" value="UTC-1:00" /> <Enumeration key="0" value="UTC+0:00" /> <Enumeration key="4" value="UTC+1:00" /> <Enumeration key="8" value="UTC+2:00" /> <Enumeration key="12" value="UTC+3:00" /> <Enumeration key="14" value="UTC+3:30" /> <Enumeration key="16" value="UTC+4:00" /> <Enumeration key="18" value="UTC+4:30" /> <Enumeration key="20" value="UTC+5:00" /> <Enumeration key="22" value="UTC+5:30" /> <Enumeration key="23" value="UTC+5:45" /> <Enumeration key="24" value="UTC+6:00" /> <Enumeration key="26" value="UTC+6:30" /> <Enumeration key="28" value="UTC+7:00" /> <Enumeration key="32" value="UTC+8:00" /> <Enumeration key="35" value="UTC+8:45" /> <Enumeration key="36" value="UTC+9:00" /> <Enumeration key="38" value="UTC+9:30" /> <Enumeration key="40" value="UTC+10:00" /> <Enumeration key="42" value="UTC+10:30" /> <Enumeration key="44" value="UTC+11:00" /> <Enumeration key="46" value="UTC+11:30" /> <Enumeration key="48" value="UTC+12:00" /> <Enumeration key="51" value="UTC+12:45" /> <Enumeration key="52" value="UTC+13:00" /> <Enumeration key="56" value="UTC+14:00" /> </Enumerations> <AdditionalValues> <Enumeration key="-128" value="time zone offset is not known"/> </AdditionalValues> </Field> </Value> </Characteristic> 


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)


Characteristic 2A2B represents the current time on the device, and it has a multi-level nesting of the fields, the descriptions and formats of which you can independently. I will give only the code to read the full 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(); // ??? 


Here are some important points.
First, the notes of all the GATT specifications 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 the low byte goes to ByteArray 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 third: I never figured out what Adjust Reason is . Who knows - share the information :).

References:


Source: https://habr.com/ru/post/251937/


All Articles