В этом примере показано, как генерировать и декодировать пакеты канального уровня Bluetooth ® с использованием библиотеки Communications Toolbox™ Library для протокола Bluetooth ®.
Спецификация ядра Bluetooth [1] включает версию с низким энергопотреблением для низкоскоростных беспроводных персональных сетей, которая называется Bluetooth Low Energy (BLE) или Bluetooth Smart. Стек BLE состоит из: Generic Attribute Profile (GATT), Attribute Protocol (ATT), Security Manager Protocol (SMP), Logical Link Control and Adaptation Protocol (L2CAP), канального уровня (LL) и физического уровня. BLE был добавлен в стандарт для устройств с низким энергопотреблением, генерирующих небольшие объемы данных, таких как уведомления, используемые в таких приложениях, как домашняя автоматизация, здравоохранение, фитнес и Интернет вещей (IoT).

Спецификация ядра Bluetooth [1] определяет два вида PHY для BLE. Каждый PHY имеет свой собственный формат пакета.
(i) Некодированные PHY (1 Мбит/с и 2 Мбит/с)
Кодированные PHY (125 кбит/с и 500 кбит/с)
Кодированные PHY используют кодирование с прямым исправлением ошибок (FEC) (со схемой кодирования S = 8 или S = 2) для пакетов. На чертежах показаны некодированные и кодированные форматы пакетов PHY.
Формат пакета радиоинтерфейса LE для некодированного PHY

Формат пакета радиоинтерфейса LE для кодированного PHY

Библиотека Toolbox™ связи для протокола Bluetooth генерирует пакеты LL, которые состоят из блока протокольных данных (PDU) и циклического избыточного контроля (CRC), показанных в пакете PHY.
BLE классифицирует 40 каналов РЧ на три рекламных канала (индексы канала: 37, 38, 39) и тридцать семь каналов данных (индексы канала: от 0 до 36). Канальный уровень BLE определяет две категории PDU, PDU рекламного канала и PDU канала данных. В этих двух категориях PDU существуют различные типы PDU. Поле адреса доступа в формате пакета радиоинтерфейса различает PDU канала данных и PDU рекламного канала. Каждая категория PDU имеет свой формат.
Блоки PDU рекламного канала (см. раздел 2,3, Part-B, Vol-6 в [1]) используются перед созданием соединения LL. Эти PDU передаются только по рекламным каналам и используются при установлении соединения LL. Блок PDU рекламного канала имеет 16-битный заголовок и полезную нагрузку переменного размера.
PDU рекламного канала имеет следующий формат пакета:

