Uuid128 что это такое

Русские Блоги

Что такое UUID?

Что такое UUID?

Чтобы гарантировать уникальность UUID, спецификация определяет элементы, включая MAC-адрес сетевой карты, временную метку, пространство имен (Namespace), случайное или псевдослучайное число, время и другие элементы, а также алгоритм для генерации UUID из этих элементов. Сложные характеристики UUID означают, что он может быть сгенерирован только компьютером, обеспечивая его уникальность.

UUID нельзя указать вручную, если вы не рискуете дублировать UUID. Сложность UUID определяет, что «нормальные люди» не могут напрямую знать, какой объект связан с UUID.

Буквы в нем в шестнадцатеричной системе счисления, независимо от регистра.

Универсальный уникальный идентификатор (UUID) сВосемь классиковизRFC спецификация, Является 128-битным числом, также может быть выражено 32 шестнадцатеричными символами, разделенными знаком «-» посередине.

-Timestamp + номер версии UUID, разделенный на три сегмента, занимающих 16 символов (60 бит + 4 бит),
— Порядковый номер часов и зарезервированное поле, занимающее 4 символа (13 бит + 3 бит),
— идентификатор узла занимает 12 символов (48 бит),

UUID имеет несколько версий, и каждая версия имеет разные алгоритмы и разные диапазоны приложений.

UUID, версия 1: UUID на основе времени

Поскольку метка времени имеет полные 60 бит, вы можете потратить ее столько, сколько захотите, со 100 наносекундами как 1, считая с 15 октября 1582 года (может длиться 3655 лет, действительно сжечь больше цифр, 1582 интересно)

Идентификатор узла также имеет 48 битов, обычно выражаемых MAC-адресом, если есть несколько сетевых карт, просто используйте одну. Если у вас нет сетевой карты, используйте случайные числа, чтобы составить числа, или возьмите кучу другой информации, например имена хостов, и хешируйте их вместе.

16-битный порядковый номер используется только во избежание предыдущего изменения метки узла (например, смены сетевой карты), проблем с системой часов (например, замедления часов после перезапуска), пусть он будет случайным, чтобы избежать дублирования.

Но похоже, что в версии 1 не учитывалась ни проблема двух процессов на одной машине, ни параллелизм одной и той же временной метки, поэтому строгая версия 1 не была реализована, поэтому давайте рассмотрим каждый вариант.

Спящий режимCustomVersionOneStrategy.java, Что решает две проблемы версии 1 до

Стоит отметить, что 64-битный Long, состоящий из машинного процесса и идентификатора процесса, почти не изменился, и достаточно другого Long.

Вариант версии 1-MongoDB

-Timestamp (4 байта, 32 бита): находится на втором уровне и может длиться 136 лет с 1970 года.

-Machine ID (3 байта 24 бит): соедините Mac-адреса всех сетевых карт вместе, чтобы получить HashCode, и тот же int должен быть усечен, а затем 3 байта. Если вы не можете получить сетевую карту, используйте случайное число, чтобы смешать ее.

-Process ID (2 байта 16 бит): получить номер процесса из JMX. Если вы его не получили, используйте хэш или случайное число имени процесса, чтобы смешать его.

Видно, что дизайн каждого поля MongoDB немного разумнее, чем Hibernate, например, временная метка находится на втором уровне. Общая длина также была уменьшена до 12 байтов 96 бит, но если вы используете 64 бит Long для сохраненияНе могу встать, Может быть выражено только как массив байтов или шестнадцатеричная строка.

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

Диспетчер снежинок Twitter

Snowflake также является диспетчером, сервисом на основе Thrift, но вместо простого самоприращения с помощью redis он похож на UUID версии 1.

Есть только одна длинная 64-битная длина, поэтомуIdWorkerРаспределены по:

-Timestamp (42bit) Количество миллисекунд с 2012 года (по сравнению с 1970 годом) может длиться 139 лет.
— последовательность автоинкремента (12 бит, максимум 4096), автоинкремент в миллисекундах и сброс на 0 через одну миллисекунду.
-DataCenter ID (5 бит, максимум 32), значение конфигурации.
— ID рабочего (5 бит, максимум 32), значение конфигурации. Поскольку это идентификатор диспетчера, достаточно 32 диспетчеров в центре обработки данных. Зарегистрируйтесь в ZK.

