L2CAP Layer = Channel Manager + L2CAP Resource Manager

Переваливаемся в высокоуровневый блок Bluetooth Host, оккупированный L2CAP уровнем. Logical Link Control and Adaptation Protocol (L2CAP) — протокол, работающий поверх созданных логических соединений, обеспечивающий инкапсуляцию, сегментацию и восстановление пакетных данных от всех вышележащих приложений.

Транспортная архитектура

В процессе знакомства с блоками архитектуры у вас уже могла выстроиться картина общей транспортной архитектуры Bluetooth, которая представляет собой трехуровневую модель:

В дальнейшем в тексте я буду использовать слово “каналы” для обозначения Channels и “соединения” для Links.

На картинке выше представлен путь юникастного асинхронного трафика по транспортной архитектуре. Именно этот тип трафика характерен для передачи “пакетного” аудио.


SCO vs ACL

Если внимательно посмотреть на предыдущий рисунок, то на уровнях Logical Links и Logical Transports чаще всего встречаются аббревиатуры ACL и (e)SCO. Это два глобальных типа логических соединений между Bluetooth-устройствами, которые служат для передачи разного рода трафика вышестоящих приложений.

По ACL (Asynchronous Connection-Oriented Links) соединениям передается асинхронный, пакетный трафик с возможностью повторной отправки в случае потерь при доставке, сегментации и управления потоком.

SCO-соединения, в свою очередь, по сути организованы по принципу коммутации каналов с постоянной пропускной способностью 64кбит/с и синхронной передачей данных в тайм-слотах. SCO-каналы, например, используются профилем Headset для потоковой передачи голоса абонента от телефона к гарнитуре.

НЕ нашли? Не то? Что вы ищете?

Согласно архитектуре Host Controller Interface, каждая его команда (HCI command) должна сопровождаться ответным событием (HCI Event). Ответ всегда возвращает статус команды (Success или код ошибки), а так же, опционально, запрошенные командой значения.

Ниже приведены три HCI команды на этапе самоинициализации модуля и события-ответы на них.


Поиск и обнаружение устройств

После того, как Bluetooth собрал информацию “о себе”, я запустил поиск устройств. Когда вы зажимаете кнопку до состояния мигающего индикатора, устройство переводится в режим прослушивания канала обнаружения (Inquiry Channel). Когда девайс услышит код доступа “ответьте все” на этом канале, он отправит информацию о своем присутствии.

Как и любой процесс обращения верхних уровней к железной части Bluetooth, все начинается с команды от HCI:


Здесь интерес представляет поле LAP. На самом деле это ни что иное, как аналог мультикаст адреса (general access code), увидев который на канале обнаружения, Bluetooth-устройства обязательно оповестят о своем присутствии ответным сообщением.

В итоге все девайсы, получившие general access code на своем физическом канале для обнаружения, отвечают сообщениями Inquiry Response, в которых:


указан MAC адрес устройства, его главный и второстепенные классы (Major Class и Minor Class), а также поддерживаемые сервисы.

Я выделил два параметра: первый — Sink — свидетельствует о том, что устройство может выступать в роли приемника аудиосигнала, а второй — Advanced Audio Distribution — что аппарат поддерживает тот самый A2DP-профиль.

Подключение

После процедуры поиска картина мира для Bluetooth-устройства становится ясна, самое время переходить к фазе подключения, или, как этот процесс называют в спецификации — Paging.

Для подключения оборудования также выделен отдельный физический канал. Важно отметить, что физические каналы Bluetooth работают в режиме двусторонней передачи (дуплекс). Использование одного физического канала для двунаправленной передачи осуществляется по принципу временного разделения каналов (TDM). При таком подходе передатчик и приемник должны иметь синхронизированные тактовые генераторы, чтобы передавать и принимать информацию в нужные моменты времени.

Так как каждое Bluetooth-устройство оснащено своим собственным генератором, то ни о какой изначальной синхронизации между ними, естественно, речи не идет. Синхронизации добивается Link Controller в процессе установления соединения.

Происходит это следующим образом: в процессе поиска master-устройство получает от ответчиков среди прочих параметров еще и их значение тактового генератора. Затем, на этапе установления соединения master-устройство передает предполагаемое значение смещения тактового генератора для slave-устройства (параметр Clock Offset в скриншоте выше), тем самым ускоряя процесс синхронизации двух генераторов.

Самым важным полем команды Create Connection на подключение является идентификатор удаленного устройства — его Bluetooth-адрес (BD_ADDR). Вслед за командой контроллеру на установление соединения в бой вступает LMP протокол, который полностью управляет процессом организации логических соединений, поверх которых впоследствии будет гулять наш трафик:

Если помните, в начале статьи я рассказывал о методе Adaptive Frequency Hopping, позволяющем избежать интерференции на уже занятых частотах? Так вот, карта используемых частот как раз и передается в LMP сообщении Set AFH. В процессе работы я замечал новые появления данных пакетов с другой картой частот, что свидетельствует о постепенном мониторинге эфира на предмет страдающих от интерференции каналов.

Итогом процесса установления соединения станет присвоение связи двух Bluetooth устройств идентификатора Connection Handle.

Сопряжение (Pairing)

Окей, мы установили физическое соединение с устройством, синхронизировали генераторы устройств и готовы к передачи служебной и пользовательской информации в тайм-слотах, чего не хватает? Спаривания. Наши устройства пока не доверяют друг другу, а значит никакой пользовательский трафик недопустим к передаче.

Т. к. оба устройства поддерживают версию спецификации Bluetooth 3.0, то им доступен метод аутентификации Secure Simple Pairing (и его подметод Just Works), позволяющий аутентифицировать и авторизовать устройства без ввода каких-либо пин-кодов.

L2CAP in action

В главе, посвященной транспортной архитектуре, изображена схема иерархии каналов и соединений, на вершине которой находится L2CAP-протокол. Именно его очередь и наступает сразу после процессов аутентификации устройств.

Структурная схема архитектурных блоков L2CAP-уровня повествует о его возможностях по сегментации, повторной отправке, управлению потоками и ресурсами.

При этом важно уяснить, что асинхронные данные от любых приложений будут скормлены L2CAP-протоколу, который подготовит данные к отправке нижним уровням стека.

Для того, чтобы от процедуры спаривания устройств перейти к непосредственно информационному обмену, хорошо бы знать, а какие профили поддерживает сопряженное устройство, умеет ли оно воспроизводить аудио или орагнизовывать обмен файлами? На эти вопросы отвечает протокол Service Discovery (SDP). Так как это протокол верхнего уровня, ему не обойтись без услуг L2CAP-протокола, который специально для этого создаст канал. Давайте посмотрим, как это происходит.

В моем примере после успешного спаривания устройств появился первый L2CAP-пакет, содержащий следующие поля:

Команда Connection Request, как подсказывает КО, инициирует создание соединения с L2CAP уровнем slave-устройства, при этом в структуре пакета есть интересные для нас поля.

L2CAP протокол использует концепцию каналов, конечные точки такого канала в паре master-slave идентифицируются при помощи 2-байтного CID (Channel Identification). CID 0x0001 — зарезервированный идентификатор канала для терминирования трафика сигнализации L2CAP протокола, что логично, ведь именно к сообщениям сигнализации относится команда Connection Request (Channel ID: 0x0001 в нижней части скриншота).

Следующее важное поле — это PSM (Protocol/Service Multiplexer). Значение PSM говорит о том, для какого протокола или сервиса мы организовываем L2CAP канал и, как видите, речь идет о канале для Service Discovery Protocol.


Service Discovery

L2CAP хорошо потрудился и организовал канал для передачи данных протокола верхнего уровня SDP, который, как мы выяснили, поможет узнать, какие сервисы поддерживаются на удаленном устройстве.

Происходит это в форме следующего диалога:

— умеешь ли ты “_какой-нибудь сервис_”?

— да, умею, и вот его характеристики (в противном случае ответ “нет, не умею, спрашивай далее”).

На запросы всех сервисов, кроме Audio Sink и AV Remote Controller я получил негативный ответ, а значит колонка, что логично, умеет только воспроизводить аудио и давать управляющие сигналы мастер устройству (например при нажатии на кнопку pause на колонке, на паузу устанавливается проигрывание у источника).

После того, как SDP узнал о собеседнике все, что мог, самое время переходить к непосредственной передаче аудио, за которую отвечает…

Audio/Video Distribution Transport Protocol

За организацию и управление аудио/видео потоками отвечает именно этот парень. И в моем случае разобраться в логике его работы можно было, даже не погружаясь в 160-страничную спецификацию.

Диаграмма работы AVDTP довольно понятна. Чтобы запустить поток, требуется открыть два канала: один управляющий (signalling) и один, непосредственно, для передаваемых аудио/видео данных.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7