]>
Commit | Line | Data |
---|---|---|
c1b9d935 LP |
1 | How we use GVariant for serializing D-Bus messages |
2 | -------------------------------------------------- | |
3 | ||
2ac7c17f LP |
4 | We stay close to the original dbus1 framing as possible, but make |
5 | certain changes to adapt for GVariant. dbus1 has the following | |
6 | framing: | |
c1b9d935 LP |
7 | |
8 | 1. A fixed header of "yyyyuu" | |
9 | 2. Additional header fields of "a(yv)" | |
10 | 3. Padding with NUL bytes to pad up to next 8byte boundary | |
11 | 4. The body | |
12 | ||
13 | Note that the body is not padded at the end, the complete message | |
14 | hence might have a non-aligned size. Reading multiple messages at once | |
15 | will hence result in possibly unaligned messages in memory. | |
16 | ||
17 | The header consists of the following: | |
18 | ||
19 | y Endianness, 'l' or 'B' | |
20 | y Message Type | |
21 | y Flags | |
22 | y Protocol version, '1' | |
23 | u Length of the body, i.e. the length of part 4 above | |
2ac7c17f | 24 | u 32bit Serial number |
c1b9d935 LP |
25 | |
26 | = 12 bytes | |
27 | ||
af86c440 ZJS |
28 | This header is then followed by the fields array, whose first value is |
29 | a 32bit array size. | |
2ac7c17f | 30 | |
c1b9d935 | 31 | When using GVariant we keep the basic structure in place, only |
2ac7c17f | 32 | slightly alter the header, and define protocol version '2'. The new |
c1b9d935 LP |
33 | header: |
34 | ||
35 | y Endianness, 'l' or 'B' | |
36 | y Message Type | |
37 | y Flags | |
38 | y Protocol version, '2' | |
2ac7c17f LP |
39 | u Reserved, must be 0 |
40 | t 64bit Cookie | |
c1b9d935 LP |
41 | |
42 | = 16 bytes | |
43 | ||
2ac7c17f LP |
44 | This is then followed by the GVariant fields array ("a{tv}"), and |
45 | finally the actual body as variant (v). Putting this altogether a | |
46 | packet on dbus2 hence qualifies as a fully compliant GVariant | |
47 | structure of (yyyyuta{tv}v). | |
48 | ||
49 | For details on gvariant, see: | |
50 | ||
51 | https://people.gnome.org/~desrt/gvariant-serialisation.pdf | |
52 | ||
53 | Regarding the framing of dbus2, also see: | |
54 | ||
55 | https://wiki.gnome.org/Projects/GLib/GDBus/Version2 | |
56 | ||
57 | The first four bytes of the header are defined the same way for dbus1 | |
5238e957 | 58 | and dbus2. The first bytes contain the endianness field and the |
2ac7c17f LP |
59 | protocol version, so that the remainder of the message can be safely |
60 | made sense of just by looking at the first 32bit. | |
61 | ||
62 | Note that the length of the body is no longer included in the header | |
63 | on dbus2! In fact, the message size must be known in advance, from the | |
64 | underlying transport in order to parse dbus2 messages, while it is | |
65 | directly included in dbus1 message headers. This change of semantics | |
66 | is an effect of GVariant's basic design. | |
67 | ||
68 | The serial number has been renamed cookie and has been extended from | |
69 | 32bit to 64bit. It is recommended to avoid the higher 32bit of the | |
70 | cookie field though, to simplify compatibility with dbus1 peers. Note | |
71 | that not only the cookie/serial field in the fixed header, but also | |
72 | the reply_cookie/reply_serial additional header field has been | |
73 | increased from 32bit to 64bit, too! | |
74 | ||
75 | The header field identifiers have been extended from 8bit to | |
7ebf71ee DR |
76 | 64bit. This has been done to simplify things, and has no effect |
77 | on the serialization size, as due to alignment for each 8bit | |
78 | header field identifier 56 bits of padding had to be added. | |
2ac7c17f LP |
79 | |
80 | Note that the header size changed, due to these changes. However, | |
81 | consider that on dbus1 the beginning of the fields array contains the | |
82 | 32bit array size (since that is how arrays are encoded on dbus1), | |
83 | thus, if one considers that size part of the header, instead of the | |
84 | array, the size of the header on dbus1 and dbus2 stays identical, at | |
85 | 16 bytes. | |
c1b9d935 LP |
86 | |
87 | 0 4 8 12 16 | |
2ac7c17f | 88 | Common: | E | T | F | V | ... |
c1b9d935 | 89 | |
2ac7c17f | 90 | dbus1: | (as above) | Body Length | Serial | Fields Length | Fields array ... |
c1b9d935 | 91 | |
2ac7c17f | 92 | gvariant: | (as above) | Reserved | Cookie | Fields array ... |
c1b9d935 LP |
93 | |
94 | And that's already it. | |
95 | ||
7ebf71ee DR |
96 | Note: To simplify parsing, valid dbus2 messages must include the entire |
97 | fixed header and additional header fields in a single non-memfd | |
98 | message part. Also, the signature string of the body variant all the | |
99 | way to the end of the message must be in a single non-memfd part | |
100 | too. The parts for this extended header and footer can be the same | |
101 | one, and can also continue any amount of additional body bytes. | |
6647dc66 LP |
102 | |
103 | Note: The GVariant "MAYBE" type is not supported, so that messages can | |
104 | be fully converted forth and back between dbus1 and gvariant | |
105 | representations. |