BLE & GATT или как отправить данные по Bluetooth.
Разрабатывая кормушку для кота, я в итоге прикрутил к ней блютус. Конечно, можно поставить на телефон обычный Bluetooth to Serial Terminal и спокойно слать нужные команды. Но так как мы не ищем простых путей, я решил написать свое приложение (на JS + Cordova) для общения с модулем HM-10. Однако, общение оказалось не таким простым, как c обычными Bluetooth устройствами. А все почему? Да потому что устройства BLE имеют немного другой принцип коммуникации.
BLE
Принцип работы BLE описан уже в его названии: Low Energy. Протокол подразумевает передачу данных короткими пакетами по необходимости, затем – выключение передатчика. Низкое энергопотребление частично достигается применением именно этого принципа. Вместо классического тандема в обычном Bluetooth, устройства BLE связываются друг с другом лишь при необходимости отправки или получения информации.
Протокол BLE строго структурирован по принципу своей коммуникации с другими устройствами. Вначале девайсы изучают доступные сервисы для отправки/принятия данных; неотъемлемая часть этих сервисов – их характеристики (characteristics), определяющие тип данных для будущей передачи. Характеристики, из соображений наглядности, могут иметь в своём составе описания-дескрипторы (descriptors), которые помогают определить тип данных. К примеру, разберём сервис под названием «Heart Rate Monitor» (монитор частоты сердцебиения) – среди его характеристик присутствуют такие, как «измерение пульса».
Большинство API для Bluetooth LE позволяют искать локальные устройства и определять доступные в них сервисы, характеристики и дескрипторы.
Термины и концепции протокола BLE
Предлагаю вашему вниманию краткий обзор ключевых терминов протокола BLE и его концепций. До начала работы над проектом BLE нужно понимать каждый из них.
Профиль общих атрибутов (GATT)
Профиль общих атрибутов (General Attribute Protocol, GATT) – это обязательный профиль с общими спецификациями отправки и приёма коротких порций данных, известных в Bluetooth Low Link под названием «атрибуты». Все нынешние профили приложений LE основаны на GATT. Институт стандартизации и разработки протокола – Bluetooth Special Interest Group уже задал для устройств BLE несколько профилей. Эти профили представляют собой спецификации, описывающие способ применения и взаимодействия с устройствами.
Протокол атрибутов (ATT)
Протокол атрибутов (он же Attribute Protocol, ATT) – основывается на GATT. ATT – оптимизированный протокол, созданный исключительно для устройств BLE. Принцип ATT – отсылать столь малое количество байтов, насколько это возможно. У каждого атрибута есть уникальный универсальный идентификатор, UUID. Он представляет собой стандартизированный 128-битный строковый ID, используемый для идентификации уникальной информации. Формат атрибутов, передаваемых как ATT, бывает двух типов: характеристики и сервисы:
Характеристика (Characteristic)
Характеристика содержит однозначный параметр, а также дескрипторы. Количество дескрипторов может быть равно нулю, то есть это не обязательная часть характеристики. Дескрипторы описывают значение характеристики.
Дескрипторы (Descriptors)
Дескрипторы представляют собой определённые атрибуты, которые описывают значение характеристики. Дескрипторы могут быть в виде понятных описаний на вполне человеческом языке, определять единицы измерений, а также задавать ряд допустимых значений.
Сервис (Service)
Сервис это совокупность характеристик. Список существующих профилей на основе GATT можно просмотреть здесь.
Работа с GATT в Cordova
Для большей наглядности взаимосвязи этих терминов приведем схему
Т.е. профайл устройства HM-10 имеет несколько сервисов, каждый из которых включает себя различные характеристики.
Пока не особо понятно, как мне теперь со всем этим работать. Естетсвенно, порыскав в гугле я начал пробовать все это на практике.
Для Cordova есть модуль для работы с BLЕ - BLE Central. Подключив его и посмотрев характеристики моего HM-10, я увидел следующее.
Вот наши сервисы:
А вот наши характеристики:
В блоге BLE нам говорят о том, что стандартный режим работы с HM-10 это работа с сервисом 0000ffe0-0000-1000-8000-00805f9b34fb, также упоминают единственную характеристику 0000ffe1-0000-1000-8000-00805f9b34fb.
Т.е. в описаниях сервисов и характеристик uuid указан неполностью (сервис - ffe0, характеристика - ffe1)
Однако это все я узнал немного позднее. Сначала я экспериментировал с передачей данных подключаясь к устройствам исходя из описания характеристик.
bleService = connectedDevice.characteristics.find(function(item){
return item.properties.indexOf('Read') > -1 && item.properties.indexOf('WriteWithoutResponse') > -1
})
Мне нужно было найти такую характеристику, которая позволяла бы передавать и получать данные. Как я понял, описание этих характеристик и сервисов должно быть в тех документации к каждому BLE-устройству.
Подключаемся к устройству через функцию ble.connect(device_uuid)
.
Отключитсья можно через ble.disconnect(device_uuid)
(неожиданно, да?).
Отправляем данные через ble.write(device_uuid, service, characteristic, stringToBytes(data), ...callbacks)
;
Чтобы получить данные от устройства нам нужно подписаться на обновления ble.startNotification(connectedDevice.id, bleService.service, bleService.characteristic, ...callbacks)
.
В принципе, этого мне было достаточно, для того чтобы передавать нужные команды и получать фидбек от устройства.
Если у Вас есть что добавить, уточнить или указать мне на неточности или ошибки, пишите комментарии. Потому что некоторые углубленные моменты для меня остались непонятны :)
В статье были исользованы материалы с хабра и оф сайта Bluetooth
Присоединяйтесь к нашим каналам FrontEndDev и Web Stack и моему личному блогу Sleepless Tech в Telegram, чтобы не пропустить самое интересное из мира Web!