![](https://habrastorage.org/getpro/habr/upload_files/b94/723/a17/b94723a1781d201c390239cb647efa07.png)
Введение
D‑Bus - это простая в использовании система межпроцессного взаимодействия (IPC) с низкими издержками. Более подробно:
D‑Bus не требует больших затрат , поскольку использует двоичный протокол и не требует преобразования в текстовый формат, например XML, и обратно. Поскольку D-Bus предназначен в первую очередь для IPC внутри одной машины, и во вторую очередь для IPC в Интернете, то это интересная оптимизация. D-Bus также спроектирован таким образом, чтобы избежать задержек и обеспечить асинхронную работу, как и протокол X.
D‑Bus прост в использовании потому, что он работает с сообщениями, а не с потоками байтов, и автоматически решает множество сложных проблем IPC. Кроме того, библиотека D‑Bus спроектирована так, чтобы можно было сделать враппер, позволяющий разработчикам использовать существующие объекты/типы их фреймворков, а не изучать новые, специализированные для IPC.
Базовый протокол D‑Bus - это протокол «точка-точка» (одноранговый или клиент-сервер), описанный в разделе «Протокол сообщений». То есть это система, в которой одно приложение взаимодействует с единственным другим приложением. Однако основным, предполагаемым применением протокола является шина сообщений D‑Bus, описанная в разделе «Спецификация шины сообщений». Шина сообщений - это специальное приложение, которое принимает соединения от множества других приложений и пересылает сообщения между ними.
D‑Bus может также использоваться для нотификации об изменениях в системе (уведомление о том, когда камера подключена к компьютеру или установлена новая версия некоторого программного обеспечения) или взаимодействия настольных компьютеров, например, сервис мониторинга файлов или сервис конфигурирования.
D‑Bus разработана для двух конкретных случаев использования:
«Системная шина» для уведомлений от системы к пользовательским сеансам и позволяющая системе запрашивать ввод из пользовательских сеансов.
«Сессионная шина», используемая для реализации окружения рабочего стола, такого как GNOME и KDE.
D‑Bus не предназначен для использования в качестве IPC общего назначения для любого возможного приложения и по этой причине намеренно опускает многие функции, имеющиеся в других системах IPC.
В то же время, демоны шины предлагают ряд функций, которых нет в других системах IPC, таких как «шинные имена» с одним владельцем (аналогично селекторам в X Window System), запуск сервисов по запросу и политики безопасности. Во многих отношениях эти функции являются основной причиной разработки D-Bus; если бы единственной целью был IPC - существующих систем было бы достаточно.
D-Bus может оказаться полезным в неожиданных приложениях, но будущие версии этой спецификации и эталонная реализация, вероятно, не будут включать функции, которые мешают основным вариантам использования.
Ключевые слова «ДОЛЖЕН», «НЕ ДОЛЖЕН», «ОБЯЗАТЕЛЬНО», «ДОЛЖЕН», «НЕ ДОЛЖЕН», «СЛЕДУЕТ», «НЕ СЛЕДУЕТ», «РЕКОМЕНДУЕТСЯ», «МОЖЕТ» и «ДОПОЛНИТЕЛЬНО» в этом документе следует интерпретировать, как описано в RFC 2119. Тем не менее, документ может потребовать серьезной проверки, чтобы убедиться, что это имеет смысл. Кроме того, они не пишутся с заглавной буквы.
Стабильность протокола и спецификации
С 8 ноября 2006г. протокол D-Bus заморожен (разрешены только совместимые расширения). Тем не менее, эта спецификация может потребовать значительных усилий, чтобы сделать возможной функционально совместимую повторную реализацию без оглядки на эталонную реализацию D‑Bus. Таким образом, эта спецификация не имеет маркировки 1.0. Прежде чем маркировать её как 1.0, мы хотели бы, чтобы кто-то приложил значительные усилия для уточнения языка спецификации и расширения спецификации, с целью охватить больше аспектов поведения эталонной реализации.
Пока эта работа не будет завершена, любая попытка повторно реализовать D-Bus, вероятно, потребует изучения эталонной реализации и/или вопросов в списке рассылки D-Bus о предполагаемом поведении. Вопросы в рассылке приветствуются.
Тем не менее, этот документ должен быть полезной отправной точкой и, насколько нам известно, точен, хотя и неполон.
Система типов
D-Bus обладает системой типов, в которой значения различных типов могут быть сериализованы в последовательность байтов, называемую стандартным способом сериализации. Преобразование значения из некоторого иного представления в сериализованный формат называется маршалингом, а преобразование его обратно из сериализованного формата - демаршалингом.
Протокол D-Bus не включает в маршалированные данные теги типов; блок маршалированных значений должен иметь сигнатуру известного типа. Сигнатура типа состоит из нуля или нескольких отдельных типов, каждый из которых состоит из одного или нескольких кодов типов.
Код типа - это символ ASCII, представляющий тип значения. Поскольку используются символы ASCII, сигнатура типа всегда будет формировать допустимую строку ASCII. Простое сравнение строк определяет, эквивалентны ли сигнатуры двух типов.
Единый полный тип - это последовательность кодов типа, которая полностью описывает его тип: либо базовый тип, либо один полностью описанный контейнерный тип. Единый полный тип - это код базового типа, код вариантного типа, массив с типом его элементов или структура с полями (все они определены ниже). Таким образом, следующие сигнатуры не являются едиными полными типами:
"aa"
"(ii"
"ii)"
А следующие сигнатуры содержат несколько полных типов:
"ii"
"aiai"
"(ii)(ii)"
Однако, обратите внимание, что единый полный тип может содержать несколько других единых полных типов, содержащих запись struct (структура) или dict (запись словаря).
Базовые типы
Простейшие коды типов - это базовые типы, то есть типы, структура которых полностью определяется их односимвольным кодом. Базовые типы состоят из фиксированных типов и строковых типов.
Фиксированные типы - это базовые типы, размер которых имеют фиксированную длину, а именно BYTE, BOOLEAN, DOUBLE, UNIX_FD и целые числа со знаком или без знака длиной 16, 32 или 64 бита.
В качестве простого примера кода типа для 32-разрядного целого числа (INT32) - это символ ASCII «i». Таким образом, сигнатура для блока значений, содержащего единственный INT32, будет:
"i"
Блок из значений, содержащий два INT32, будет иметь такую сигнатуру:
"ii"
Характеристики фиксированных типов перечислены в этой таблице.
Обычное имя | ASCII код типа | Расшифровка |
BYTE | y(121) | Беззнаковое 8-битное целое число |
BOOLEAN | b(98) | Логическое значение: 0 - ложь, 1 - истина, любое другое значение, разрешенное форматом маршалинга, недопустимо |
INT16 | n(110) | Знаковое (в дополнительном коде) 16-разрядное целое число |
UINT16 | q(113) | Беззнаковое 16-битное целое число |
INT32 | i(105) | Знаковое (в дополнительном коде) 32-битное целое |
UINT32 | u(117) | Беззнаковое 32-битное целое число |
INT64 | x(120) | Знаковое (в дополнительном коде) 64-битное целое число (мнемоника: x и t - первые символы в «шестидесяти (sixty)», которые еще не используются для чего-то другого более распространенного) |
UINT64 | t(116) | Беззнаковое 64-битное целое число |
DOUBLE | d(100) | IEEE 754 с плавающей запятой двойной точности |
UNIX_FD | h(104) | Беззнаковое 32-разрядное целое число, представляющее индекс во вспомогательном массиве файловых дескрипторов, передаваемых через некоторый, зависящий от платформы, механизм (мнемоника: h от handle (дескриптор)) |
Строковые типы это базовые типы переменной длины. Значение любого строкового типа концептуально равно 0 или более кодовым позициям Unicode, закодированным в UTF-8, ни одна из которых не может бытьU + 0000 . Текст UTF-8 должен быть строго проверен: в частности, он не должен содержать слишком длинных последовательностей или кодовых позицийU + 10FFFF
Начиная со спецификации D‑Bus версии 0.21, в соответствии с исправлением Unicode #9, в строках UTF‑8 разрешены "несимвольные знаки" U + FDD0..U + FDEF, U + nFFFE и U + nFFFF (но обратите внимание, что старые версии D‑Bus эти несимвольные знаки отклоняли).
Все маршалинговые форматы строковых типов оканчиваются одним нулевым байтом (NUL), но этот байт не считается частью текста.
Характеристики строковых типов перечислены в этой таблице.
Условное обозначение | ASCII код типа | Ограничения валидности |
STRING | s(115) | Без лишних ограничений |
OBJECT_PATH | o(111) | Должен быть синтаксически допустимый объектный путь. |
SIGNATURE | g(103) | Ноль или более единых полных типов. |
Допустимые объектные пути
Объектный путь - это имя, используемое для ссылки на экземпляр объекта. По идее, каждый участник обмена сообщениями D-Bus может иметь любое количество экземпляров объекта (подумайте об объектах C ++ или Java), и каждый такой экземпляр будет иметь путь. Как и файловая система, экземпляры объектов в приложении образуют иерархическое дерево.
Объектные пути часто имеют пространство имен, начинающееся с перевернутого имени домена и содержат номер версии интерфейса, точно так же, как имена интерфейсов и общеизвестные шинные имена. Это позволяет реализовать в одном процессе более одного сервиса или более одной версии сервиса даже если сервисы совместно используют соединение, но не могут взаимодействовать иным образом (например, если они реализованы разными плагинами).
Использование пути к объекту «/» разрешено, но не рекомендуется, так как это затрудняет управление версиями интерфейсов. Любые сигналы, испускаемые объектом D‑Bus, имеют связанное с ними уникальное шинное имя, а не его общеизвестное имя. Это означает, что получатели сигналов, чтобы определить какой интерфейс породил сигнал, должны полностью полагаться на имя сигнала и объектный путь.
Например, если владелец example.com разрабатывает API D-Bus для музыкального проигрывателя, он может использовать для своих объектов иерархию путей к объектам, которые начинаются с /com/example/MusicPlayer1 .
Следующие правила определяют допустимый путь к объекту. Реализации не должны отправлять или принимать сообщения с недопустимыми путями к объектам.
Путь может быть любой длины.
Путь должен начинаться с символа косой черты ASCII '/' (целое число 47) и должен состоять из элементов, разделенных этим символом.
Каждый элемент должен содержать только символы ASCII "[A-Z] [a-z] [0-9] "
Никакой элемент не может быть пустой строкой.
Символы '/' не могут идти подряд.
Завершающий символ '/' не допускается, если путь не является корневым (один символ «/»).
Допустимые сигнатуры
Реализация не должна отправлять или принимать недопустимые сигнатуры. Допустимые сигнатуры будут соответствовать следующим правилам:
Сигнатура - это список единых полных типов. Массивы должны иметь типы элементов, а структуры должны иметь как открывающую, так и закрывающую круглые скобки.
В сигнатуре разрешены только коды типов, открывающие и закрывающие круглые скобки, а также открывающие и закрывающие фигурные скобки. В сигнатурах не допускается код типа STRUCT, так как вместо него используются круглые скобки. Точно так же в сигнатурах не разрешен код типа DICT_ENTRY, потому что вместо него используются фигурные скобки.
Максимальная глубина вложенности контейнерных типов составляет 32 кода типа массива и 32 открывающие скобки. Это означает, что максимальная общая глубина рекурсии равна 64 для «массива массивов массива … структуры структуры структуры …», где имеется 32 массива и 32 структуры.
Максимальная длина сигнатуры 255.
Когда сигнатуры появляются в сообщениях, формат маршалинга гарантирует, что за ними будет следовать нулевой байт (который можно интерпретировать как завершение строки в стиле C или как код типа INVALID), но он концептуально не является частью сигнатуры.
Контейнерные типы
В дополнение к базовым типам существует четыре типа контейнеров: STRUCT, ARRAY, VARIANT и DICT_ENTRY.
STRUCT имеет кодом типа символ ASCII 'r', но этот код не появляется в сигнатурах. Вместо этого используются символы ASCII '(' и ')' для обозначения начала и конца структуры. Так, например, структура, содержащая два целых числа, будет иметь такую сигнатуру:
"(ii)"
Структуры могут быть вложенными, например, структура, содержащая целое число и другую структуру:
"(i(ii))"
Блок значений, хранящий эту структуру, будет содержать три целых числа; сигнатура типа позволяет отличить«(i(ii))» от«(ii)i)» ,«(iii)» или«iii»
Код типа STRUCT 'r' в настоящее время в протоколе D‑Bus не используется, но полезен в коде, реализующем протокол. Этот код типа указывается, чтобы позволить такому коду взаимодействовать в непротокольных контекстах.
Пустые структуры не допускаются; между скобками должен быть хотя бы один код типа.
ARRAY в качестве кода типа используется символ ASCII 'a'. Код типа массива должен сопровождаться единым полным типом. Единый полный тип, следующий за массивом, - это тип элементов массива. Итак, простой пример:
"ai"
который представляет собой массив 32-битных целых чисел. Но массив может быть любого типа, например, этот массив‑структур‑с‑двумя‑полями‑int32:
"a(ii)"
Или этот массив массивов целых чисел:
"aai"
VARIANT имеет в качестве кода типа ASCII-символ 'v '. Маршалированное значение типа VARIANT будет иметь как часть значения сигнатуру единого полного типа. За этой сигнатурой будет следовать маршалированное значение этого типа.
В отличие от сигнатуры сообщения, сигнатура варианта может содержать только единый полный тип. Итак, «i», «ai» или «(ii)» подходят, а «ii» - нет. Использование вариантов может не привести к тому, что общая глубина сообщения будет больше 64, включая другие типы контейнеров, такие как структуры.
DICT_ENTRY работает точно так же, как структура, но вместо круглых скобок использует фигурные скобки и имеет больше ограничений. Ограничения: тип встречается только как тип элемента массива; внутри фигурных скобок есть ровно два единых полных типа; первый единый полный тип («ключ») должен быть базовым типом, а не контейнерным. Реализации не должны принимать записи dict вне массивов, не должны принимать записи dict с нулем, одним или более чем двумя полями, а также не должны принимать записи dict с ключами, отличными от базовых типов. Запись dict - это всегда пара ключ‑значение.
Первое поле в DICT_ENTRY всегда является ключом. Сообщение считается поврежденным, если один и тот же ключ встречается дважды в одном и том же массиве DICT_ENTRY. Однако по соображениям производительности реализациям не требуется отклонять словари с повторяющимися ключами.
В большинстве языков массив записей dict будет представлен как map , хеш‑таблица или объект dict .
Сводка по типам
В следующей таблице приведены типы D-Bus.
Категория | Условное обозначение | Код | Описание |
зарезервированный | INVALID | 0 (ASCII NUL) | Недействительный код типа, используемый для завершения сигнатур |
фиксированный, базовый | BYTE | 121 (ASCII 'y') | 8-битное целое число без знака |
фиксированный, базовый | BOOLEAN | 98 (ASCII 'b') | Логическое значение, 0 - ЛОЖЬ, а 1 - ИСТИНА. Все остальное неверно. |
фиксированный, базовый | INT16 | 110 (ASCII 'n') | 16-битное целое число со знаком |
фиксированный, базовый | UINT16 | 113 (ASCII 'q') | 16-битное целое число без знака |
фиксированный, базовый | INT32 | 105 (ASCII 'i') | 32-битное целое число со знаком |
фиксированный, базовый | UINT32 | 117 (ASCII 'u') | 32-битное целое число без знака |
фиксированный, базовый | INT64 | 120 (ASCII 'x') | 64-битное целое число со знаком |
фиксированный, базовый | UINT64 | 116 (ASCII 't') | 64-битное целое число без знака |
фиксированный, базовый | DOUBLE | 100 (ASCII 'd') | IEEE 754 двойной |
строковый, базовый | STRING | 115 (ASCII 's') | Строка UTF-8 (должен быть действительный UTF-8). Должен заканчиваться нулем и не содержать других нулевых байтов. |
строковый, базовый | OBJECT_PATH | 111 (ASCII 'o') | Имя экземпляра объекта |
строковый, базовый | SIGNATURE | 103 (ASCII 'g') | Сигнатура типа |
контейнер | ARRAY | 97 (ASCII 'a') | Массив |
контейнер | STRUCT | 114 (ASCII 'r'), 40 (ASCII '('), 41 (ASCII ')') | Struct; код типа 114 'r' зарезервирован для использования в привязках и реализациях для представления общей концепции структуры и не должен появляться в сигнатурах, используемых в D-Bus. |
контейнер | VARIANT | 118 (ASCII 'v') | Тип варианта (тип значения является частью самого значения) |
контейнер | DICT_ENTRY | 101 (ASCII 'e'), 123 (ASCII '{'), 125 (ASCII '}') | Запись в dict или map (массив пар ключ-значение). Код типа 101 «e» зарезервирован к использованию в привязках и реализациях для представления общей концепции dict или dict-entry и не должен появляться в сигнатурах, используемых на D-Bus. |
фиксированный, базовый | UNIX_FD | 104 (ASCII 'h') | Дескриптор файла Unix |
зарезервированный | (зарезервированный) | 109 (ASCII 'm') | Зарезервировано для типа "возможно", совместимого с типом в GVariant, и не должно появляться в сигнатурах, используемых на D-Bus, пока не будет указано здесь |
зарезервированный | (зарезервированный) | 42 (ASCII '*') | Зарезервировано для использования в привязках/реализациях для представления любого единого полного типа и не должно появляться в сигнатурах, используемых на D-Bus. |
зарезервированный | (зарезервированный) | 63 (ASCII '?') | Зарезервировано для использования в привязках/реализациях для представления любого базового типа и не должно появляться в сигнатурах, используемых на D‑Bus. |
зарезервированный | (зарезервированный) | 64 (ASCII '@'), 38 (ASCII '&'), 94 (ASCII '^') | Зарезервировано для внутреннего использования привязками/реализациями и не должно появляться в сигнатурах, используемых на D‑Bus. GVariant использует эти коды типов для кодирования соглашений о вызовах. |
Маршалинг (Сериализация)
D-Bus для своей системы типов определяет формат маршалинга(сериализации), который используется в сообщениях D-Bus. Это не единственный возможный формат маршалинга для системы типов: например, GVariant (часть GLib) использует систему типов D‑Bus, но реализует альтернативный формат маршалинга.
Порядок байтов и выравнивание
Учитывая сигнатуру типа, блок байтов можно преобразовать в типизированные значения. В этом разделе описывается формат блока байтов. Вопросы порядка байтов и выравнивания решаются единообразно для всех типов D‑Bus.
Блок байтов имеет порядок байтов. Порядок байтов должен быть каким-то образом обозначен; для сообщений D‑Bus порядок байтов является частью заголовка сообщения, как описано в разделе «Формат сообщения». Пока предположим, что известен порядок байтов младшим вперед или старшим вперед (little-endian или big‑endian).
Каждое значение в блоке байтов выравнивается «естественным образом», например, 4‑байтовые значения выравниваются по 4‑байтовой границе, а 8‑байтовые значения - по 8‑байтовой границе. Границы вычисляются глобально по отношению к первому байту сообщения. Чтобы правильно выровнять значение, перед значением может потребоваться заполнение. Выравнивающее заполнение всегда должно быть минимально необходимым для правильного выравнивания следующего значения; и оно всегда должно состоять из нулевых байтов. Выравнивающее заполнение выравнивания не должно оставаться неинициализированным (оно не может содержать мусор), и нельзя использовать больше байтов заполнения, чем требуется.
Как исключение из естественного порядка выравнивания значений, STRUCT и DICTENTRY всегда выравниваются по 8‑байтовой границе, независимо от выравнивания их содержимого.
Маршалинг базовых типов
Чтобы маршалировать и демаршалировать фиксированные типы, вы просто считываете одно значение из блока данных, соответствующего каждому коду типа в сигнатуре. Все целочисленные значения со знаком кодируются в дополнительном коде, значения DOUBLE представляют собой числа с плавающей запятой двойной точности IEEE 754, а значения BOOLEAN кодируются в 32‑битном формате (из которых используется только младший значащий бит).
Строковые типы (STRING, OBJECTPATH и SIGNATURE) все упорядочиваются как целое число фиксированной длины без знака, содержащее длину переменной части, за которым следуют ненулевые байты текста UTF‑8, и далее следует один нулевой (nul ) байт, который не является частью текста. Выравнивание строкового типа такое же, как выравнивание n : любое заполнение, необходимое для n , появляется непосредственно перед ним. Никогда не бывает выравнивающего заполнения между n и текстом строки или между текстом строки и конечным nul. Выравнивающее заполнение для следующего значения в сообщении (если оно есть) начинается после завершающего нуля.
Для типов STRING и OBJECTPATH n кодируется 4 байтами (UINT32), что приводит к 4‑байтовому выравниванию. Для типа SIGNATURE n кодируется как один байт (UINT8). В результате выравнивающее заполнение перед SIGNATURE никогда не требуются.
Например, если текущая позиция кратна 8 байтам от начала сообщения с порядком байтов младшим вперед, строки «foo », «+» и «bar » будут сериализованы в следующей последовательности:
выравнивание не требуется, поскольку длина кратна 4
0x03 0x00 0x00 0x00 длина ‘foo’ = 3
0x66 0x6f 0x6f ‘foo’
0x00 завершающий ноль
выравнивание не требуется, поскольку длина кратна 4
0x01 0x00 0x00 0x00 length of ‘+’ = 1
0x2b ‘+’
0x00 завершающий ноль
0x00 0x00 2 выравнивающих байта чтобы получить ближайшую кратную 4 длину
0x03 0x00 0x00 0x00 длина ‘bar’ = 3
0x62 0x61 0x72 ‘bar’
0x00 завершающий ноль
Маршалинг контейнеров
Массивы маршалируются как n типа UINT32, содержащее длину данных массива в байтах, за которым следует выравнивающее заполнение до границы выравнивания типа элемента массива, далее следуют байты элементов массива, маршалированных в последовательность. Значение n не включает заполнение после длины или любое другое заполнение после последнего элемента. Т.е. n должно быть кратно количеству элементов в массиве.
Например, если текущая позиция в сообщении кратна 8 байтам и порядок байтов big‑endian , массив, содержащий только 64-разрядное целое число 5, будет маршалирован как:
00 00 00 08 n = 8 байт данных
00 00 00 00 дополнение до границы 8-байт
00 00 00 00 00 00 00 05 первый элемент = 5
Массивы имеют максимальную длину 2 в 26-й степени или 67108864 (64 МиБ). Реализации не должны отправлять или принимать массивы, превышающие эту длину.
Структуры и записи dict маршалируются таким же образом, как их содержимое, но выравнивание всегда осуществляется по 8-байтовой границе, даже если содержимое могло бы быть выровнено по меньшему значению границы.
Варианты маршалируются как SIGNATURE их содержимого (которое должно быть единого полного типа), за которым следует маршалированное значение с типом, заданным этой сигнатурой. Вариант, как и сигнатура имеет 1‑байтовое выравнивание, это означает, что выравнивающее заполнение перед вариантом никогда не требуется. Использование вариантов не должно приводить к тому, чтобы общая глубина сообщения превышала 64, включая другие типы контейнеров, такие как структуры (См. Вводную статью).
Сводка по маршалированию в D-Bus
Учитывая вышесказанное, типы маршалируются по сети следующим образом:
Условное обозначение | Кодирование | Выравнивание |
INVALID | Недопустимый, не может быть маршалирован. | Нет данных |
BYTE | Один 8-битный байт. | 1 |
BOOLEAN | Используется UINT32, но допустимыми значениями являются только 0 и 1. | 4 |
INT16 | 16‑битовое целое число со знаком в порядке байтов сообщения. | 2 |
UINT16 | 16‑битное целое число без знака в байтовом порядке сообщения. | 2 |
INT32 | 32‑битное целое число со знаком в порядке байтов сообщения. | 4 |
UINT32 | 32‑битовое целое число без знака в байтовом порядке сообщения. | 4 |
INT64 | 64‑битное целое число со знаком в порядке байтов сообщения. | 8 |
UINT64 | 64‑битное целое число без знака в байтовом порядке сообщения. | 8 |
DOUBLE | 64‑битный IEEE 754 с двойным порядком байтов сообщения. | 8 |
STRING | Сначала UINT32, указывающий длину строки в байтах, за исключением завершающего нулевого значения, затем следуют ненулевые строковые данные заданной длины, за которыми следует завершающий нулевой байт. | 4 (по длине) |
OBJECT_PATH | Точно так же, как STRING, за исключением того, что содержимое должно быть допустимым путем к объекту (см. Выше). | 4 (по длине) |
SIGNATURE | То же, что и STRING, за исключением того, что длина кодируется одним байтом (таким образом, максимальная длина сигнатуры составляет 255), а содержимое должно быть действительной сигнатурой (см. Выше). | 1 |
ARRAY | AUINT32 предоставляет длину данных массива в байтах, за которой следует выравнивающее заполнение до границы выравнивания типа элемента массива, за которым следует каждый элемент массива. | 4 (по длине) |
STRUCT | Структура должна начинаться на 8‑байтовой границе независимо от типа полей структуры. Значение структуры состоит из каждого поля, упорядоченного по порядку, начиная с этой 8‑байтовой границы выравнивания. | 8 |
VARIANT | Маршалированная SIGNATURE одного полного типа, за которой следует маршалированное значение с типом, указанным в сигнатуре. | 1 (выравнивание сигнатуры) |
DICT_ENTRY | Идентично STRUCT. | 8 |
UNIX_FD | 32‑битовое целое число без знака в байтовом порядке сообщения. Фактические файловые дескрипторы необходимо передавать по дополнительному каналу с помощью определенного механизма платформы. На проводе значения этого типа сохраняют индекс файлового дескриптора в массиве файловых дескрипторов, сопровождающих сообщение. | 4 |
Протокол сообщений
Сообщение состоит из заголовка и тела. Если вы думаете о сообщении как о пакете, то заголовок - это адрес, а тело содержание пакета. Система доставки сообщений использует информацию заголовка, чтобы выяснить, куда отправить сообщение и как его интерпретировать; получатель интерпретирует тело сообщения.
Тело сообщения состоит из нуля или более аргументов, которые представляют собой типизированные значения, такие как целое число или массив байтов.
Для сериализации данных и заголовка, и тела используется формат и система типов D‑Bus.
Формат сообщения
Сообщение состоит из заголовка и тела.
Заголовок- это блок значений с фиксированной сигнатурой и значением.
Тело- это отдельный блок значений соответствующих сигнатуре, указанной в заголовке.
Длина заголовка должна быть кратна 8, чтобы тело могло начинаться с 8‑байтовой границы при сохранении всего сообщения в одном буфере. Если заголовок не заканчивается естественным образом на 8-байтовой границе, необходимо добавить до 7 нулевых байтов выравнивающего заполнения.
Тело сообщения не обязательно должно заканчиваться на 8‑байтовой границе.
Максимальная длина сообщения, включая заголовок, заполнение для выравнивания заголовка и тело, составляет 2 в 27-й степени или 134217728 (128 МиБ). Реализации не должны отправлять или принимать сообщения, превышающие этот размер.
Сигнатура заголовка:
"yyyyuua(yv)"
Если расшифровать то, это:
BYTE, BYTE, BYTE, BYTE, UINT32, UINT32, ARRAY of STRUCT of (BYTE,VARIANT)
Эти значения имеют следующий смысл:
Значение | Описание |
1‑й BYTE | Флаг порядка байтов; ASCII 'l' для порядка байтов little‑endian или ASCII 'B' для big‑endian. И заголовок, и тело используют этот порядок. |
2‑й BYTE | Тип сообщения. Неизвестные типы следует игнорировать. Типы, определенные в настоящее время, описаны ниже. |
3‑й BYTE | Побитовая сумма флагов по «ИЛИ». Неизвестные флаги следует игнорировать. Определенные в настоящее время флаги описаны ниже. |
4‑й BYTE | Основная версия протокола отправляющего приложения. Если основная версия протокола принимающего приложения не совпадает, приложения не смогут взаимодействовать и соединение D-Bus должно быть разорвано. Основная версия протокола для этой версии спецификации - 1. |
1‑й UINT32 | Длина тела сообщения в байтах, начиная с конца заголовка. Заголовок заканчивается после его выравнивающего заполнения до 8‑байтной границы. |
2‑й UINT32 | Серийный номер этого сообщения, используемый отправителем подобно cookie для идентификации ответа, соответствующего этому запросу. Это значение не должно быть нулевым. |
ARRAY of STRUCT of (BYTE, VARIANT) | Массив из нуля или более полей заголовка, где байт - это код поля, а вариант - значение поля. Тип сообщения определяет, какие поля обязательны. |
Типы сообщений, которые могут появиться во втором байте заголовка:
Условное обозначение | Десятичное значение | Описание |
INVALID | 0 | Это недопустимый тип. |
METHOD_CALL | 1 | Вызов метода. Этот тип сообщения может требовать ответа. |
METHOD_RETURN | 2 | Ответ метода с возвращенными данными. |
ERROR | 3 | Ответ об ошибке. Если первый аргумент существует и является строкой, это сообщение об ошибке. |
SIGNAL | 4 | Излучение сигнала. |
Флаги, которые могут появляться в третьем байте заголовка:
Условное обозначение | hex | Описание |
NO_REPLY_EXPECTED | 0x1 | Это сообщение не ожидает ответов метода или ошибок, даже если оно имеет тип, который может иметь ответ; ответ следует опустить. Обратите внимание, что METHOD_CALL - единственный тип сообщения из определенных в текущей спецификации, который может ожидать ответа, поэтому наличие или отсутствие этого флага в трех других типах сообщений, которые в настоящее время задокументированы, бессмысленно: ответы на эти типы сообщений не должны отправляться, независимо от того установлен этот флаг или нет. |
NO_AUTO_START | 0x2 | Шина не должна запускать владельца шинного имени назначения в ответ на это сообщение. |
ALLOW_INTERACTIVE_AUTHORIZATION | 0x4 | Этот флаг может быть установлен в сообщении о вызове метода, чтобы информировать принимающую сторону о том, что вызывающий абонент готов ждать интерактивной авторизации, для завершения которой может потребоваться значительное время. Например, если этот флаг установлен, было бы целесообразно запрашивать у пользователя пароли или подтверждение через Polkit или аналогичный фреймворк. Этот флаг полезен только тогда, когда непривилегированный код делает вызов более привилегированного метода, и когда развернута система авторизации, которая возможно, предоставляет интерактивную авторизацию. Если такая система не развернута, флаг не имеет никакого эффекта. Реализации клиентов не должны устанавливаться этот флаг по умолчанию. Если он установлен, вызывающий должен также установить достаточно длительный тайм-аут для вызова метода, чтобы убедиться, что взаимодействие с пользователем успеет завершиться. Этот флаг действителен только для сообщений о вызове методов и в противном случае должен игнорироваться. Взаимодействие, которое происходит как часть эффекта вызываемого метода, выходит за рамки этого флага, даже если его также можно охарактеризовать как аутентификацию или авторизацию. Например, в вызове метода, который указывает сервису управления сетью попытаться подключиться к виртуальной частной сети (VPN), этот флаг должен управлять тем, как сервис управления сетью принимает решение «разрешено ли этому пользователю изменять конфигурацию сети системы?», Но он не должно влиять на то, как сервис управления сетью будет взаимодействовать с пользователем для получения учетных данных, необходимых для доступа к VPN. Если этот флаг не установлен для вызова метода, и сервиса определяет, что запрошенная операция не разрешена без интерактивной авторизации, но может быть разрешена после успешной интерактивной авторизации, она может вернуть ошибку org.freedesktop.DBus.Error.InteractiveAuthorizationRequirederror. Отсутствие этого флага не гарантирует, что интерактивная авторизация не будет применена, поскольку существующие сервисы, которые предшествуют этому флагу, могут уже использовать интерактивную авторизацию. Однако существующие API‑интерфейсы D‑Bus, которые будут использовать интерактивную авторизацию, должны задокументировать, что вызов может занять больше времени, чем обычно, а новые API‑интерфейсы D‑Bus должны избегать интерактивной авторизации при отсутствии этого флага. |
Поля заголовка
Массив в конце заголовка содержит поля заголовка, где каждое поле представляет собой 1‑байтовый код поля, за которым следует значение поля. Заголовок должен содержать обязательные поля заголовка для своего типа сообщения и ноль или более любых дополнительных полей заголовка. В будущих версиях этой спецификации протокола могут быть добавлены новые поля. Реализации не должны изобретать свои собственные поля заголовка; новые поля заголовка могут вводить только изменения этой спецификации.
Если реализация видит код поля заголовка, которого она не ожидает, она должна принять и проигнорировать это поле, так как оно будет частью новой (но совместимой) версии этой спецификации. Это также относится к известным полям заголовка, появляющимся в неожидавшихся сообщениях, например: если сигнал имеет серийный номер ответа, его следует игнорировать, поскольку он не имеет значения в этой версии спецификации.
Однако реализации не должны отправлять или принимать известные поля заголовка с неправильным типом, хранящимся в значении поля. Так, например, сообщение с полем INTERFACE типа UINT32 будет считаться поврежденным.
Реализации сервера, которые могут ретранслировать сообщения от одного недоверенного клиента к другому, например, как на шина сообщений, должна удалить поля заголовка, которые сервер не распознает. Однако клиент должен предполагать, что сервер этого не сделал, если только он не имеет доказательств обратного, например, проверив функцию шины сообщения HeaderFiltering .
Новые поля заголовка, управляемые шиной сообщений (аналогичные SENDER), могут быть добавлены в эту спецификацию в будущем. Такие поля сообщений обычно следует добавлять только к сообщениям, которые будут доставлены клиенту, который их специально запросил (например, вызвав какой‑либо метод), а шина сообщений должна удалить эти поля заголовка из всех других сообщений, которые она ретранслирует. Этот принцип устройства служит двум основным целям. Одна из них - избежать ненужных затрат памяти и пропускной способности при доставке сообщений клиентам, которым не интересны новые поля заголовка. Другая - дать клиентам причину вызвать метод, запрашивающий эти сообщения (в противном случае клиенты не будут работать). Это желательно, потому что просмотр ответа на вызов этого метода - естественный способ проверить, гарантирует ли шина сообщений фильтрацию ложных полей заголовка, которые могли быть отправлены злонамеренными узлами.
Вот определенные в настоящее время поля заголовка:
Условное обозначение | Десятичный код | Тип | Где требуется | Описание |
INVALID | 0 | N/A | не допускается | Недействительное имя поля (ошибка, если оно появляется в сообщении) |
PATH | 1 | OBJECT_PATH | METHOD_CALL, SIGNAL | Объект, которому отправляется вызов или объект, из которого исходит сигнал. Зарезервирован специальный путь /org/ freedesktop/DBus/Local; реализации не должны отправлять сообщения с этим путем, а эталонная реализация демона шины отключит любое приложение, которое пытается это сделать. Это поле заголовка контролируется отправителем сообщения. |
INTERFACE | 2 | STRING | SIGNAL | Интерфейс, выполняющий вызов метода или из которого исходит сигнал. Необязательный для вызовов методов, требуется для сигналов. Зарезервирован специальный интерфейс org.freedesktop.DBus.Local; реализации не должны отправлять сообщения с этим интерфейсом, а эталонная реализация демона шины отключит любое приложение, которое пытается это сделать. Это поле заголовка контролируется отправителем сообщения. |
MEMBER | 3 | STRING | METHOD_CALL, SIGNAL | Член, либо имя метода, либо имя сигнала. Это поле заголовка контролируется отправителем сообщения. |
ERROR_NAME | 4 | STRING | ERROR | Название возникшей ошибки, для ошибок |
REPLY_SERIAL | 5 | UINT32 | ERROR, METHOD_RETURN | Порядковый номер сообщения, на которое это сообщение является ответом. (Порядковый номер является вторым UINT32 в заголовке.) Это поле заголовка контролируется отправителем сообщения. |
DESTINATION | 6 | STRING | необязательный | Имя соединения, для которого предназначено это сообщение. Это поле обычно имеет смысл только в сочетании с шиной сообщений (см. Раздел «Спецификация шины сообщений»), но другие серверы могут определять для него свои собственные значения. Это поле заголовка контролируется отправителем сообщения. |
SENDER | 7 | STRING | необязательный | Уникальное имя отправляющего соединения. Это поле обычно имеет значение только в сочетании с шиной сообщений, но другие серверы могут определять для него свои собственные значения. На шине сообщений это поле заголовка контролируется шиной сообщений, поэтому оно так же надежно и заслуживает доверия, как и сама шина сообщений. В противном случае это поле заголовка контролируется отправителем сообщения, если нет дополнительной информации, указывающей на иное. |
SIGNATURE | 8 | SIGNATURE | необязательный | Сигнатура тела сообщения. Если опущено, предполагается, что это пустая подпись "" (т.е. длина тела должна быть 0). Это поле заголовка контролируется отправителем сообщения. |
UNIX_FDS | 9 | UINT32 | необязательный | Количество файловых дескрипторов Unix, сопровождающих сообщение. Если он опущен, предполагается, что сообщение не сопровождается дескрипторами файлов Unix. Фактические файловые дескрипторы необходимо передавать по дополнительному механизму, зависящему от платформы. Они должны быть отправлены одновременно с самим сообщением. Они не могут быть отправлены до передачи первого байта самого сообщения или после последнего байта самого сообщения. Это поле заголовка контролируется отправителем сообщения. |
Допустимые имена
Разнообразие имен в сообщениях D‑Bus имеет некоторые ограничения.
Для шинных имен, интерфейсов и членов установлена максимальная длина имени 255.
Имена интерфейсов
Интерфейсы имеют имена с типом STRING, что означает, что они должны соответствовать UTF‑8. Однако есть также некоторые дополнительные ограничения, которые относятся конкретно к именам интерфейсов:
Имена интерфейсов состоят из 2 или более элементов, разделенных точкой ('.'). Все элементы должны содержать хотя бы один символ.
Каждый элемент должен содержать только символы ASCII «[A‑Z] [a‑z] [0‑9] _» и не должен начинаться с цифры.
Имена интерфейсов не должны превышать максимальную длину имени.
Имена интерфейсов должны начинаться с перевернутого имени домена DNS автора интерфейса (в нижнем регистре), подобно именам интерфейсов в Java. Обычно, остальная часть имени интерфейса состоит из слов, идущих подряд, с начальными заглавными буквами во всех словах («Верблюжий регистр»). Можно использовать несколько уровней иерархии. Также неплохо включить в имя основную версию интерфейса и увеличить ее, если внесены несовместимые изменения; таким образом, один объект может при необходимости реализовать несколько версий интерфейса параллельно.
Например, если владелец example.com разрабатывает D‑Bus API для музыкального проигрывателя, он может определить интерфейсы с именами com.example.MusicPlayer1, com.example.MusicPlayer1.Track и com.example.MusicPlayer1.Seekable.
Если имя домена DNS автора содержит символы дефиса/минуса ('-'), которые не разрешены в именах интерфейсов D‑Bus, их следует заменить подчеркиванием. Если имя домена DNS содержит цифру, следующую сразу за точкой ('.'), (что также недопустимо в именах интерфейсов), в имени интерфейса перед этой цифрой должен быть добавлен символ подчеркивания. Например, если владелец 7‑zip.org определил интерфейс для плагинов вне процесса, он может называться org._7_zip.Plugin.
D-Bus не делает различий между концепциями, которые в Java назывались бы классами и интерфейсами: любой из них можно идентифицировать на D‑Bus по имени интерфейса.
Шинные имена
Соединения имеют одно или несколько шинных имен, связанных с ними. У соединения есть ровно одно шинное имя, которое является уникальным именем соединения. Уникальное имя соединения остается у соединения в течение всего его срока жизни. Шинное имя имеет тип STRING, что означает, что оно должно быть допустимым UTF‑8. Однако есть также некоторые дополнительные ограничения, которые применяются конкретно к шинным именам:
Шинные имена, начинающиеся с символа двоеточия (':'), являются уникальными именами соединений. Другие шинные имена называются общеизвестными шинными именами.
Шинные имена состоят из 1 или более элементов, разделенных точкой ('.'). Все элементы должны содержать хотя бы один символ.
Каждый элемент должен содержать только символы ASCII «[A‑Z] [a‑z] [0-9] -», при этом «-» не рекомендуется использовать в новых шинных именах. Только элементы, которые являются частью уникального имени соединения, могут начинаться с цифры, элементы в других шинных именах не должны начинаться с цифры.
В шинном имени должен быть хотя бы один символ «.» (точка) (и, следовательно, как минимум два элемента).
Шинные имена не должны начинаться с символа «.» (точка).
Длина шинного имени не должна превышать максимальную длину.
Обратите внимание, что символ дефиса ('-') разрешен в шинных именах, но не в именах интерфейсов. Это также проблематично или не разрешено в различных спецификациях и API‑интерфейсах, которые относятся к D‑Bus, таких как идентификаторы приложений Flatpak, интерфейс DBusActivatable в спецификации Desktop Entry, а также соглашение о том, что «основной» интерфейс приложения и путь к объекту похожи на его шинное имя. Чтобы избежать ситуаций, требующих специальной обработки, рекомендуется, чтобы в новых именах D‑Bus неуклонно заменяли дефис на подчеркивание.
Как и имена интерфейсов, общеизвестные шинные имена должны начинаться с перевернутого имени домена DNS автора интерфейса (в нижнем регистре), и обычно остальная часть общеизвестного шинного имени состоит из слов, соединенных вместе, с начальными заглавными буквами. Как и в случае с именами интерфейсов, неплохо было бы включить номер версии в общеизвестные шинные имена; возможно иметь общеизвестные шинные имена для нескольких версий одновременно, если требуется обратная совместимость.
Как и в случае с именами интерфейсов, если имя домена DNS автора содержит символы дефиса/минуса, они должны быть заменены знаками подчеркивания, а если оно содержит ведущие цифры, их следует экранировать, добавив знак подчеркивания. Например, если владелец 7-zip.org использовал имя D‑Bus для приложения архивации, оно могло бы называться org._7_zip.Archiver.
Если общеизвестное имя шины подразумевает наличие «основного» интерфейса, этому «главному» интерфейсу часто дается то же имя, что и общеизвестное шинное имя, и оно располагается в соответствующем объектном пути. Например, если владелец example.com разрабатывает API D-Bus для музыкального проигрывателя, он может установить, что любое приложение, которое получает хорошо известное имя com.example.MusicPlayer1 , в реализации интерфейса com.example.MusicPlayer1 должно иметь объект, с объектный путём /com/example/MusicPlayer1 .
Имена членов
Имена членов (то есть методов или сигналов):
Должны содержать только символы ASCII «[A-Z] [a-z] [0-9] _» и не могут начинаться с цифры.
Не должны содержать символ "." (точка).
Длина не должна превышать максимальную длину имени.
Длина должна быть не менее 1 байта.
Обычно имена членов на D‑Bus состоят из прописных слов без знаков препинания («верблюжий регистр»). Имена методов обычно должны быть глаголами, такими как GetItems , а имена сигналов обычно должны быть описанием события, например ItemsChanged .
Имена ошибок
Имена ошибок имеют те же ограничения, что и имена интерфейсов и часто содержат .Error.; например, владелец example.com может определить errorcom.example.MusicPlayer1.Error.FileNotFound и com.example.MusicPlayer1.Error.OutOfMemory . Ошибки, определенные в самом D‑Bus, такие как org.freedesktop.DBus.Error.Failed , следуют аналогичному шаблону.
Типы сообщений
Каждый из типов сообщений (METHOD_CALL, METHOD_RETURN, ERROR и SIGNAL) ожидаемо имеет свои собственные соглашения об использовании и поля заголовка. В этом разделе описаны эти соглашения.
Вызов методов
Некоторые сообщения вызывают операцию на удаленном объекте. Они называются сообщениями о вызове методов и имеют тег типа METHO_DCALL. Такие сообщения естественно отображаются в обычной программе в методы объектов.
Сообщение о вызове метода должно иметь поле заголовка MEMBER, указывающее имя метода. Опционально, сообщение может иметь поле INTERFACE, в котором указывается интерфейс, частью которого является метод. Настоятельно рекомендуется включать INTERFACE во все сообщения о вызове методов.
В отсутствие поля INTERFACE, если два или более интерфейса одного и того же объекта имеют методы с одинаковыми именами, то не определено, какой из этих методов будет вызван. Реализации могут выбрать либо возврат ошибки, либо доставить сообщение одному, произвольно выбранному из этих интерфейсов.
В некоторых ситуациях (например, в общеизвестной системной шине) сообщения фильтруются через список управления доступом, внешний по отношению к реализации удаленного объекта. Если этот фильтр отклоняет определенные сообщения путем сопоставления их интерфейса или принимает только сообщения для определенных интерфейсов, он также должен отклонять сообщения, у которых нет INTERFACE: в противном случае вредоносные приложения могли бы использовать это для обхода фильтра.
Сообщения о вызове метода также включают поле PATH, указывающее объект, для которого нужно вызвать метод. Если вызов проходит через шину сообщений, в сообщении также будет поле DESTINATION, в котором будет указано имя соединения для получения сообщения.
Когда приложение обрабатывает сообщение о вызове метода, оно должно вернуть ответ. Ответ идентифицируется полем заголовка REPLY_SERIAL, указывающим серийный номер METHOD_CALL, на который осуществляется ответ. Ответ может быть одного из двух типов; либо METHOD_RETURN, либо ERROR.
Если ответ имеет тип METHOD_RETURN, аргументами ответного сообщения являются возвращаемое значение (значения) или «выходные параметры» вызова метода. Если ответ имеет тип ERROR, то возникло «исключение» и вызов завершился неудачно; возвращаемого значения не будет. Нет смысла отправлять несколько ответов на один и тот же вызов метода.
Даже если вызов метода не имеет возвращаемых значений, требуется ответ METHOD_RETURN, по которому вызывающий будет знать, что метод был успешно обработан.
Ответное сообщение METHOD_RETURN или ERROR должно иметь поле заголовка REPLY_SERIAL.
Если сообщение METHOD_CALL имеет флаг NO_REPLY_EXPECTED, то приложение, получающее метод, не должно отправлять ответное сообщение (независимо от того, был ли ответом METHOD_RETURN или ERROR).
Если у сообщения нет флага NO_AUTO_START, если имя пункта назначения не существует, то программа, владеющая именем пункта назначения, будет запущена (активирована) до того, как сообщение будет доставлено. См. Раздел «Сервисы запуска шины сообщений (активация)» . Сообщение будет удерживаться до тех пор, пока новая программа не будет успешно запущена или потерпит неудачу при старте; в случае неудачи будет возвращена ошибка. Этот флаг уместен только в контексте шины сообщений, он игнорируется при соединении точка-точка без промежуточной шины.
Отображение вызовов методов на API
в сообщение D-Bus.API для D‑Bus могут отображать вызовы метода в вызов метода на определенном языке программирования, таком как C++, или могут отображать вызов метода, описанного на IDL.
В API такого рода аргументы метода часто называются «in» («входящими») (что подразумевает отправку в METHOD_CALL) или «out» («исходящие», что подразумевает возвращение с METHOD_RETURN). Некоторые API, такие как CORBA, также имеют аргументы «inout», которые отправляются и принимаются, т.е. вызывающий объект передает значение, которое изменяется. В D-Bus аргумент «inout» эквивалентен аргументу «in», за которым следует аргумент «out». Вы не можете передавать по сети вещи «по ссылке», поэтому «inout» - это просто иллюзия внутрипроцессного API.
Для метода с нолём или одним возвращаемым значением, за которым следуют ноль или более аргументов, где каждый аргумент может быть «in», «out» или «inout», вызывающая сторона создает сообщение, добавляя по порядку каждое «in» или «inout». Аргументы "out" не фигурируют в сообщении вызывающего абонента.
Получатель создает ответ, добавляя сначала возвращаемое значение, если оно есть, а затем по порядку каждый аргумент «out» или «inout» . Аргументы "in" не представлены в ответном сообщении.
Обычно, ответы об ошибках в языках отображаются в исключения, если они там есть.
При преобразовании собственных API-интерфейсов в D‑Bus, возможно, было бы неплохо автоматически отображать соглашения об именах D‑Bus («FooBar») на собственные соглашения, такие как «fooBar» или «foobar». Это нормально, если вы можете сказать, что собственный API был специально написан для D‑Bus. Это имеет наибольшее значение при написании реализаций объектов, которые будут экспортироваться по шине. Прокси‑серверы объектов, используемые для вызова удаленных объектов D‑Bus, вероятно, нуждаются в возможности вызывать любой метод D‑Bus, и, следовательно, подобное волшебное отображение имен может быть проблемой.
Эта спецификация не требует никаких привязок собственного API; приведенное выше является лишь предложенным соглашением для согласованности привязок.
Излучение сигнала
В отличие от вызовов методов, на излучение сигналов нет ответов. Излучение сигнала - это просто одно сообщение типа SIGNAL. Оно должно иметь три поля заголовка: PATH, указывающий на объект, из которого был испущен сигнал, плюс INTERFACE и MEMBER, указывающие полное имя сигнала. Заголовок INTERFACE необходим для сигналов, но не является обязательным для вызовов методов.
Ошибки
Сообщения типа ERROR чаще всего являются ответами на METHOD_CALL, но могут быть возвращены в ответ на любое сообщение. Шина сообщений, например, вернет ERROR в ответ на передачу сигнала, если у шины недостаточно памяти для отправки сигнала.
ERROR может иметь любые аргументы, но если первый аргумент - STRING, это должно быть сообщение об ошибке. Сообщение об ошибке может быть записано в журнал или каким-либо образом показано пользователю.
Нотация в этом документе
В этом документе используется простой псевдо-IDL для описания вызовов и сигналов конкретных методов. Вот пример вызова метода:
org.freedesktop.DBus.StartServiceByName (in STRING name,
in UINT32 flags,
out UINT32 resultcode)
Это означает, что INTERFACE = org.freedesktop.DBus , MEMBER = StartServiceByName, аргументы METHOD_CALL - STRING и UINT32, аргумент METHODRETURN - UINT32. Помните, что поле MEMBER не может содержать "." (точка), поэтому понятно, что последняя часть имени в «IDL» является именем члена.
В C ++ это может выглядеть так:
unsigned int org::freedesktop::DBus::StartServiceByName (
const char *name,
unsigned int flags);
или в равной степени реализуемый вариант где возвращаемое значение может быть сделано аргументом:
void org::freedesktop::DBus::StartServiceByName (const char *name,
unsigned int flags,
unsigned int *resultcode);
Каким будет внешний вид в действительности, зависит от разработчика API. Вы можете разработать API не используя пространство имен C++, применяя STL или Qt, varargs или что-то другое.
Сигналы записываются следующим образом:
org.freedesktop.DBus.NameLost (STRING name)
В сигналах не указывается «in » или «out », потому что возможно только одно направление.
Не особо рекомендуется использовать этот убогий псевдо-IDL в существующих реализациях API; вы можете применять собственную нотацию для используемого вами языка или, например, использовать COM или CORBA IDL.
Недопустимые расширения протокола и спецификации
По соображениям безопасности протокол D‑Bus следует строго анализировать и проверять, за исключением определенных точек расширения. Любые недопустимые нарушения протокола или спецификации должны привести к немедленному разрыву соединения без уведомления на другом конце. Следует внимательно рассмотреть исключения, например, может потребоваться исключение из-за хорошо изученной идиосинкразии общеизвестной реализации. В случаях, когда другой конец соединения является 100% доверенным и заведомо дружественным, пропуск проверки по причинам производительности также может иметь смысл в некоторых случаях.
Вообще говоря, нарушения требований "должен" в этой спецификации следует рассматривать как возможные попытки использования системы безопасности, а нарушения предложений "следует" следует рассматривать как законные (хотя, возможно, они должны вызывать ошибку в некоторых случаях).
Следующие точки расширения специально встроены в D‑Bus и не должны рассматриваться как недопустимый протокол. Точки расширения предназначены для использования в будущих версиях этой спецификации, они не предназначены для третьих лиц. На данный момент единственный способ, которым третья сторона может расширить D‑Bus, не нарушая взаимодействия, - это ввести способ согласования поддержки новых функций как части протокола аутентификации с использованием команд с префиксом EXTENSION. Стандартного способа согласования функций пока нет.
В протоколе аутентификации (см. Раздел «Протокол аутентификации») неизвестные команды приводят к ERROR, а не к разъединению. Это позволяет в будущем расширять протокол. Команды, начинающиеся с EXTENSION, зарезервированы для третьих лиц.
Протокол аутентификации поддерживает подключаемые механизмы аутентификации.
Формат адреса (см. Раздел «Адреса серверов») поддерживает новые виды транспорта.
Сообщения с неизвестным типом (что-то кроме METHOD_CALL, METHOD_RETURN, ERROR, SIGNAL) игнорируются. Сообщения неизвестного типа должны быть тем не менее правильно сформированы так же, как и известные сообщения. У них должны быть нормальные заголовок и тело.
Поля заголовка с неизвестным или неожиданным кодом поля должны быть проигнорированы, хотя, опять же, они должны быть правильно сформированы.
Конечно, могут быть добавлены новые стандартные интерфейсы (с новыми методами и сигналами).