- Клиент Bluetooth GATT
- Общие сведения
- Примеры
- Отправка запросов для ближайших устройств
- Подключение к устройству
- Перечисление поддерживаемых служб и характеристик
- Выполнение операций чтения и записи с характеристикой
- Подписка на уведомления
- Bluetooth Low Energy в универсальная платформа Windows приложениях
- Центральное и периферийное устройство
- Атрибуты
- Клиент и сервер
- Наблюдатели и издатели (маяки)
- См. также:
Клиент Bluetooth GATT
В этой статье показано, как использовать клиентские API-интерфейсы универсального атрибута Bluetooth (GATT) для приложений универсальная платформа Windows (UWP).
Необходимо объявить возможность bluetooth в Package.appxmanifest.
Общие сведения
С помощью API-интерфейсов в пространстве имен Windows.Devices.Bluetooth.GenericAttributeProfile разработчики получают доступ к устройствам Bluetooth с низким энергопотреблением. Функции устройств Bluetooth с низким энергопотреблением обеспечиваются коллекцией следующих элементов:
Службы определяют функциональный контракт устройства с низким энергопотреблением и содержат набор характеристик, определяющих службу. Характеристики в свою очередь содержат описывающие их дескрипторы. Эти 3 элемента, как правило, называют атрибутами устройства.
API-интерфейсы Bluetooth GATT для устройств с низким энергопотреблением предоставляют доступ к объектам и функциям, а не собственно к механизмам передачи. Кроме того, API-интерфейсы Bluetooth GATT позволяют разработчикам работать с устройствами Bluetooth с низким энергопотреблением и выполнять следующие задачи:
- Обнаружение атрибутов
- Чтение и запись значений атрибутов
- Регистрация обратного вызова для события Characteristic ValueChanged
Для эффективной реализации разработчик должен иметь представление о службах и характеристиках GATT, которые будет обрабатывать приложение. Он должен уметь преобразовывать значения отдельных характеристик, например двоичных данных, предоставляемых API-интерфейсами, в полезные данные, отображаемые для пользователей. API Bluetooth GATT предоставляют только основные примитивы, необходимые для взаимодействия с устройством Bluetooth с низким энергопотреблением. Для интерпретации данных необходимо определить профиль приложения. Для этого используется либо стандартный профиль Bluetooth SIG, либо настраиваемый профиль, реализованный поставщиком устройства. Профиль создает контракт привязки между приложением и устройством в отношении содержимого передаваемых данных и их интерпретации.
Для удобства Bluetooth SIG ведет список доступных общих профилей.
Примеры
Отправка запросов для ближайших устройств
Существует два основных метода отправки запросов для ближайших устройств:
Второй метод подробно рассматривается в документации по классу Advertisement, поэтому здесь упоминается только основной принцип — поиск адресов ближайших устройств Bluetooth, соответствующих критериям конкретного фильтра объявления. Когда адрес найден, можно вызвать BluetoothLEDevice.FromBluetoothAddressAsync для получения ссылки на устройство.
Вернемся к методу DeviceWatcher. Устройство Bluetooth с низким энергопотреблением ничем не отличается от любых других устройств в Windows. Запрос к этому устройству можно отправить с помощью API-интерфейсов перечисления. Используйте класс DeviceWatcher, чтобы передать строку запроса с указанием искомых устройств:
// Query for extra properties you want returned string[] requestedProperties = < "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" >; DeviceWatcher deviceWatcher = DeviceInformation.CreateWatcher( BluetoothLEDevice.GetDeviceSelectorFromPairingState(false), requestedProperties, DeviceInformationKind.AssociationEndpoint); // Register event handlers before starting the watcher. // Added, Updated and Removed are required to get all nearby devices deviceWatcher.Added += DeviceWatcher_Added; deviceWatcher.Updated += DeviceWatcher_Updated; deviceWatcher.Removed += DeviceWatcher_Removed; // EnumerationCompleted and Stopped are optional to implement. deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted; deviceWatcher.Stopped += DeviceWatcher_Stopped; // Start the watcher. deviceWatcher.Start();
После запуска DeviceWatcher вы получите DeviceInformation для каждого устройства, соответствующего критериям запроса, в обработчике события Added для соответствующих устройств. Чтобы получить более полное представление о методе DeviceWatcher, см. полный пример кода на Github.
Подключение к устройству
После обнаружения нужного устройства используйте DeviceInformation.Id, чтобы получить объект BluetoothLEDevice для соответствующего устройства:
async void ConnectDevice(DeviceInformation deviceInfo) < // Note: BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent. BluetoothLEDevice bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id); // . >
С другой стороны, при удалении всех ссылок на объект BluetoothLEDevice инициируется автоматическое отключение от устройства после короткого периода ожидания (если на это устройство не ссылаются другие приложения в системе).
Если приложению снова потребуется доступ к устройству, создайте объект устройства заново и предоставьте доступ к характеристике (см. следующий раздел). После этого операционная система будет инициировать повторное подключение по требованию. Если устройство находится поблизости, вы получите доступ к нему. В противном случае будет получен ответ с ошибкой DeviceUnreachable.
Создание объекта BluetoothLEDevice путем вызова только этого метода не обязательно инициирует подключение. Чтобы инициировать подключение, задайте для параметра GattSession.MaintainConnection значение true или вызовите метод обнаружения некэшированных служб на BluetoothLEDevice или выполните операцию чтения и записи на устройстве.
- Если для GattSession.MaintainConnection задано значение true, то система будет бесконечно ожидать подключения и будет подключаться, когда устройство станет доступным. Приложению нечего ждать, так как GattSession.MaintainConnection является свойством.
- Для операций обнаружения служб и чтения и записи в GATT система ожидает конечное, но переменное время. Все, от мгновенного до считанных минут. Факторы, включающие трафик в стеке, и способ постановки запроса в очередь. Если нет других ожидающих запросов и удаленное устройство недоступно, система будет ожидать 7 (семь) секунд, прежде чем истечет время ожидания. Если есть другие ожидающие запросы, обработка каждого из запросов в очереди может занять семь (7) секунд, поэтому чем дальше ваш запрос находится в задней части очереди, тем дольше вы будете ждать.
В настоящее время вы не можете отменить процесс подключения.
Перечисление поддерживаемых служб и характеристик
Теперь, когда у вас есть объект BluetoothLEDevice, можно перейти к следующему шагу — обнаружению данных, предоставляемых устройством. Сначала необходимо запросить службы:
GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesAsync(); if (result.Status == GattCommunicationStatus.Success) < var services = result.Services; // . >
После определения нужных служб необходимо запросить характеристики.
GattCharacteristicsResult result = await service.GetCharacteristicsAsync(); if (result.Status == GattCommunicationStatus.Success) < var characteristics = result.Characteristics; // . >
ОС возвращает список объектов GattCharacteristic только для чтения, с которыми затем можно выполнять операции.
Выполнение операций чтения и записи с характеристикой
Характеристика — неотъемлемая часть обмена данными с использованием GATT. Она содержит значение, представляющее уникальный фрагмент данных на устройстве. Например, характеристика Battery Level содержит значение, представляющее уровень заряда аккумулятора устройства.
Изучите свойства характеристики, чтобы определить поддерживаемые операции:
GattCharacteristicProperties properties = characteristic.CharacteristicProperties if(properties.HasFlag(GattCharacteristicProperties.Read)) < // This characteristic supports reading from it. >if(properties.HasFlag(GattCharacteristicProperties.Write)) < // This characteristic supports writing to it. >if(properties.HasFlag(GattCharacteristicProperties.Notify)) < // This characteristic supports subscribing to notifications. >
Если поддерживается чтение, можно прочитать значение:
GattReadResult result = await selectedCharacteristic.ReadValueAsync(); if (result.Status == GattCommunicationStatus.Success) < var reader = DataReader.FromBuffer(result.Value); byte[] input = new byte[reader.UnconsumedBufferLength]; reader.ReadBytes(input); // Utilize the data as needed >
Запись в характеристику выполняется по аналогичному шаблону:
var writer = new DataWriter(); // WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle writer.WriteByte(0x01); GattCommunicationStatus result = await selectedCharacteristic.WriteValueAsync(writer.DetachBuffer()); if (result == GattCommunicationStatus.Success) < // Successfully wrote to device >
DataReader и DataWriter не являются незаменимыми при работе с необработанными буферами, которые вы получаете из многих API Bluetooth.
Подписка на уведомления
Проверьте свойства характеристики и убедитесь, что характеристика поддерживает операцию Indicate или Notify.
Параметр Указывает считается более надежным, так как каждое событие изменения значения связано с подтверждением от клиентского устройства. Операция Notify используется чаще, так как большинство транзакций GATT обеспечивает экономию энергии, а не высочайший уровень надежности. Так или иначе, все эти операции обрабатываются на уровне контроллера без участия приложения. Мы будем называть их просто «уведомлениями».
Перед получением уведомлений необходимо обеспечить выполнение двух условий:
- Запись в дескриптор конфигурации характеристик клиента (Client Characteristic Configuration, CCCD)
- Обработка события Characteristic.ValueChanged
Запись в CCCD сообщает серверу, что данный клиент должен получать оповещение каждый раз, когда меняется значение определенной характеристики. Для этого выполните следующие действия.
GattCommunicationStatus status = await selectedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync( GattClientCharacteristicConfigurationDescriptorValue.Notify); if(status == GattCommunicationStatus.Success) < // Server has been informed of clients interest. >
Теперь событие ValueChanged для GattCharacteristic будет вызываться при каждом изменении значения на удаленном устройстве. Осталось только реализовать обработчик:
characteristic.ValueChanged += Characteristic_ValueChanged; . void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) < // An Indicate or Notify reported that the value has changed. var reader = DataReader.FromBuffer(args.CharacteristicValue) // Parse the data however required. >
Bluetooth Low Energy в универсальная платформа Windows приложениях
В этом разделе представлен обзор Bluetooth LE в приложениях универсальная платформа Windows (UWP) (дополнительные сведения о Bluetooth LE см. в спецификации Bluetooth Core Specification версии 4.0).
Bluetooth с низким энергопотреблением (LE) является спецификацией, определяющей протоколы для обнаружения и обмена данными между энергоэффективными устройствами. Обнаружение устройств выполняется с помощью протокола Generic Access Profile (GAP). После обнаружения обмен данными между устройствами выполняется с помощью протокола Generic Attribute (GATT).
появились в Windows 10 версии 1703
Протоколы GATT и GAP можно внедрить в приложение UWP с помощью указанных ниже пространств имен.
Центральное и периферийное устройство
Две основные роли обнаружения называются центральное устройство и периферийное устройство. Как правило, Windows работает в режиме центрального устройства и подключается к различным периферийным устройствам.
Атрибуты
Профиль cGeneric Attribute (GATT) определяет структуру данных и режимы работы, с помощью которых взаимодействуют два устройства Bluetooth LE. Атрибут является основным блоком построения GATT. К main типам атрибутов относятся службы, характеристики и дескрипторы. Эти атрибуты действуют по-разному между клиентами и серверами, поэтому полезнее обсудить их взаимодействие в соответствующих разделах.
Служба частоты сердечных сокращений выражается в форме API сервера GATT
Клиент и сервер
После установления подключения устройство, которое содержит данные (обычно небольшой датчик IoT или носимое устройство), называется сервером. Устройство, которое использует данные для выполнения функций, называется клиентом. Например, компьютер под управлением Windows (клиент) считывает данные с монитора частоты пульса (сервер) для отслеживания оптимальных тренировок пользователя. Дополнительные сведения см. в разделах Клиент GATT и Сервер GATT.
Наблюдатели и издатели (маяки)
Кроме ролей центрального и периферийного устройств, существуют роли наблюдателя и вещателя. Вещатели обычно называются маяками, они не взаимодействуют через GATT, поскольку используют ограниченное пространство, предоставленное в пакете объявления для передачи данных. Аналогично наблюдатель не должен устанавливать подключения для получения данных, он сканирует ближайшие рекламные объявления. Чтобы настроить Windows для отслеживания ближайших рекламных объявлений, используйте класс BluetoothLEAdvertisementWatcher. Чтобы транслировать полезные данные маяка, используйте класс BluetoothLEAdvertisementPublisher. Дополнительные сведения см. в разделе Объявления Bluetooth LE.