Этот пример иллюстрирует формирование и декодирование PDU индикации рекламы. Список других поддерживаемых PDU рекламных каналов см. в разделе PDUType имущество bleLLAdvertisingChannelPDUConfig объект.
Рекламный признак: рекламный PDU признака используется, когда устройство хочет рекламировать себя. Этот PDU содержит рекламные данные, относящиеся к профилю приложения устройства.
% Check if the 'Communications Toolbox Library for the Bluetooth Protocol' % support package is installed or not. commSupportPackageCheck('BLUETOOTH');
Вы можете использовать bleLLAdvertisingChannelPDU функция формирования PDU рекламного канала. Эта функция принимает объект конфигурации bleLLAdvertisingChannelPDUConfig. Этот объект конфигурирует поля, необходимые для формирования PDU рекламного канала.
Формирование рекламной индикации
Для создания PDU «Рекламная индикация» создайте bleLLAdvertisingChannelPDUConfig объект с PDUType установить в значение 'Advertising indication'.
cfgLLAdv = bleLLAdvertisingChannelPDUConfig('PDUType', ... 'Advertising indication');
Сконфигурируйте поля:
% Advertiser address cfgLLAdv.AdvertiserAddress = '012345ABCDEF'; % Advertising data cfgLLAdv.AdvertisingData = '0201060D09426174746572792056312E30'
cfgLLAdv =
bleLLAdvertisingChannelPDUConfig with properties:
PDUType: 'Advertising indication'
ChannelSelection: 'Algorithm1'
AdvertiserAddressType: 'Random'
AdvertiserAddress: '012345ABCDEF'
AdvertisingData: [17x2 char]
Создайте PDU «Рекламная индикация».
llAdvPDU = bleLLAdvertisingChannelPDU(cfgLLAdv);
Вы можете использовать bleLLAdvertisingChannelPDUDecode функция декодирования PDU рекламного канала. Эта функция выводит следующую информацию:
status: Перечисление типа blePacketDecodeStatus, указывая, было ли декодирование LL успешным.
cfgLLAdv: Объект конфигурации PDU рекламного канала LL типа bleLLAdvertisingChannelPDUConfig, который содержит декодированные свойства LL.
Предоставьте PDU рекламного канала и опциональную пару «имя-значение», задающую формат PDU входных данных для функции bleLLAdvertiingStartPDUDecode. Входной формат по умолчанию - «» bits «».
Декодирование рекламной индикации
[llAdvDecodeStatus, cfgLLAdv] = bleLLAdvertisingChannelPDUDecode(llAdvPDU); % Observe the outputs % Decoding is successful if strcmp(llAdvDecodeStatus, 'Success') fprintf('Link layer decoding status is: %s\n\n', llAdvDecodeStatus); fprintf('Received Advertising channel PDU configuration is:\n'); cfgLLAdv % Decoding failed else fprintf('Link layer decoding status is: %s\n', llAdvDecodeStatus); end
Link layer decoding status is: Success
Received Advertising channel PDU configuration is:
cfgLLAdv =
bleLLAdvertisingChannelPDUConfig with properties:
PDUType: 'Advertising indication'
ChannelSelection: 'Algorithm1'
AdvertiserAddressType: 'Random'
AdvertiserAddress: '012345ABCDEF'
AdvertisingData: [17x2 char]
Блоки PDU канала данных (см. раздел 2.4, Part-B, Vol-6 в [1]) используются после создания соединения LL. Блоки PDU канала данных состоят из двух подкатегорий: блоки PDU данных LL и блоки PDU управления LL. PDU управления LL используются для управления соединением LL, а PDU данных LL используются для переноса данных верхнего уровня. PDU канала данных имеет 16-битный заголовок и полезную нагрузку переменного размера.
PDU канала данных имеют следующий формат пакета:

Этот пример иллюстрирует генерацию и декодирование следующих PDU. Список других поддерживаемых типов PDU управления и типов PDU данных см. в разделе Opcode и LLID свойства bleLLControlPDUConfig и bleLLDataChannelPDUConfig соответственно.
Индикация карты каналов: этот PDU управления LL используется для обновления карты каналов в одноранговом устройстве. Этот PDU содержит обновленную карту каналов, указывающую хорошие и плохие каналы.
Данные (начальный фрагмент/полный): этот PDU данных LL используется для передачи L2CAP данных в одноранговое устройство.
Вы можете использовать bleLLDataChannelPDU для формирования PDU канала данных. Эта функция принимает объект конфигурации bleLLDataChannelPDUConfig, которая конфигурирует поля, необходимые для формирования PDU канала данных. bleLLControlPDUConfig является объектом под-конфигурации в bleLLDataChannelPDUConfig, управляющие поля полезной нагрузки PDU заполняются с использованием настроек этого объекта конфигурации.
PDU канала данных используют значение инициализации CRC, полученное в пакете индикации соединения. Значение инициализации CRC, используемое при генерации и декодировании пакетов.
% CRC initialization value crcInit = 'ED321C';
Формирование PDU данных LL
Для создания PDU данных создайте bleLLDataChannelPDUConfig объект с LLID установить в значение 'Data (start fragment/complete)'.
cfgLLData = bleLLDataChannelPDUConfig('LLID', ... 'Data (start fragment/complete)');
Сконфигурируйте поля:
% CRC initialization value cfgLLData.CRCInitialization = crcInit; % Sequence number cfgLLData.SequenceNumber = 0; % Next expected sequence number cfgLLData.NESN = 1
cfgLLData =
bleLLDataChannelPDUConfig with properties:
LLID: 'Data (start fragment/complete)'
NESN: 1
SequenceNumber: 0
MoreData: 0
CRCInitialization: 'ED321C'
PDU данных используется для передачи полезной нагрузки от верхнего уровня. В этом примере используется 18-байтовая полезная нагрузка.
% Payload payload = '0E00050014010A001F004000170017000000';
Создание PDU данных с использованием полезной нагрузки и конфигурации.
llDataPDU = bleLLDataChannelPDU(cfgLLData, payload);
Формирование PDU управления LL
Чтобы создать управляющий PDU, создайте bleLLDataChannelPDUConfig объект с LLID установить в значение 'Control'.
cfgLLData = bleLLDataChannelPDUConfig('LLID', 'Control');
Сконфигурируйте поля:
% CRC initialization value
cfgLLData.CRCInitialization = crcInit
cfgLLData =
bleLLDataChannelPDUConfig with properties:
LLID: 'Control'
NESN: 0
SequenceNumber: 0
MoreData: 0
CRCInitialization: 'ED321C'
ControlConfig: [1x1 bleLLControlPDUConfig]
Можно сконфигурировать содержимое PDU управления LL с помощью bleLLControlPDUConfig.
Создание объекта конфигурации управляющего PDU с помощью Opcode установить в значение 'Channel map indication'.
cfgControl = bleLLControlPDUConfig('Opcode', 'Channel map indication');
Сконфигурируйте поля:
% Used channels cfgControl.UsedChannels = [9, 10, 12, 24, 28, 32]; % Connection event instant cfgControl.Instant = 245
cfgControl =
bleLLControlPDUConfig with properties:
Opcode: 'Channel map indication'
Instant: 245
UsedChannels: [9 10 12 24 28 32]
Назначение обновленного объекта конфигурации PDU управления ControlConfig в объекте конфигурации PDU канала данных.
% Update the data channel PDU configuration
cfgLLData.ControlConfig = cfgControl;
Создайте управляющий PDU с обновленной конфигурацией.
llControlPDU = bleLLDataChannelPDU(cfgLLData);
Вы можете использовать bleLLDataChannelPDUDecode функция декодирования PDU канала данных. Эта функция выводит следующую информацию:
status: Перечисление типа blePacketDecodeStatus, указывая, было ли декодирование LL успешным.
cfgLLData: Объект конфигурации PDU канала данных LL типа bleLLDataChannelPDUConfig, который содержит декодированные свойства LL.
payloadМассив символов n-на-2, представляющий полезную нагрузку верхнего уровня, переносимую блоками PDU данных LL.
Предоставить PDU канала данных, значение инициализации CRC и опциональную пару имя-значение, определяющую формат PDU входных данных для bleLLDataChannelPDUDecode функция. Входной формат по умолчанию - «» bits «».
Декодирование PDU данных LL
[llDataDecodeStatus, cfgLLData, payload] = ... bleLLDataChannelPDUDecode(llDataPDU, crcInit); % Observe the outputs % Decoding is successful if strcmp(llDataDecodeStatus, 'Success') fprintf('Link layer decoding status is: %s\n\n', llDataDecodeStatus); fprintf('Received Data channel PDU configuration is:\n'); cfgLLData fprintf('Size of the received upper-layer payload is: %d\n', ... numel(payload)/2); % Decoding failed else fprintf('Link layer decoding status is: %s\n', llDataDecodeStatus); end
Link layer decoding status is: Success
Received Data channel PDU configuration is:
cfgLLData =
bleLLDataChannelPDUConfig with properties:
LLID: 'Data (start fragment/complete)'
NESN: 1
SequenceNumber: 0
MoreData: 0
CRCInitialization: '012345'
Size of the received upper-layer payload is: 18
Декодирование PDU управления LL
[llControlDecodeStatus, cfgLLData] = ... bleLLDataChannelPDUDecode(llControlPDU, crcInit); % Observe the outputs % Decoding is successful if strcmp(llControlDecodeStatus, 'Success') fprintf('Link layer decoding status is: %s\n\n', llControlDecodeStatus); fprintf('Received Data channel PDU configuration is:\n'); cfgLLData fprintf('Received control PDU configuration is:\n'); cfgControl = cfgLLData.ControlConfig % Decoding failed else fprintf('Link layer decoding status is: %s\n', llControlDecodeStatus); end
Link layer decoding status is: Success
Received Data channel PDU configuration is:
cfgLLData =
bleLLDataChannelPDUConfig with properties:
LLID: 'Control'
NESN: 0
SequenceNumber: 0
MoreData: 0
CRCInitialization: '012345'
ControlConfig: [1x1 bleLLControlPDUConfig]
Received control PDU configuration is:
cfgControl =
bleLLControlPDUConfig with properties:
Opcode: 'Channel map indication'
Instant: 245
UsedChannels: [9 10 12 24 28 32]
В этом примере используется blePCAPWriter объект для экспорта созданных PDU в файл с расширением .pcap или .pcapng. Для анализа и визуализации этого файла используйте анализатор пакетов третьей части, такой как Wireshark.
Адрес предварительного доступа
Формат PCAP ожидает, что адрес доступа будет предшествовать пакету LL. Вспомогательная функция helperBLEPrependStartAddress добавляет адрес доступа к сгенерированному пакету LL.
% Advertising channel PDUs use the default access address advAccessAddress = '8E89BED6'; % Data channel PDUs use the access address obtained from 'Connection % indication' packet. A random access address is used for this example connAccessAddress = 'E213BC42'; % Prepend access address llPkts{1} = helperBLEPrependAccessAddress(llAdvPDU, advAccessAddress); llPkts{2} = helperBLEPrependAccessAddress(llDataPDU, connAccessAddress); llPkts{3} = helperBLEPrependAccessAddress(llControlPDU, connAccessAddress);
Экспорт в файл PCAP
Создание объекта типа blePCAPWriter и укажите имя файла захвата пакетов.
% Create the BLE PCAP Writer file object pcapObj = blePCAPWriter("FileName", "bleLLPackets");
Используйте 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(llPkts) write(pcapObj, llPkts{idx}, timestamp, 'PacketFormat', 'bits'); end % Clear the object clear pcapObj;
Файл PCAP, содержащий сгенерированные пакеты LL, можно открыть в анализаторе пакетов. Пакеты, декодированные анализатором пакетов, соответствуют стандартным совместимым пакетам LL, генерируемым библиотекой Communications Toolbox™ Library для протокола Bluetooth. Захваченный анализ пакетов показан ниже.
Рекламная индикация