Можно видеть, что, поскольку это диспетчер чисел, идентификатор машины и идентификатор процесса опускаются, поэтому он может быть выражен только одним Long.

Кроме того, для диспетчера этого типа клиент может иметь только один идентификатор за раз и не может быть получен пакетами, поэтому дополнительная задержка является проблемой.

UUID версии 2: защищенный UUID DCE

Безопасный UUID DCE (распределенной вычислительной среды) и алгоритм UUID на основе времени одинаковы, но первые 4 позиции временной метки будут заменены на POSIX UID или GID. Эта версия UUID редко используется на практике.

UUID версии 3: UUID на основе имени (MD5)

UUID на основе имени получается путем вычисления хеш-значения MD5 имени и пространства имен. Эта версия UUID гарантирует: уникальность UUID, сгенерированных разными именами в одном пространстве имен; уникальность UUID в разных пространствах имен; повторное создание UUID с одним и тем же именем в одном пространстве имен одинаково.

UUID версии 4: случайный UUID

Сгенерировать UUID на основе случайного числа или псевдослучайного числа. Вероятность повторения этого UUID можно рассчитать, но случайные вещи похожи на покупку лотерейного билета: вы не можете рассчитывать на то, что он принесет вам целое состояние, но дерьмовая удача обычно приходит случайно.

UUID версии 5: UUID на основе имени (SHA1)

похож на алгоритм UUID версии 3, за исключением того, что при вычислении значения хеш-функции используется алгоритм SHA1 (алгоритм безопасного хеширования 1).

Из различных версий UUID видно, что версия 1/2 подходит для использования в распределенной вычислительной среде и имеет высокую степень уникальности; версия 3/5 подходит для уникальных имен в определенном диапазоне. И в средах, где UUID требуются или могут генерироваться повторно; что касается версии 4, я лично рекомендую не использовать ее (хотя это самый простой и удобный вариант).

Обычно мы рекомендуем использовать UUID для идентификации объектов или постоянных данных, но лучше не использовать UUID в следующих ситуациях:

Для объектов с естественными характеристиками неповторяющихся имен лучше всего использовать UUID версии 3/5. Например, пользователи в системе. Если UUID пользователя версии 1, если вы случайно удалите его, а затем перестроите пользователя, вы обнаружите, что этот человек по-прежнему является этим человеком, а пользователь больше не является этим пользователем. (Хотя отметка как удаленная также является решением, это усложняет реализацию.)

Я не ожидал, что кто-то самостоятельно реализует генератор UUID после прочтения этой статьи, поэтому предыдущее содержание не содержит деталей алгоритма. Вот несколько доступных генераторов Java UUID:

Кроме того, в Hibernate есть также генератор UUID, но это не UUID какой-либо (стандартной) версии, и это настоятельно не рекомендуется.

Метод генерации

Собраны некоторые методы генерации UUID, организованные следующим образом

Shell

Прочитать файл /proc/sys/kernel/random/uuid Получите UUID, например:

libuuid

Необходимо связать библиотеку uuid при компиляции под Linux

В Ubuntu libuuid можно установить с помощью следующей команды:

boost uuid

Библиотека BoostЭто переносимая библиотека C ++ с открытым исходным кодом, которая обеспечивает реализацию UUID.

Следующий код может генерировать UUID

Qt QUuid

функция QUuid createUuid(); Может использоваться для генерации случайного UUID. Примеры следующие

CoCreateGuid

UUID поддерживается выше JDK 1.5, использование выглядит следующим образом:

Источник

Системный номер раздела диска UUID / GUID / serial number

На чистом диске нет никаких разделов и соответственно нет никаких номеров раздела.

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

В чем отличие UUID от GUID

UUID (Universally unique identifier «универсальный уникальный идентификатор») — UUID представляет собой 16-байтный (128-битный) номер. В каноническом представлении UUID изображают в виде числа в шестнадцатеричной системе счисления, разделённого дефисами на пять групп в формате 8-4-4-4-12.

