...

вторник, 3 марта 2015 г.

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

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

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




Сканируя сервисы и характеристики своего macbook, увидел следующие сервисы:


  • UUID: 180A — Device Information

  • UUID: D0611E78-BBB4-4591-A5F8-487910AE4366 — Continuity

  • ...


Сервис Continuity




Сервис Continuity служит для передачи данных между связанными Apple устройствами, подробнее здесь: http://ift.tt/1wPQ5eD. Если будет время разобраться в формате передаваемых данных — напишу об этом отдельный пост.

Сервис 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 устройство и заглянуть какие данные оно предоставляет. Мой iPhone показал мне следующие сервисы:


  • UUID: 180F

  • UUID: 1805

  • UUID: 7905F431-B5CE-4E99-A40F-4B1E122D00D0



Сервис 7905F431-B5CE-4E99-A40F-4B1E122D00D0, это сервис центра уведомлений Apple, подробнее здесь: http://ift.tt/18IWwLt. Будет время, попробую разобраться в формате данных и напишу отдельный пост по работе с 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://ift.tt/1DOAroZ" xmlns:xsi="http://ift.tt/ra1lAU" 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 приложения для сканирования сервисов и получения информации с имеющихся характеристик


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий