libei/doc/protocol/overview.md

3.1 KiB

title draft archetype weight
Protocol Overview false chapter 1

Protocol Components

The ei protocol has three components: objects, requests and events. It is designed to be connect two processes over a UNIX socket - an ei client and an EIS implementation (typically a Wayland compositor). The protocol is asynchronous and object-based.

Whenever a message (request or event) is sent, that message carries an identifier for the object. The type of an object is defined by its interface - the interfaces are detailed here in this protocol. Thus, when a message for an object arrives, the client or EIS implementation can invoke the corresponding function on the object.

An object has exactly one interface but there may be multiple objects with the same interface (e.g. multiple devices all use the ei_device interface).

Requests are messages sent from an ei client to an EIS implementation, events are messages sent from the EIS implementation to the client. This is the same nomenclature that the Wayland protocol uses.

The ei protocol is modelled closely after the Wayland protocol, but it is not binary compatible.

Wire Format

The wire format consists of a 3-element header comprising the sender-id of the object, the length of the message and the opcode representing the message itself.

byte:     |0         |4         |8        |12        |16
content:  |sender-id            |length   |opcode    |...

Where:

  • sender-id is one 64-bit unsigned integer
  • length and opcode are 32-bit unsigned integers
  • all integers are in the EIS implementation's native byte order.
  • length is the length of the message in bytes, including the 16 header bytes for sender-id, length and opcode.
  • sender-id is the id of the object sending the request/event. The sender-id 0 is reserved for the special [ei_handshake]({{< relref "interfaces/ei_handshake" >}}) object.
  • opcode is the event or request-specific opcode, starting at 0. requests and events have overlapping opcode ranges, i.e. the first request and the first event both have opcode 0.

The header is followed by the message-specific arguments. All arguments are 4 bytes or padded to a multiple of 4 bytes.

Version negotiation

For objects to be created, the EIS implementation and the client must agree on a supported version for each object. This agreement happens during the initial setup in ei_handshake

  • the client notifies the EIS implementation of the highest supported version for an interface, e.g. in the ei_handshake.interface_version request
  • the EIS implementation responds by selecting the highest version the EIS implementation supports but not higher than the client version. It may notify the client of that version before ei_handshake.connection.

An exception to this is the ei_handshake.handshake_version request and event where the EIS implementation initializes the version exchange and thus the client picks the version number.

In both cases, the version number used is simply v = min(eis_version, client_version).

Whenever an object is created, the version number of that object must be sent in the corresponding request or event.