Чтение GATT-характеристик Bluetooth устройства

от автора

Привет, хабраюзеры!

Работая над своей ANE библиотекой для работы с Bluetooth LE в AIR приложении для iOS+OSX, обнаружил что помимо ваших собственных сервисов и характеристик для обмена информацией, у bluetooth-устройств есть стандартные. Статья о том, как считывать информацию с этих характеристик. Скажу сразу я не большой знаток bluetooth и всего что с ним связано, и для мне все это в новинку 🙂 Поехали…

Сервисы и характеристики OSX устройства
Сканируя сервисы и характеристики своего macbook, увидел следующие сервисы:
UUID: 180A — Device Information UUID: D0611E78-BBB4-4591-A5F8-487910AE4366 — Continuity …

Сервис Continuity
Сервис Continuity служит для передачи данных между связанными Apple устройствами, подробнее здесь: www.apple.com/ru/ios/whats-new/continuity/. Если будет время разобраться в формате передаваемых данных — напишу об этом отдельный пост.

Сервис 180A (Device Information)
Рассмотрим сервис 180A — информация об устройстве. Этот сервис является часть GATT-профиля. Открываем страницу GATT-сервисов, находим сервис по идентификатору 180A. В списке доступных указаны различные характеристики:
Manufacturer Name String Model Number String … и еще много всего
Конкретно мое устройство показало только две доступные характеристики:
UUID: 2A29 — Manufacturer Name String UUID: 2A24 — Model Number String
Открываем страницу GATT-характеристик, находим там нужную характеристику по uuid, например 2A29. В описании сказано что характеристика имеет одно единственное поле и оно имеет формат utf8s:

Это значит что прочитать значение в AIR приложении можно следующим способом:
var bytes:ByteArray = …; var string:String = bytes.readUTFBytes(bytes.bytesAvailable);
В моем случае я получил значения:
2A29 — Apple Inc 2A24 — MacBookPro10,2
С этими характеристиками было все просто, идем дальше.

Сервисы и характеристики iOS устройства
Попробуем теперь сканировать iOS устройство и заглянуть какие данные оно предоставляет. Мой iPhone показал мне следующие сервисы:
UUID: 180F UUID: 1805 UUID: 7905F431-B5CE-4E99-A40F-4B1E122D00D0 …

Сервис 7905F431-B5CE-4E99-A40F-4B1E122D00D0, это сервис центра уведомлений Apple, подробнее здесь: developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html. Будет время, попробую разобраться в формате данных и напишу отдельный пост по работе с bluetooth-сервисами устройств Apple.

Сервис 180F (Battery Service)
Сервис 180F — это информация о заряде батареи. Этот сервис имеет одну единственную характеристику 2A19, в описании которой сказано что характеристика имеет одно единственное поле формата uint8:

Прочитать эту информацию в AIR приложении можно так:
var bytes:ByteArray = …; var level:int = bytes.readByte();
Получим значение от 0 до 100, соответствующее уровню заряда батареи устройства.

Сервис 1805 (Current Time Service)
Как видим из описания сервиса 1805 — это информация о текущем времени. Мое iOS устройство показало только две характеристики у этого сервиса:
UUID: 2A0F — Local Time Information UUID: 2A2B — Current Time

Характеристика 2A0F (Local Time Information)
Характеристика 2A0F имеет два поля:

Открываем описание первого поля Time Zone и видим что оно содержит в себе одно поле формата sint8.

Второе поле у сервиса 2A0F это Daylight Saving Time — информация о переходе на летнее время, формат: uint8.

Итак, чтобы прочитать характеристику 2A0F в AIR приложении используем следующий код:
var bytes:ByteArray = …; var timeZoneValue:int = bytes.readByte(); // считываем Time Zone var dstValue:int = bytes.readUnsignedByte(); // считываем Daylight Saving Time
В моем случае я получил значения:
TimeZone: 12 Daylight Saving Time: 0
Значение 12 в поле TimeZone соответствует временной зоне UTC+3:00, согласно XML файлу:
Список временных зон в 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>

cкачать который можно в описании поля Time Zone нажав кнопку Download / View напротив имени поля.

Характеристика 2A2B (Current Time)
Характеристика 2A2B представляет текущее время на устройстве, и она имеет многоуровневую вложенность полей, ознакомиться с описаниями и форматами которых вы можете самостоятельно. Я приведу только код, для считывания полной информации о текущем времени устройства:
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(); // ???

Здесь есть несколько важных моментов.
Первое: в примечаниях всех GATT спецификаций сказано:
The fields in the above table are in the order of LSO to MSO. Where LSO = Least Significant Octet and MSO = Most Significant Octet.
Это значит что в ByteArray первым идет младший байт, в AIR это можно указать с помощью свойства endian:
bytes.endian = Endian.LITTLE_ENDIAN;

Второе: поле fraction, как следует из описания — это 1/256я секунды, т.е. чтобы получить миллисекунды пишем код:
var milliseconds:int = Math.floor(fraction/256*1000);

И третье: я так и не разобрался что такое Adjust Reason. Кто знает — поделитесь информацией :).

Ссылки:
GATT сервисы GATT характеристики Видео, демонстрирующие чтение GATT-характеристик с OSX и iOS устройств в AIR приложении ANE библиотека для работы с Bluetooth в AIR приложении. Там же есть готовые iOS и OSX приложения для сканирования сервисов и получения информации с имеющихся характеристик http://habrahabr.ru/post/251937/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *