BLE под микроскоп (ATTы GATTы…)

BLE под микроскоп (ATTы GATTы...)

BLE под микроскоп (ATTы GATTы…)

Част 1, преглед

Измина доста време от излизането на първата спецификация за Bluetooth 4.0. И въпреки че темата за BLE е много интересна, тя все още отблъсква много разработчици поради своята сложност. В предишните си статии разглеждах основно най-ниското ниво, Link Layer и Physical Layer. Това ни позволи да избегнем необходимостта да прибягваме до такива сложни и объркващи концепции като протокола за атрибути (ATT) и общия профил на атрибутите (GATT). Въпреки това, няма къде да отидете, без да ги разберете, е невъзможно да се разработят съвместими устройства. Днес бих искал да споделя това знание с вас. В моята статия ще разчитам на учебник за начинаещи от сайта Nordic. Така че да започваме.

Защо всичко е толкова трудно?

Според мен веднага стана ясно, че управлението на устройства чрез смартфони е много обещаваща и дълготрайна тема. Затова решиха да го структурират веднага и максимално. Така че производителите на различни джаджи да не измислят свои собствени протоколи, които след това ще бъдат несъвместими. Оттук и трудността. Още на първия етап те се опитаха да вкарат всичко възможно в протокола BLE. И няма значение дали ще бъде полезно по-късно или не. Освен това те предвидиха възможност за разширяване на списъка с устройства за бъдещето.

Нека да разгледаме снимката, където е нарисувана диаграмата на протокола BLE. Състои се от няколко слоя. Най-ниският физически слой (PHY) отговаря за радиоканала на устройството. Link Layer(LL) съдържа цялата поредица от байтове в предаденото съобщение. В предишни статии проучихме точно това. Интерфейсът на хост контролер (HCI) е протокол за обмен между BLE слоеве или чипове, ако контролерът и хостът са внедрени на различни чипове. Протоколът за контрол и адаптиране на логическа връзка (L2CAP) отговаря за формирането на пакети, рамкирането, контрола на грешките и сглобяването на пакети. Протоколът за управление на сигурността (SMP) отговаря за криптирането на пакети. Общият профил за достъп (GAP) е отговорен за първоначалния обмен на данни между устройствата, за да се определи „Кой кой е“. Включва също сканиране и реклама. В тази статия ще се спра на двете останали части на протокола – GATT и ATT. GATT е надстройка на ATT, така че те са тясно преплетени.

BLE под микроскоп (ATTы GATTы...)

За да опростя историята, бих искал да се обърна към една аналогия. Чух го някъде и бих искал да го подкрепя. Представете си BLE устройство като библиотека с няколко рафта. Всеки рафт е отделна тема. Например, имаме рафтове с научна фантастика, математика и енциклопедии. На всеки рафт има книги с определена тема. А някои книги дори имат хартиени отметки с бележки. Освен това имаме малък хартиен каталог на всички книги. Ако си спомняте, училищните библиотеки са тясна кутия с хартиени карти. С тази аналогия, шкафът е профилът на нашето устройство. Рафтовете са услуги, книгите са характеристики, а каталогът е таблица с атрибути. Отметките в книгите са дескриптори, за които също ще говоря по-късно по-подробно.

Всеки, който е разработвал устройства, знае, че много проекти имат подобни части от код. Факт е, че много устройства имат подобна функционалност. Например, ако устройствата се захранват от батерии, тогава проблемът със зареждането и наблюдението на нивото им ще бъде същият. Същото важи и за сензорите. Всъщност обектно-ориентиран подход към програмирането „осигурява възможност за създаване на обекти, които комбинират свойства и поведение в самостоятелен съюз, който след това може да се използва повторно“. По мое мнение BLE опита подобен подход. Профилите са разработени от Bluetooth Special Interest Group (SIG). Устройства от различни производители, които имат еднакви профили, трябва да работят помежду си без затруднения. Профилите от своя страна се състоят от услуги и услуги от характеристики, допълнени от дескриптори. Най-общо може да изглежда така:

BLE под микроскоп (ATTы GATTы...)

Например, разгледайте диаграмата на профила на пулсомер (фитнес гривна). Състои се от две услуги и няколко характеристики. От него веднага става ясна профилната йерархия. Характеристиката на контролната точка нулира общия разход на калории до нула.

1. Услугата за сърдечен ритъм включва три характеристики (0x180D):
    a) Задължителна характеристика на сърдечната честота (0x2A37)
    b) Допълнителна характеристика на позицията на сензора за тяло (0x2A38)
    c) Условни характеристики на контролната точка на сърдечната честота (0x2A39)
2. Услуга за поддръжка на батерията (0x180F):
    a) Задължителна характеристика на нивото на зареждане на батерията (0x2A19)

UUID

За да имаме уникален достъп до елементите на профила (услуги, характеристики и дескриптори), трябва да ги номерираме по някакъв начин. За тази цел се въвежда концепция като Universally Unique ID (UUID) или Universally Unique Identifier. UUID е посочен в скобите на всеки ред. И тук има една особеност. За UUID решихме да използваме код с дължина 16 и 128 бита. Защо питаш? В протокола BLE всичко е свързано с пестенето на енергия. Следователно размерът от 16 бита е доста разумен. Малко вероятно е в близко бъдеще да бъдат създадени повече от 65 хиляди. уникални услуги и характеристики. В момента всичко, което можеше да е вече преброено (помнете откъде дойде това - „и той ви преброи“ :-)) Номерирани елементи профили, услуги, характеристики и дескриптори можете да разгледате линковете.

Мисля обаче, че всеки помни историята с 4 байта IP адреси в интернет. Първоначално решихме, че това е достатъчно, но сега все още не можем да превключим на 6-байтов адрес. За да не повтори тази грешка и да даде воля на игривите ръце на DIYers, SIG незабавно реши да въведе 128-битови UUID. Това лично на мен ми напомня за нелицензираната честотна лента 433 MHz, която беше дадена на всякакви кулибини от радиоканала. В нашия случай 128-битов идентификатор на услуги и характеристики беше изведен от фермата. Това означава, че ние, за нашите услуги и устройства, можем да използваме почти всяка 128-битова стойност. Все пак вероятността да излезете със същия UUID клони към нула.

Всъщност кратките 16-битови UUID имат разширение до 128-битова стойност. В спецификацията това разширение се нарича Bluetooth Base UUID и има стойност 00000000-0000-1000-8000-00805F9B34FB. Ако например 16-битовият атрибут UUID има стойност 0x1234, тогава еквивалентният 128-битов UUID ще има стойност 00001234-0000-1000-8000-00805F9B34FB. И дори е дадена съответната формула:

                                128_битова_стойност = 16_битова_стойност * 2^96 + Bluetooth_Base_UUID

Не знам откъде идва това магическо число. Ако някой от читателите знае, нека пише в коментарите (Потребител с псевдоним Sinopteek вече е направил това. Вижте коментарите). Що се отнася до 128-битовите UUID, по принцип можете да използвате специален от генераторакой ще го направи вместо вас.

АТти ГАТИ...

Всъщност тогава започва забавлението. Нека ви напомня, че ATT се основава на връзка клиент-сървър. Сега разглеждаме сървърното устройство. Той съдържа информация като стойности на сензора, състояние на превключвателя на светлината, данни за местоположение и др. Сега, когато всички „участници в нашия парад“ са номерирани, трябва по някакъв начин да ги поставим в паметта на устройството. За да направим това, ние ги поставяме в таблица, наречена таблица с атрибути. Запомнете това добре. Това е самото сърце на BLE. Това ще разгледаме по-нататък. Сега ще наричаме всеки ред атрибут. Тази таблица се намира дълбоко в стека и по правило нямаме директен достъп до нея. Инициализираме го и имаме достъп до него, но това, което се случва вътре, е скрито от нас зад седем печата.

Нека да разгледаме снимката от спецификацията, но преди това веднага бих искал да обърна внимание на честото объркване в термините, а именно в дескрипторите. Ролята на дескриптора е да допълва описанието на характеристиката. Когато е необходимо да се разширят неговите възможности, тогава се използват дескриптори. Те също са атрибути и също като услугите и характеристиките се намират в таблицата с атрибути. Ще ги разгледаме подробно във втората част на статията. Понякога обаче дескрипторите се отнасят до номера на реда в таблицата с атрибути. Това трябва да се има предвид. За да избегнем объркване, ще използваме термина „указател на атрибут“ за тези цели.
BLE под микроскоп (ATTы GATTы...)

Така че атрибутът е дискретна стойност, която има следните свойства, свързани с него:
1. Справка за атрибут е индексът на таблицата, съответстващ на атрибута
2. Типът на атрибута е UUID, който описва неговия тип
3. Стойността на атрибута е данните, индексирани от указателя на атрибута
4. Разрешенията за атрибут са част от атрибут, разрешенията, които не могат да бъдат прочетени или записани с помощта на протокола за атрибути

Как да разберем всичко това? Указателят на атрибута е, относително казано, неговия номер в нашата таблица.
Той позволява на клиента да препраща към атрибут в заявки за четене или запис. Можем да номерираме нашите редове (атрибути) от 0x0001 до 0xFFFF. В нашата връзка с библиотеката това е номерът на картата в хартиения каталог. По същия начин, както в библиотечния каталог, картите са подредени в нарастващ ред на броя. Номерът на всеки следващ ред трябва да е по-голям от предишния. Както в библиотеката, понякога някои карти се губят, така и при нас може да има пропуски в номерирането на редовете. Това е разрешено. Основното е, че вървят прогресивно.

Типът на атрибута определя какво представлява атрибутът. По аналогия с езика C,
където има булеви, числови променливи и низове, така е и тук. По тип атрибут разпознаваме
с какво имаме работа и как можем да продължим да работим с този атрибут. По-долу ще разгледаме някои специфични типове атрибути. Например „декларация на услуга“ (0x2800), „декларация на характеристики“ (0x2803), „декларация на дескриптор“ (0x2902).

Стойността на даден атрибут е действителното му значение, простете за тавтологията. Ако типът на атрибута е низ, тогава стойността на атрибута може да бъде например слоганът „Здравей свят !!!“. Ако типът на атрибута е „декларация за услуга“, тогава неговата стойност е самата услуга. И понякога това е информация за това къде да намерите други атрибути и техните свойства.

Разрешенията за атрибути позволяват на сървъра да разбере дали е разрешен достъп за четене или запис.
Имайте предвид, че тези разрешения се отнасят само за стойността на атрибута, а не за указателя, типа или самото поле за разрешение. Тези. ако записването на атрибути е разрешено, тогава можем да променим, например, реда „Hello World !!!“ към реда „Добро утро“. Но не можем да забраним писането на нов ред или да променим типа на атрибута и да обозначим реда като „декларация за услуга“. Когато клиент се свърже със сървър, клиентът изисква неговите атрибути. Това позволява на клиента да знае какво може да предостави сървърът. Въпреки че не е необходимо да четете и записвате стойностите.

Как изглежда

Концепцията на GATT е да групира атрибутите в таблица с атрибути заедно в много специфичен и логичен ред. Нека разгледаме по-отблизо профила на сърдечната честота по-долу. Най-лявата колона на тази таблица не е задължителна. Той просто ни описва какво представлява този ред (атрибут). Всички останали колони вече са ни познати.

BLE под микроскоп (ATTы GATTы...)

В горната част на всяка група винаги имаме атрибут за декларация на услугата. Типът му винаги е 0x2800, а указателят зависи от това колко атрибута вече присъстват в таблицата. Неговите разрешения винаги са само за четене, без никакво удостоверяване или оторизация. Ще говорим за тези концепции малко по-късно. Стойността е друг UUID, който идентифицира каква е услугата. В таблицата стойността е 0x180D, която се определя от Bluetooth SIG като услуга за сърдечен ритъм.

След обявяването на услугата следва обявяването на характеристиката. По форма е подобна на декларация за услуга. Неговият UUID винаги е 0x2803 и неговите разрешения винаги са само за четене без удостоверяване или оторизация. Нека да разгледаме полето Стойност на атрибута, което включва някои данни. Винаги съдържа указател, UUID и набор от свойства. Тези три елемента описват последващото деклариране на характеристичната стойност. Указателят естествено обозначава местоположението на декларацията на характеристичната стойност в таблицата с атрибути. UUID описва какъв тип информация или стойност можем да очакваме. Например стойността на температурата, състоянието на превключвателя на светлината или някаква друга произволна стойност. И накрая свойства, които описват как може да се взаимодейства с характеристичната стойност.

Тук ни очаква още един капан. Той е свързан с разрешения за атрибути и характерни свойства. Нека да разгледаме снимката на свойствата на битовото поле от спецификацията.

BLE под микроскоп (ATTы GATTы...)

Както можете да видите, тук също има полета, които предоставят възможности за четене и запис. Може би се чудите защо имаме разрешения за четене/запис за атрибут и свойство
четене/запис за характерна стойност? Не трябва ли винаги да са едни и същи? Факт е, че свойствата за характеристичната стойност всъщност са само препоръки за клиента, използван в GATT и приложните слоеве. Това са просто съвети за това, което клиентът може да очаква от атрибута за декларация на характеристиките. Нека разгледаме това по-подробно. Какви типове разрешения има даден атрибут?

1. Разрешения за достъп:
     - четене
     — запис
     - Чети и пиши
2. Разрешение за удостоверяване:
     - изисква се удостоверяване
     - не се изисква удостоверяване
3. Разрешение за оторизация:
     — изисква се разрешение
     - не се изисква разрешение

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

Дескриптор

Да се ​​върнем на нашата маса. След деклариране на стойността на характеристика са възможни следните декларации на атрибути:
1. Нова декларация за характеристики (една услуга може да има много характеристики)
2. Декларация за нова услуга (може да има много от тях в таблицата)
3. Деклариране на манипулатор

В случая на характеристиката за измерване на сърдечната честота, в нашата таблица, декларацията на характеристичната стойност е придружена от декларацията на дескриптора. Дескрипторът е атрибут с допълнителна информация за характеристика. Има няколко типа дескриптори. За тях ще говорим подробно във втората част на тази статия. Засега ще се докоснем само до дескриптора на конфигурацията на клиентските характеристики (CCCD). Той има UUID, равен на 0x2902. Използвайки този дескриптор, клиентът има способността да активира индикация или известие на сървъра. Разликата между тях е малка, но все пак я има. Уведомлението не изисква потвърждение за получаване от клиента. Индикацията изисква това, въпреки че се случва на ниво GATT, а не достига до ниво на приложение. Защо така, ще попитате? Уви, не знам това. Нека само да кажа, че северните експерти препоръчват използването на известия. Освен това проверката на целостта на пакета (чрез CRC) се извършва и в двата случая.

Заключение

В края на статията бих искал да кажа това. Последната таблица е малко объркваща. Избрах го обаче, защото се отдава Статия, на които разчитам. Във втората част на моята статия възнамерявам да навляза по-дълбоко в спецификацията на BlueTooth 4.0. Там ни очакват още правилни схеми и чертежи. В третата част бих искал да анализирам дневника, получен с помощта на програмата Wireshark от една от джаджите, и да видя „на живо“ цялата теория, която изучаваме.

Служител на групата компании "Сателит Цезар"
Владимир Печерских

Източник: www.habr.com

Добавяне на нов коментар