GUID (Globally Unique Identifier) — это так называется у Microsoft — фактически это последняя реализация UUID (да, там были свои предыдущие версии и свой зоопарк).

Именно по этому актуальная разметка диска от Microsoft называется GPT (GUID Partition Table), читаем статью

В целом используется как идентификатор (в составе также закодирована дата и время создания):

Почему такая загадочная запись?

Очень удобно переводить двоичные числа в шестнадцатеричный формат (а в десятичный формат — очень неудобно).

Помним, что для половинки байта (4 бита):

BinHexDec
000000
000111
001022
001133
010044
010155
011066
011177
100088
100199
1010A10
1011B11
1100C12
1101D13
1110E14
1111F15

Т.е. один байт (8 бит) вида 11111111 легко представляется в виде FF = т.е. каждая половинка байта — это F (15 в десятичной системе).

Поэтому 128 бит легко превращаются в номер из 32 цифр в шестнадцатеричной системе счисления, 128/4 = 32

В номере UUID <8e44ac32-40e2-11ea-93a4-bff4e4da2abb> каждые два разряда фактически кодируют один байт.

Посмотрим на структуру номера

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

xxxxxxxx-xxxx-MxxxNxxx-xxxxxxxxxxxx

4 бита M обозначают версию («version») UUID, а 1-3 старших бита N обозначают вариант («variant») UUID.

Первые две цифры кодируют дату и время создания.

Такое разделение на группы основано на структуре UUID:

Название поляДлина (в байтах)Длина (число 16-ричных цифр)Содержимое
time_low48целое число, обозначающее младшие 32 бита времени
time_mid24целое число, обозначающее средние 16 бит времени
time_hi_and_version244 старших бита обозначают версию UUID, младшие биты обозначают старшие 12 бит времени
clock_seq_hi_and_res clock_seq_low241-3 старших бита обозначают вариант UUID, остальные 13-15 бит обозначают clock sequence
node61248-битный идентификатор узла

Как вытащить дату и время из GUID?

bdb62d89-cede-11e4-b12b-d4ae52b5e909

дата содержится в первых символах, bdb62d89-cede-11e4 которые нужно переставить задом наперед: 11e4-cede-bdb62d89

первый символ отбрасываем, убираем «лишние» знаки «-«(тире)

интервал в десятых долях микросекунд (HEX) получается равным: интервал 16= 1E4CEDEBDB62D89

переводим его в десятичный интервал интервал 10 = HexToDec(интервал 16);в результате получаем: интервал 10 = 136 461 344 788 852 105

находим интервал в секундах: интервал Сек = интервал 10 / 10 000 000;

Делаем сдвиг даты от 15.10.1582 г. + 13 646 134 478 + сдвиг на часовой пояс (Московское время) от «мирового времени» (GMT) = 20.03.2015 16:54:38

Использование UUID / GUID как номера раздела (тома) на диске

В LInux изначально используется UUID как системный номер раздела.

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

В Windows свой зоопарк.

Для FAT 32 — серийный номер из 4 байт = 8 символов в шестнадцатеричной системе

Для NTFS — серийный номер из 8 байт = 16 символов в шестнадцатеричной системе

Системный номер раздела записан непосредственно на диске — создается при форматировании диска. В серийном номер также закодирована дата и время создания раздела.

ВАЖНО: каждый диск «помнит» дату и время создания на нем конкретного раздела, это фактически записано в номере созданного раздела (при форматировании). Нужна шапочка из фольги…

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

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

Номер 4610e64f 10e64611 — 16 цифр в шестнадцатеричной системе

Правую половинку номера тома мы также можем увидеть через команду DIR в режиме командной строки

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

10e6-4611

Он используется Windows уже для регистрации (например раздела) — как устройства, подключенного к системе, вот на фото ниже (как это красиво называется — «точка монтирования» — Mount point).

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

Этот номер уже записан в недрах реестра — в отличии от серийного номера раздела, записанного в заголовке тома на диске.

Этот же номер мы можем увидеть в bcdedit — как номер основного диска С для работы системы

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

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

