В этом примере показано моделирование устройств Bluetooth ® Low Energy с профилем сердечного ритма с помощью библиотеки Communications Toolbox™ для протокола Bluetooth ®.
Спецификация ядра Bluetooth [1] включает версию Low Energy для низкоскоростных беспроводных персональных сетей, которая упоминается как Bluetooth Low Energy (BLE) или Bluetooth Smart. Стек BLE состоит из: профиля типовых атрибутов (GATT), протокола атрибутов (ATT), протокола диспетчера безопасности (SMP), протокола логического управления Ссылки и адаптации (L2CAP), Ссылки Слоя (LL) и физического слоя (PHY). BLE был добавлен к стандарту для устройств с низким энергопотреблением, генерирующих небольшие объемы данных, таких как оповещения об уведомлениях, используемые в таких приложениях, как автоматизация дома, здравоохранение, фитнес и Интернет вещей (IoT).
ATT построен на верхнюю часть из L2CAP слоев BLE. ATT задает набор модулей протокольных данных (PDU), которые используются для обмена данными в профилях на основе GATT.
GATT является сервисной средой, созданной с использованием ATT. GATT обрабатывает генерацию запросов или ответов на основе данных приложения от более высоких слоев или PDU ATT, полученного от нижнего уровня. Он хранит информацию в виде сервисов, признаков и дескрипторов признаков. Он использует архитектуру клиент-сервер.
Терминология ГАТТ:
Сервис: Сервис является набором данных и связанного поведения для выполнения конкретной функции или функции. Пример: Служба сердечного ритма, которая позволяет измерять сердечный ритм.
Характеристика: Характеристика является значением, используемым в службе вместе с ее разрешениями. Пример: Характеристика измерения сердечного ритма содержит информацию об измеренном значении сердечного ритма.
Характеристический дескриптор: Дескрипторы характеристического поведения. Пример: Дескриптор строения характеристики клиента (CCCD), описывает, должен ли сервер уведомлять клиента в ответе, содержащем значение характеристики.
GATT-Client: инициирует команды и запросы к серверу и получает ответы, указания и уведомления, отправляемые сервером.
GATT-сервер: принимает входящие команды и запросы от клиента и отправляет ответы, показания и уведомления клиенту.
Профиль сердечного ритма
Профиль сердечного ритма (HRP) [2] является низкоэнергетическим профилем на основе GATT, заданным Bluetooth Special Interest Group (SIG). HRP определяет связь между сервером ГАТТ устройства датчика сердечного ритма, такого как повязка на запястье, и клиентом ГАТТ, таким как смартфон или планшет. HRP широко используется в фитнес-приложениях для сбора измерений сердечного ритма.
% Check if the 'Communications Toolbox Library for the Bluetooth Protocol' % support package is installed or not. commSupportPackageCheck('BLUETOOTH');
В этом сценарии GATT-сервер представляет собой запястье с полосой пульса, а GATT-клиент - смартфон.
% Create objects for GATT-server and GATT-client devices.
gattServer = helperBLEGATTServer;
gattClient = helperBLEGATTClient;
Первоначально клиент HRP обнаруживает сервисы, характеристики, характерные дескрипторы, определенные на сервере. После обнаружения клиент подписывается на уведомления об измерении сердечного ритма.
Клиенты выполняют операцию обнаружения услуг, чтобы получить информацию о доступных услугах. При обнаружении службы клиент вызывает 'Discover all primary services'
путем отправки запроса типа Read by group ATT PDU. Сервер отвечает доступными службами и связанными с ними указателями, отправляя ATT PDU «Read by group type response». Указатель является уникальным идентификатором атрибута, который динамически назначается сервером.
Запрос клиента на услуги на сервере
Функция generateATTPDU генерирует PDU ATT, соответствующий данной подпроцессе, как указано в спецификации ядра Bluetooth.
% Preallocate a variable to store the generated link layer packets. pcapPackets = cell(1, 9); count = 1; % Configure a GATT client to discover services available at the server. gattClient.SubProcedure = 'Discover all primary services'; serviceDiscReqPDU = generateATTPDU(gattClient); % Transmit the application data (|serviceDiscReqPDU|) to the server through % PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(serviceDiscReqPDU); count = count+1;
Получение запроса клиента на сервере
Сервер получает от клиента запрос типа Read by group и отправляет список доступных служб в ATT PDU ответа типа Read by group.
Функция receiveData декодирует входящий PDU как GATT-сервер и возвращает соответствующий объект строения ATT PDU и соответствующий PDU ответа.
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode the received ATT PDU and generate response PDU, if applicable. [attServerRespPDU, serviceDiscReqCfg, gattServer] = receiveData(gattServer, receivedPDU); fprintf("Received service discovery request at the server:\n") serviceDiscReqCfg % Transmit the application response data (|attServerRespPDU|) to the client % through PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(attServerRespPDU); count = count+1;
Received service discovery request at the server: serviceDiscReqCfg = bleATTPDUConfig with properties: Opcode: 'Read by group type request' StartHandle: '0001' EndHandle: 'FFFF' AttributeType: '2800'
Получение ответа сервера в клиенте
Функция receiveData декодирует входящий PDU как GATT-клиент и возвращает соответствующий объект строения ATT PDU и соответствующий PDU ответа, если применимо.
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode received ATT PDU and generate response PDU, if applicable. [~, serviceDiscRespCfg] = receiveData(gattClient, receivedPDU); gattClient.StartHandle = serviceDiscRespCfg.StartHandle; gattClient.EndHandle = serviceDiscRespCfg.EndHandle; % Expected response from the server: |'Read by group type response'| or % |'Error response'|. if strcmp(serviceDiscRespCfg.Opcode, 'Error response') fprintf("Received error response at the client:\n") serviceDiscRespCfg serviceDiscRespMsg = ['Error response(''' serviceDiscRespCfg.ErrorMessage ''')']; else fprintf("Received service discovery response at the client:\n") serviceDiscRespCfg service = helperBluetoothID.getBluetoothName(serviceDiscRespCfg.AttributeValue); serviceDiscRespMsg = ['Service discovery response(''' service ''')']; end
Received service discovery response at the client: serviceDiscRespCfg = bleATTPDUConfig with properties: Opcode: 'Read by group type response' StartHandle: '0001' EndHandle: '0006' AttributeValue: [2x2 char]
Сервис состоит из нескольких характеристик. Для каждой услуги существуют информационные элементы, которыми обмениваются клиент и сервер. Каждый информационный элемент может содержать дескрипторы его поведения. Характеристика содержит значение и связанные с ним дескрипторы. После обнаружения услуги клиенты выполняют обнаружение характеристик, чтобы узнать о характеристиках, определенных в услуге. При обнаружении характеристик клиент вызывает 'Discover all characteristics of service'
путем отправки 'Read by type request' ATT PDU. Сервер отвечает доступными характеристиками и связанными с ними указателями, отправляя ATT PDU 'Read by type response'.
Запрос клиента на характеристики на сервере
% Configure a GATT client to discover all the available characteristics at % the server. gattClient.SubProcedure = 'Discover all characteristics of service'; chrsticDiscReqPDU = generateATTPDU(gattClient); % Transmit the application data (|chrsticDiscReqPDU|) to the server through % PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(chrsticDiscReqPDU); count = count+1;
Получение запроса клиента на сервере
Декодирует полученный запрос и возвращает список доступных характеристик в ответе типа Read by ATT PDU.
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode received ATT PDU and generate response PDU, if applicable. [chrsticDiscRespPDU, chrsticDiscReqCfg, gattServer] = receiveData(gattServer, receivedPDU); fprintf("Received characteristic discovery request at the server:\n") chrsticDiscReqCfg % Transmit the application response data (|chrsticDiscRespPDU|) to the % client through PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(chrsticDiscRespPDU); count = count+1;
Received characteristic discovery request at the server: chrsticDiscReqCfg = bleATTPDUConfig with properties: Opcode: 'Read by type request' StartHandle: '0001' EndHandle: '0006' AttributeType: '2803'
Получение ответа сервера в клиенте
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode received ATT PDU and generate response PDU, if applicable. [~, chrsticDiscRespCfg] = receiveData(gattClient, receivedPDU); % Expected response from the server: |'Read by type response'| or |'Error % response'|. if strcmp(chrsticDiscRespCfg.Opcode, 'Error response') fprintf("Received error response at the client:\n") chrsticDiscRespCfg chrsticDescRespMsg = ['Error response(''' chrsticDiscRespCfg.ErrorMessage ''')']; else fprintf("Received characteristic discovery response at the client:\n") attributeValueCfg = helperBLEDecodeAttributeValue(... chrsticDiscRespCfg.AttributeValue, 'Characteristic'); attributeValueCfg chrsticDescRespMsg = ['Characteristic discovery response(''' attributeValueCfg.CharacteristicType ''')']; end
Received characteristic discovery response at the client: attributeValueCfg = helperBLEAttributeValueConfig with properties: AttributeType: 'Characteristic' BroadcastFlag: 'False' ReadFlag: 'False' WriteWithoutResponseFlag: 'False' WriteFlag: 'False' NotifyFlag: 'True' IndicateFlag: 'False' AuthenticatedSignedWritesFlag: 'False' ExtendedPropertiesFlag: 'False' CharacteristicValueHandle: '0003' CharacteristicType: 'Heart rate measurement'
Характеристика может состоять из нескольких дескрипторов характеристик. После обнаружения характеристики клиенты выполняют обнаружение дескрипторов характеристик, чтобы узнать о списке дескрипторов и их указателях. При обнаружении характеристического дескриптора клиент вызывает 'Discover all descriptors'
путем отправки «Информационного запроса» ATT PDU. Сервер отвечает доступными дескрипторами характеристик и связанными с ними указателями, отправляя «информационный ответ» ATT PDU.
Запрос клиента на дескрипторы характеристик на сервере
% Configure a GATT client to discover all the available characteristic % descriptors at the server. gattClient.SubProcedure = 'Discover all descriptors'; gattClient.StartHandle = dec2hex(hex2dec(chrsticDiscRespCfg.AttributeHandle)+1, 4); chrsticDescDiscReqPDU = generateATTPDU(gattClient); % Transmit the application data (|chrsticDescDiscReqPDU|) to the client % through PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(chrsticDescDiscReqPDU); count = count+1;
Получение запроса клиента на сервере
Декодирует полученный запрос и возвращает список доступных дескрипторов характеристик в информационном ответе ATT PDU.
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode received ATT PDU and generate response PDU, if applicable. [chrsticDescDiscRespPDU, chrsticDescDiscReqCfg, gattServer] = receiveData(gattServer, receivedPDU); fprintf("Received characteristic descriptor discovery request at the server:\n") chrsticDescDiscReqCfg % Transmit the application response data (|chrsticDescDiscRespPDU|) to the % client through PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(chrsticDescDiscRespPDU); count = count+1;
Received characteristic descriptor discovery request at the server: chrsticDescDiscReqCfg = bleATTPDUConfig with properties: Opcode: 'Information request' StartHandle: '0003' EndHandle: '0006'
Получение ответа сервера в клиенте
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode received ATT PDU and generate response PDU, if applicable. [~, chrsticDescDiscRespCfg] = receiveData(gattClient, receivedPDU); % Expected response from the server: |'Information response'| or |'Error % response'|. if strcmp(chrsticDescDiscRespCfg.Opcode, 'Error response') fprintf("Received error response at the client:\n") chrsticDescDiscRespCfg chrsticDescDiscRespMsg = ['Error response(''' chrsticDescDiscRespCfg.ErrorMessage ''')']; else fprintf("Received characteristic descriptor discovery response at the client:\n") chrsticDescDiscRespCfg descriptor = helperBluetoothID.getBluetoothName(chrsticDescDiscRespCfg.AttributeType); chrsticDescDiscRespMsg = ['Characteristic descriptor discovery response(''' descriptor ''')']; end
Received characteristic descriptor discovery response at the client: chrsticDescDiscRespCfg = bleATTPDUConfig with properties: Opcode: 'Information response' Format: '16 bit' AttributeHandle: '0004' AttributeType: '2902'
После обнаружения дескрипторов характеристик клиент может включать или отключать уведомления по своему значению характеристики. Чтобы включить уведомления, клиент должен задать бит уведомления (первый бит) значения дескриптора строения характеристики клиента (CCCD) путем вызова 'Write characteristic value'
подпроцесса.
Клиент подписывается на уведомления на сервере
% Configure a GATT client to enable the notifications of Heart rate % measurement characteristic. gattClient.SubProcedure = 'Write characteristic value'; gattClient.AttributeHandle = chrsticDescDiscRespCfg.AttributeHandle; gattClient.AttributeValue = '0100'; enableNotificationReqPDU = generateATTPDU(gattClient); % Transmit the application data (|enableNotificationReqPDU|) to the client % through PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(enableNotificationReqPDU); count = count+1;
Получение запроса клиента на сервере
Декодирует принятый запрос и отправляет ответ в ATT PDU ответа на запись.
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode received ATT PDU and generate response PDU, if applicable. [enableNotificationRespPDU, enableNotificationReqCfg, gattServer] = receiveData(gattServer, receivedPDU); fprintf("Received enable notification request at the server:\n") enableNotificationReqCfg % Transmit the application response data (|enableNotificationRespPDU|) to % the client through PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(enableNotificationRespPDU); count = count+1;
Received enable notification request at the server: enableNotificationReqCfg = bleATTPDUConfig with properties: Opcode: 'Write request' AttributeHandle: '0004' AttributeValue: [2x2 char]
Получение ответа сервера в клиенте
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode received ATT PDU and generate response PDU, if applicable. [~, enableNotificationRespCfg] = receiveData(gattClient, receivedPDU); % Expected response from the server: |'Write response'| or |'Error % response'|. if strcmp(enableNotificationRespCfg.Opcode, 'Error response') fprintf("Received error response at the client:\n") enableNotificationRespCfg enableNotificRespMsg = ['Error response(''' enableNotificationRespCfg.ErrorMessage ''')']; else fprintf("Received enable notification response at the client:\n") enableNotificationRespCfg enableNotificRespMsg = 'Notifications enabled(''Heart rate measurement '')'; end
Received enable notification response at the client: enableNotificationRespCfg = bleATTPDUConfig with properties: Opcode: 'Write response'
Когда клиент включает уведомления для характеристики, сервер периодически уведомляет клиента о значении характеристики (измерение сердечного ритма).
Сервер HRP уведомляет клиента об измерении частоты сердечных сокращений после подписки.
Сервер отправляет уведомления клиенту
Функция notifyHeartRateMeasurement генерирует PDU уведомлений, как указано в спецификации ядра Bluetooth.
% Reset the random number generator seed. rng default % Measure heart rate value using sensor (generate a random number for heart % rate measurement value). heartRateMeasurementValue = randi([65 95]); % Notify the heart rate measurement. [gattServer, notificationPDU] = notifyHeartRateMeasurement(gattServer, ... heartRateMeasurementValue); % Transmit the application data (|notificationPDU|) to the client through % PHY. [bleWaveform, pcapPackets{count}] = helperBLETransmitData(notificationPDU); count = count+1;
Получение уведомлений сервера в клиенте
% Decode the received BLE waveform and retrieve the application data. receivedPDU = helperBLEDecodeData(bleWaveform); % Decode received ATT PDU and generate response PDU, if applicable. [~, notificationCfg] = receiveData(gattClient, receivedPDU); fprintf("Received notification at the client:\n") % Decode the received heart rate measurement characteristic value. heartRateCharacteristicValue = helperBLEDecodeAttributeValue(... notificationCfg.AttributeValue, 'Heart rate measurement'); heartRateCharacteristicValue heartRateMeasurementValue = heartRateCharacteristicValue.HeartRateValue; % Visualize the BLE GATT Client-Server model. helperBLEVisualizeHRPFrame(serviceDiscRespMsg, chrsticDescRespMsg, ... chrsticDescDiscRespMsg, enableNotificRespMsg, heartRateMeasurementValue);
Received notification at the client: heartRateCharacteristicValue = helperBLEAttributeValueConfig with properties: AttributeType: 'Heart rate measurement' HeartRateValueFormat: 'UINT8' SensorContactStatus: 'Contact detected' EnergyExpendedFieldFlag: 'Present, Units: Kilo Joules' RRIntervalFieldFlag: 'Present' HeartRateValue: 90 EnergyExpended: 100 RRInterval: 10
Этот пример использует blePCAPWriter
объект для экспорта сгенерированных PDU в файл с расширением.pcap или расширением.pcapng. Чтобы проанализировать и визуализировать этот файл, используйте анализатор пакетов третьей части, такой как Wireshark.
Создайте объект типа blePCAPWriter
и укажите имя файла захвата пакетов.
% Create the BLE PCAP Writer file object pcapObj = blePCAPWriter("FileName", "bleHRP");
Используйте write
функция для записи всех блоков PDU BLE LL в файл PCAP. Постоянная timestamp
задает время захвата PDU. В этом примере время захвата одинаково для всех PDU.
timestamp = 124800; % timestamp (in microseconds) % Write all the LL PDUs to the PCAP file for idx = 1:numel(pcapPackets) write(pcapObj, pcapPackets{idx}, timestamp, "PacketFormat", "bits"); end % Clear the object clear pcapObj; fprintf("Open generated pcap file 'bleHRP.pcap' in a protocol analyzer to view the generated frames.\n")
Open generated pcap file 'bleHRP.pcap' in a protocol analyzer to view the generated frames.
Поскольку сгенерированные пакеты профиля сердечного ритма соответствуют стандарту Bluetooth, можно открыть, проанализировать и визуализировать файл PCAP с помощью стороннего анализатора пакетов, такого как Wireshark [3]. Данные, показанные на этих рисунках, используют пакеты профиля сердечного ритма, сгенерированные в этом примере.
Запрос на обнаружение службы
Ответ на обнаружение службы
Уведомление о значении измерения сердечного ритма
Этот пример продемонстрировал моделирование устройств BLE с профилем сердечного ритма с помощью сценария клиент-сервер GATT, как указано в спецификации ядра Bluetooth [1]. Можно использовать анализатор пакетов, чтобы просмотреть сгенерированные системы координат.
В примере используются следующие функции:
bleATTPDUConfig
: Создайте объект строения для PDU BLE ATT
bleATTPDU
: BLE ATT PDU генерация
bleATTPDUDecode
: BLE ATT PDU декодирование
blePCAPWriter
: Создайте BLE PCAP или PCAPNG файл средства записи объект
В примере используются следующие помощники:
helperBLEGATTClient: предоставляет методы в профиль типового атрибута
helperBLEGATTServer: Создает объект сервера GATT
helperBLEAttributeValueConfig: создайте объект строения для значения атрибута BLE
helperBLEGenerateAttributeValue: генерация значений атрибута BLE
helperBLEDecodeAttributeValue: декодер значений атрибутов BLE
helperBLEDecodeData: Декодирует полученный сигнал и извлекает данные приложения
helperBLEPrependAccessAddress: заполняет PDU канального слоя адресом доступа
helperBLETransmitData: Передайте данные приложения путем генерации волны BLE
helperBluetoothID: идентификаторы Bluetooth и их имена, присвоенные Bluetooth Special Interest Group (SIG)
helperBLEVisualizeHRPFrame: Визуализация систем координат профиля сердечного ритма (HRP), обмененных в примере HRP.
helperBLEPlotHRPFrames: постройте график обмена системами координат данных между сервером профиля сердечного ритма и клиентом
Веб-сайт Bluetooth ® Technology. Bluetooth Technology Website | Официальный сайт Bluetooth Technology. Доступ к 8 июля 2020 года. https://www.bluetooth.com/.
«Разработка/LibpcapFileFormat - Wireshark Wiki». Доступ к 8 июля 2020 года. https://wiki.wireshark.org/Development/LibpcapFileFormat.
Группа, The Tcpdump. «Общий репозиторий Tcpdump/Libpcap». Доступ к 8 июля 2020 года. https://www.tcpdump.org.