# Interface YAML D-Bus interfaces can be defined by creating a YAML file to describe the methods, properties, and signals they contain. From this YAML file, both documentation and binding code may be generated. ## YAML sections An interface YAML may have the following sections: * description - A small documentation section describing the purpose of the interface. * methods - A list of methods provided by this D-Bus interface. * properties - A list of properties provided by this D-Bus interface. * signals - A list of signals generated by this D-Bus interface. * enumerations - A list of enumerations defined by this D-Bus interface. ## Enumerations A common problem we have found with D-Bus interfaces is having a consistent way to define enumerations. Two common practices are to either assign special meaning to integers, as a C compiler might do, or to have specific strings representing the enumeration name. The [D-Bus API design guidelines](https://dbus.freedesktop.org/doc/dbus-api-design.html) specify both of these options: > For APIs being used in constrained situations, enumerated values should be > transmitted as unsigned integers. For APIs which need to be extended by > third parties or which are used in more loosely coupled systems, enumerated > values should be strings in some defined format. What we have done in `sdbus++` is to consider enumerations as a first-class type. Within an interface you can define an enumeration and the bindings will have a C++ enumeration defined for it. At a D-Bus level any property or method parameter will be a string, but the string will contain a fully-qualified name "interface.enum-name.enum-value" like "org.freedesktop.Example.Color.Red". Within the generated bindings, an automatic conversion is done between strings and C++ enumeration values and clients will get an "xyz.openbmc_project.sdbusplus.Error.InvalidEnumString" error response if they attempt to use an invalid string value. An enumeration must have the YAML properties `name` and `values` and may optionally contain a `description`. The `name` is a word corresponding to the desired "enum-name" portion of the fully-qualified name and the resulting C++ enum type. The `values` are a list of enumeration values each containing their own `name` and optional `description`. Example: ``` enumerations: - name: Suits description: > The suits found in a deck of cards. values: - name: Diamonds - name: Hearts - name: Clubs description: > This is the suit that looks like a clover. - name: Spades ``` ## Types ### Base types Types are identified in YAML using their typename found in the [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html), but listed using lowercases: `int64` instead of `INT64` or C++ `int64_t`. * byte * boolean * int16 * uint16 * ... * uint64 * double * unixfd * string * object_path * signature ### Containers Container types can also be expressed, but the contained-type should be expressed within square-brackets `[]`. The following containers are supported: * `array[type]` - C++ type is `std::vector` * `struct[type0, type1, ...]` - C++ type is `std::tuple` * `variant[type0, type1, ...]` - C++ type is `std::variant` * `dict[keytype, valuetype]` - C++ type is `std::map` It may seem odd that variants are required to list the types they may contain, but this is due to C++ being a strongly-typed language. In order to generate bindings, to read from and append to a message, the binding generator must know all possible types the variant may contain. ### Enumerations Enumerations are expressed like a container, but the contained-type is an identifier of the fully-qualified enum-name or a shortened `self.` identifier for locally defined types. * enum[org.freedesktop.Example.Suits] * enum[self.Suits] ## Methods A method must have the YAML property `name` and may optionally have `parameters`, `returns`, `errors`, and `description`. Each parameter must have a `name`, `type`, and optional `description`. Each return must have a `type` and may optionally have a `name` and `description`. Errors are a list of fully-qualified or shortened `self.` identifiers for errors the method may return, which must be defined in a corresponding errors YAML file. Example: ``` methods: - name: Shuffle errors: - self.Error.TooTired - name: Deal description: > Deals a new hand to each player. errors: - self.Error.OutOfCards - name: LookAtTop returns: - name: Card type: struct[enum[self.Suit], byte] - name: MoveToTop parameters: - name: Card type: struct[enum[self.Suit], byte] ``` ## Properties A property must have the YAML property `name` and `type` and may optionally have `description`, `flags`, `default`, and `errors`. The `default` defines the default value of the property. See the `Methods` section above for more information on errors. The only current supported value for `flags` is `const`, which corresponds to SD_BUS_VTABLE_PROPERTY_CONST, making the property read-only via D-Bus but still writable by the app implementing it. Example: ``` properties: - name: CardsRemaining type: uint32 default: 52 flags: - const description: > The number of cards remaining in the deck. errors: - self.Error.InvalidNumber ``` ## Signals A signal must have the YAML property `name` and may optionally have a `description` and list of `properties`. Properties are specified the same as interface properties. Example: ``` signals: - name: Shuffled description: > The deck has been shuffled. - name: Cheated properties: - name: CardToTop type: struct[enum[self.Suit], byte] ```