Вы можете сохранить ссылку на эту страницу себе на компьютер в виде htm файла

Вы будете видеть наш сайт у себя в ленте

Нажмите «Нравится» или напишите сообщение

Источник

UUID и браузеры. Почему фронтенд живет без страшных айдишников?

Решил я делать свой пет-проект по учету прочитанных книг на PWA. Покорять новые технологии и все такое. Расчет был на то, что с его выложу и установлю на телефон и вот у меня есть мобильное приложение, которое можно использовать оффлайн. Хочу я сгенерировать UUID, чтобы сохранить книгу, а не нахожу API. Предлагаю разобраться почему.

Что такое UUID

UUID — стандарт идентификации данных используемый, преимущественно, для распределенных систем. Его задача позволить генерировать ключи, которые не вызовут конфликтов при сохранении в то, или иное хранилище данных.

UUID представляет собой 16-байтное число в HEX’е формате:

Здесь я не буду вдаваться в подробности, что из этого что означает. С этим вы подробно можете ознакомиться в википедии.

Способы генерации UUID

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

Все способы генерации UUID сводятся к тому, что мы берем уникальные данные клиента прогоняем через хеш-функцию и получаем наш 128-битный ключик.

1 и 2 версии использовали время с точностью до 0.1 микросекунды + MAC адрес, что гарантировало практически полное отсутствие возможности получить дубликат. Чтобы полностью добить эту вероятность первая версия добавляет рандомную соль, а вторая ничего не делает (вторую версию мы не любим, она вообще может сгенерировать только 64 уникальных id за семь минут).

3 и 5 хешируют пространство имен (Url, FQDN, OID) + само имя. Таким образом в каждый момент времени мы получаем абсолютно идентичные UUID для одних и тех же входных параметров.

Отличие 3 и 5 версии только в том, что 3 использует для хеширования MD-5, а 5 — SHA-1.

4 же версия просто использует рандом ¯_(ツ)_/¯.

Почему его нет в браузере

JS не имеет доступа к данным машины

Мы не можем получить MAC-адрес пользователя, мы не можем получить данные его IP, а так же вообще что-либо с его машины без разрешения пользователя.
Да, мы можем загружать файлы и делать красивые file-инпуты на фронте, но мы можем получить только конкретный файл, который нам предоставит пользователь. Но согласитесь, как бы не шибко удобно запрашивать на каждый UUID по файлу. Неудобно их запрашивать даже каждый раз при входе на сайт.
Сделано же это из благих целей: представьте, что читаете вы Хабр, а тут:

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

И больше никаких проблем с высшим образованием.

Потому что до недавних пор он был просто не нужен

Браузер для того, чтобы сидеть в интернете.
Через браузер мы заходим на сайт. Если мы зашли на сайт — нам отдали страничку. А раз нам ее отдали — значит мы связаны с сетевым узлом который может сгенерировать UUID и сами мы можем этого не делать. По факту, нам как фронту вообще на ID информации все равно, мы отдали, а дальше это уже проблема принимающей стороны.

Вы можете возразить, что есть PWA, и что оно есть аж с 2007 года. Но так уж вышло, что PWA никому не нужен, примерно, с того же самого времени. (Хотя нынче Play Market позволяет загружать PWA как приложения, но. ). Сами посудите, много вы PWA приложений установили? Я даже Хабр не поставил.

Но осадочек остался.

Какие трудности вас ждут

Точность времени

Я бы не стал называть это большой проблемой.

Мы можем получить время с точностью только до миллисекунды, в то время как первая версия UUID делала это с точностью до 100 наносекунд.

Ну чисто теоретически мы можем получить и с точностью до 1 микросекунды, но это будет время от открытия вкладки (это если мы сейчас про performance.now() ), что уже не так заманчиво.

Идентификация браузера

Браузеры вообще не уникальны и сейчас я вам это докажу.

Для идентификации клиента HTML Living Standard нам предлагает использовать The Navigator object.

А теперь внимание сравним то, что нам предлагают сравнивать

БраузерappCodeNameappNameplatform​productproductSubvendorvendorSub
ChromeMozillaNetscapeWin32Gecko20030107Google Inc.
Mozilla 75MozillaNetscapeWin32Gecko20100101
Mozilla 45MozillaNetscapeWin32Gecko20100101
Internet ExplorerMozillaNetscapeWin32Gecko
Microsoft EdgeMozillaNetscapeWin32Gecko20030107Google Inc.

Как вам такое? Почувствовали все разнообразие клиентов? Вот и я нет.

Но надо признать, что местами отличаются userAgent и appVersion :

Тут Edge впереди планеты всей, так как он отображает IP, и мы можем использовать его. Но это только в Edge. А так, как видите, многого с навигатором не навоюешь.

Как это реализовал я

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

Для себя я решил отталкиваться от своих нужд и особенностей архитектуры своего приложения.

Последние 6 байт я беру из SHA-1 хеша логина — можно идентифицировать 281,474,976,710,656 уникальных пользователей (если взять расчет на то, что не будет коллизий). Тоже с запасом (у меня их всего 30).

1 байт у нас отводится на версию (M) и вариант (N).

Оставшиеся 3 байта я солю рандомом.

Если вдруг мое приложение станет супер-пупер популярным и 100,000 и они будут за минуту каждый делать по 100 книг, то за миллисекунду будет генерироваться:

$$
100,000 * 100 / 60,000 = 166
$$

Вероятность того, что совпадут два:

Это очень мало и этого мне хватает

Реализацию можно посмотреть тут.

Предвещая вопрос «А почему же не рандом?»

Да, есть такой легендарный код

В моем случае на бэкенде UUID используется как первичный ключ.

Когда первые байты ключа идут по порядку больше вероятность, что новая запись встанет в конец таблицы. Даже если на клиенте будет запущена синхронизация. Ведь вряд ли юзер выполнит синхронизацию данных внесенных полгода назад и СУБД будет сдвигать половину таблицы.

В случае же с рандомом — данные будут вставляться в табличку куда ни попадя.

Источник

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

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

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

Уже прошло довольно большое время, с тех пор, когда вышла первая спецификация на Bluetooth 4.0. И, хотя тема BLE очень интересна, она до сих пор отталкивает многих разработчиков, из-за своей сложности. В своих предыдущих статьях я рассматривал в основном самый нижний уровень Link Layer и Physical Layer. Это позволяло не обращаться к таким сложным и запутанным понятиям как протокол атрибутов(ATT) и общий профиль атрибутов (GATT). Однако деваться некуда, не понимая их, невозможно разрабатывать совместимые устройства. Сегодня я хотел бы поделиться с вами этими знаниями. В своей статье я буду опираться на учебник для начинающих с сайта Nordic-а. Итак, давайте приступим.

Почему всё так сложно?

На мой взгляд, сразу было понятно, что управление устройствами через смартфоны — тема очень перспективная и долгоиграющая. Поэтому её решили структурировать сразу и по-максимуму. Что бы производители различных гаджетов не придумывали свои протоколы, которые потом будут не совместимы. Отсюда и сложность. Уже на первом этапе в протокол BLE попытались втиснуть всё что только было возможно. И не важно пригодится это в последствии или нет. Кроме того, предусмотрели возможность расширения списка устройств на будущее.

Давайте взглянем на картинку, где нарисована схема протокола BLE. Он состоит из нескольких слоев. Самый нижний, физический слой (PHY) отвечает за радиоканал устройства. Link Layer(LL) содержит всю последовательность байтов в передаваемом сообщении. В прошлых статьях мы изучали именно его. Host Controller Interface (HCI) — это протокол обмена между слоями или микросхемами BLE, если Controller и Host реализованы на разных чипах. За формирование пакетов, деление на кадры, контролем ошибок и сборку пакетов отвечает Logical Link Control and Adaptation Protocol (L2CAP). За шифрование пакетов отвечает Security Manager Protocol (SMP). Профиль общего доступа (GAP) отвечает за первоначальный обмен данными между устройствами, для определения «Who is who». К нему так же относятся scanning и advertising. В этой статье я остановлюсь на двух оставшихся частях протокола — GATT и ATT. GATT является надстройкой над ATT, поэтому они сильно переплетены.

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