PDU данных LL (несущий полезную нагрузку L2CAP)

PDU управления LL (индикация карты каналов)

В этом примере показано формирование и декодирование пакетов LL, указанных в стандарте Bluetooth [1]. Для просмотра сгенерированных пакетов LL можно использовать анализатор пакетов.
В примере используется следующая функция:
bleLLAdvertisingChannelPDU: Создание рекламного канала LL PDU
bleLLAdvertisingChannelPDUDecodeДекодировать рекламный канал LL PDU
bleLLAdvertisingChannelPDUConfigСоздание объекта конфигурации для генерации и декодирования PDU рекламного канала LL
bleLLDataChannelPDUСоздание PDU канала данных LL
bleLLDataChannelPDUDecodeДекодирование PDU канала данных LL
bleLLDataChannelPDUConfigСоздание объекта конфигурации для генерации и декодирования PDU канала данных LL
bleLLControlPDUConfigСоздание объекта подконфигурации, используемого при формировании и декодировании PDU канала данных
blePCAPWriter: Создание объекта записи файлов BLE PCAP или PCAPNG
В этом примере используется этот помощник:
helperBLEPrependStartAddress: добавляет PDU канального уровня с адресом доступа
Веб-сайт технологии Bluetooth ®. «Веб-сайт Bluetooth Technology | Официальный веб-сайт Bluetooth Technology». Доступ состоялся 8 июля 2020 года. https://www.bluetooth.com/.
«Development/LibpcapFileFormat - Wiki Wiki Wieshark». Доступ состоялся 8 июля 2020 года. https://wiki.wireshark.org/Development/LibpcapFileFormat.
Группа, Tcpdump. «Общий репозиторий Tcpdump/Libpcap». Доступ состоялся 8 июля 2020 года. https://www.tcpdump.org.