Для упрощения повествования, я бы хотел обратиться к аналогии. Я её где то слышал и хотел бы поддержать. Представьте себе BLE устройство в качестве книжного шкафа с несколькими полками. Каждая полка — это отдельная тематика. К примеру, у нас есть полки с фантастикой, математикой, энциклопедиями. На каждой полке стоят книги с указанной темой. А в некоторых книгах есть даже бумажные закладки с записями. Кроме того, у нас есть небольшой бумажный каталог всех книг. Если помните школьные библиотеки — это узкий ящик с бумажными карточками. При такой аналогии шкаф — это профиль нашего устройства. Полки — это сервисы, книги — характеристики, а каталог — это таблица атрибутов. Закладки в книгах — это дескрипторы, о которых я так же расскажу позже, более подробно.

Все, кто разрабатывал устройства, знает, что во многих проектах есть похожие куски кода. Дело в том, что многие устройства имеют сходный функционал. К примеру, если устройства работают от аккумуляторов, то проблема зарядки и контроля их уровня, будет одинаковой. То же касается и датчиков. Собственно, объектно-ориентированный подход в программировании «предоставляет возможность создавать объекты, которые соединяют свойства и поведения в самостоятельный союз, который затем можно многоразово использовать». На мой взгляд, в BLE была предпринята попытка похожего подхода. Группой Bluetooth Special Interest Group (SIG) были разработаны профили. Устройства от разных производителей, имеющие одинаковые профили, должны без труда работать друг с другом. Профили в свою очередь состоят из сервисов, а сервисы из характеристик, дополняемых дескрипторами. В общем случае это может выглядеть так:

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

Для примера, рассмотрим схему профиля heart rate monitor (фитнес браслет). Он состоит из двух сервисов и нескольких характеристик. Из неё сразу становится понятна иерархия профиля. Характеристика контрольной точки сбрасывает общий подсчет расходов калорий в ноль.

1. Сервис сердечного ритма включает три характеристики (0x180D):
a) Обязательная характеристика частоты сердечных сокращений (0х2A37)
б) Опционная характеристика положения датчика тела (0x2A38)
в) Условная характеристика контрольной точки сердечного ритма (0x2A39)
2. Сервис обслуживания батареи (0x180F):
a) Обязательная характеристика уровня заряда батареи (0x2A19)

Для того, чтобы мы могли однозначно обращаться к элементам профиля (сервисам, характеристикам и дескрипторам) нужно все их как то пронумеровать. Для этой цели вводят такое понятие как Universally Unique ID (UUID) или Универсальный уникальный идентификатор. В скобках каждой строки как раз и указан UUID. И здесь есть одна особенность. Для UUID решили использовать код длиной 16 и 128 бит. Зачем, спросите вы? В протоколе BLE всё подчинено сохранению энергии. Поэтому размерность в 16 бит вполне разумна. Вряд ли в ближайшем будущем будет создано больше 65тыс. уникальных сервисов и характеристик. На данный момент всё что могли, уже посчитали (помните откуда это — «он и вас посчитал» :-)) Пронумерованные элементы профилей, сервисов, характеристик и дескрипторов вы можете посмотреть по ссылкам.

Однако, я думаю, все помнят историю с 4-мя байтами IPv4 адреса в интернете. Сначала думали что хватит, а теперь всё никак не перейдем на IPv6 адресацию. Что бы не повторять этой ошибки и дать простор шаловливым ручкам самодельщиков, SIG сразу решила ввести ещё и 128-ми битные UUID. Это лично мне напоминает нелицензионный диапазон 433МГц, который был дан на откуп всевозможным Кулибиным от радиоканала. В нашем случае, на откуп был отдан 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_bit_value = 16_bit_value * 2^96 + Bluetooth_Base_UUID

Откуда взялось это магическое число, мне не известно. Если кто нибудь из читателей знает — пусть напишет в комментариях (Пользователь с ником Sinopteek уже сделал это. Смотрите комментарии). Что касается придумывания 128-ти битных UUID, то в принципе можно воспользоваться специальным генератором, который сделает это за вас.

ATTы GATTы.

Собственно дальше начинается самое интересное. Я напомню, что ATT основан на клиентском-серверном отношении. Сейчас мы рассматриваем устройство сервера. Он содержит такую информацию, как значения датчиков, состояние выключателя света, данные о местоположении и т.д. Теперь, когда все «участники нашего парада» пронумерованы, надо как то их размещать в памяти устройства. Для этого мы помещаем их в таблицу, которая называется таблицей атрибутов. Запомните это хорошенько. Это самое сердце BLE. Именно его мы и будем рассматривать в дальнейшем. Теперь каждую строчку мы будем называть аттрибутом. Эта таблица находится в глубине стека и, как правило, мы не имеем к ней прямого доступа. Мы её инициализируем и к ней обращаемся, но что там происходит внутри, от нас скрыто за семью печатями.

Рассмотрим картинку из спецификации, однако перед этим, хочу сразу обратить внимание на частую путаницу в терминах, а именно в дескрипторах. Роль дескриптора — дополнить описание характеристики. Когда надо расширить её возможности, тогда и применяют дескрипторы. Они так же являются аттрибутами, и так же, наравне с сервисами и характеристиками, располагаются в таблице аттрибутов. Мы подробно разберем их во второй части статьи. Однако иногда дескрипторами называют номер строки в таблице аттрибутов. Это надо иметь ввиду. Мы же, что бы не путаться, будем для этих целей использовать термин «указатель атрибута».
Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

Итак атрибут — это дискретное значение, которое имеет следующие свойства, связанные с ним:
1. Указатель атрибута (Attribute Handle) — это индекс таблицы, соответствующий атрибуту
2. Тип атрибута (Attribute Type) — это UUID, который описывает его тип
3. Значение аттрибута (Attribute Value) — это данные, индексируемые указателем атрибута
4. Разрешения атрибутов (Attribute Permissions) — это часть атрибута, разрешения, которые не могут быть прочитаны или записаны с использованием протокола атрибутов

Как всё это понимать? Указатель аттрибута — это, условно говоря, его номер в нашей таблице.
Он позволяет клиенту ссылаться на атрибут в запросах чтения или записи. Мы можем нумеровать наши строчки (аттрибуты) от 0x0001 до 0xFFFF. В нашей ассоциации с книжным шкафом — это номер карточки в бумажном каталоге. Аналогично, как в каталоге библиотеки, карточки располагаются в порядке увеличения номера. Номер каждой последующей строчки должен быть больше предыдущей. Как и в библиотеке, иногда теряются некоторые карточки, так и у нас — в нумерации строк могут быть промежутки. Это допускается. Главное, что бы они шли по нарастающей.

Тип атрибута определяет что представляет собой данный атрибут. По аналогии с языком Си,
где есть булевые, числовые переменные и строки, так и здесь. По типу аттрибута мы узнаем
с чем мы имеем дело и как нам дальше с этим аттрибутом работать. Ниже мы рассмотрим некоторые специфичные типы аттрибутов. Например «сервисная декларация» (0х2800), «декларация характеристики» (0х2803), «декларация дескриптора» (0x2902).

Как это выглядит

Концепция GATT заключается в том, чтобы сгруппировать атрибуты в таблице атрибутов вместе в очень специфическом и логическом порядке. Давайте более внимательно рассмотрим профиль частоты сердечных сокращений, приведенный ниже. Самый левый столбик этой таблицы не обязательный. Он просто описывает нам чем является эта строчка (аттрибут). Все остальные столбцы нам уже знакомы.

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

В верхней части каждой группы мы всегда имеем атрибут объявления сервиса. Его тип всегда равен 0x2800, а указатель зависит от того, сколько атрибутов уже присутствует в таблице. Его разрешения всегда доступны только для чтения, без какой-либо проверки подлинности или авторизации. Об этих понятиях мы поговорим чуть позже. Значение — это еще один UUID, определяющий, что это за служба. В Таблице значение равно 0x180D, что определяется Bluetooth SIG как сервис частоты сердечных сокращений.

Вслед за объявлением сервиса, следует объявление характеристики. По форме оно аналогично объявлению сервиса. Его UUID всегда имеет значение 0x2803, а разрешения так же всегда доступны только для чтения без какой-либо проверки подлинности или авторизации. Давайте посмотрим на поле Attribute Value, которое включает некоторые данные. Оно всегда содержит указатель, UUID и набор свойств. Эти три элемента описывают последующее объявление значения характеристики. Указатель естественным образом обозначает место объявления значения характеристики в таблице атрибутов. UUID описывает, какой тип информации или значения мы можем ожидать. Например, значение температуры, состояние выключателя света или какое-либо другое произвольное значение. И наконец свойства, которые описывают, как можно взаимодействовать с характеристическим значением.

Тут нас поджидает ещё один подводный камень. Он связан с разрешениями аттрибутов и свойствами характеристик. Давайте мы посмотрим на картинку свойств битового поля из спецификации.

Uuid128 что это такое. Смотреть фото Uuid128 что это такое. Смотреть картинку Uuid128 что это такое. Картинка про Uuid128 что это такое. Фото Uuid128 что это такое

Как видите, здесь так же присутствуют поля, дающие возможности чтения и записи. Вы можете задаться вопросом, почему у нас есть разрешения на чтение/запись для атрибута и свойства
чтения/записи для значения характеристики? Разве они не должны быть всегда одинаковыми? Дело в том, что свойства для значения характеристики, фактически являются только рекомендациями для клиента, используемыми в ГАТТ и прикладных слоях. Это просто подсказки о том, что клиент может ожидать от атрибута объявления характеристики. Давайте с этим разберемся поподробнее. Какие виды разрешений существуют у аттрибута?

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

Главное отличие разрешения аттрибутов от свойств характеристик состоит в том, что первые относятся к серверам, а вторые к клиентам. У сервера может быть разрешено чтение значения характеристики, но при этом стоять требование аутентификации или авторизации. Поэтому при запросе клиентом свойств характеристики, мы получим, что чтение разрешено. Но при попытке чтения получим ошибку. Поэтому можно смело говорить о приоритете разрешений над свойствами. Знание о том, какие разрешения есть у аттрибута, мы, со стороны клиента, получить не можем.

Дескриптор

Вернемся к нашей таблице. После объявления значения характеристики, возможны следующие объявления аттрибутов:
1. Новое объявление характеристики (в сервисе может быть много характеристик)
2. Новая декларация сервиса (в таблице может быть их много)
3. Объявление дескриптора

В случае характеристики измерения частоты сердечных сокращений, в нашей таблице, объявление значения характеристики сопровождается объявлением дескриптора. Дескриптор — это атрибут с дополнительной информацией о характеристике. Существует несколько видов дескрипторов. О них мы подробно поговорим во второй части этой статьи. Сейчас же мы коснемся только дескриптора конфигурации характеристик клиента (Client Characteristic Configuration Descriptor — CCCD). Он имеет UUID равную 0х2902. При помощи этого дескриптора клиент имеет возможность включить на сервере индикацию или нотификацию. Разница между ними небольшая, но всё таки есть. Нотификация не требует подтверждения в получении со стороны клиента. Индикация же этого требует, хотя она и происходит на уровне GATT, не доходя до уровня приложения. Зачем так, спросите вы? Увы, это мне не ведомо. Скажу лишь, что специалисты Nordic-а рекомендуют использовать нотификацию. Тем более, что проверка целостности пакета (при помощи CRC) происходит в обоих случаях.

Заключение

В конце статьи я хотел бы сказать вот о чем. Последняя таблица несколько запутанна. Однако я остановился на ней из-за того, что она приводится в статье, на которую я опираюсь. Во второй части своей статьи я намерен углубиться в спецификацию BlueTooth 4.0. Там нас ждут более корректные схемы и рисунки. В третьей части, я хотел бы разобрать лог, полученный при помощи программы Wireshark от одного из гаджетов и увидеть «в живую» всю ту теорию, которую мы с вами изучаем.

Сотрудник Группы Компаний «Цезарь Сателлит»
Печерских Владимир

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *