Using a struct[enum] as an sdbusplus D-Bus method arg?
Matt Spinler
mspinler at linux.ibm.com
Fri Jan 10 04:25:24 AEDT 2020
On 1/9/2020 10:22 AM, Patrick Williams wrote:
> On Wed, Jan 08, 2020 at 01:32:49PM -0600, Matt Spinler wrote:
>
> Hi Matt,
>
>> I'm designing a phosphor-dbus-interfaces D-Bus method where I think the
>> ideal interface has YAML like:
>>
>> - name : CreateStuff
>> parameters:
>> - name: Data
>> type: array[struct[enum[self.Types], uint32]]
>>
>> But that doesn't compile using an enum in the struct, and fails because
>> sdbus++ creates code like:
>>
>> server.cpp:
>>
>> // Uses enum<self.Types>
>> std::vector<std::tuple<enum<self.Types>, uint8_t>> data{};
>> m.read(data);
>> auto o = static_cast<Create*>(context);
>> o->createStuff(data);
>>
>> What I'm trying to do is a valid D-Bus definition, correct? Or should I just
>> use a string instead
>> of an enum?
> Enums are not actually a DBus concept, but something we added to
> sdbusplus specifically. What happens is that at the DBus level we send
> them between processes as fully-qualified strings[1]. In the sdbusplus
> generated code we know that this was defined in the YAML as an enum and
> so we look the string up in a map<string, enum> to get you the enum
> value (and throw an exception if an invalid enum was given).
>
> I wouldn't recommend using a string instead because you are just
> bypassing this enum-string checking code.
>
>> It doesn't seem very straightforward to fix, as the vector that gets passed
>> to o->createStuff()
>> is a std::vector<std::tuple<Types, uint32_t>>, but the vector passed to
>> m.read() is a
>> std::vector<std::tuple<std::string, uint32_t>>.
> This is a bug / missing feature in the header generator. I'd have to
> look into the code but it seems like it is not re-cursing inside the
> tuple correctly. We handle this case fine for raw enums. The
> definition of data's type looks like a start of the problem
> (enum<self.Types> doesn't seem correct to me). It's possible though
> that the m.read generated function is wrong in that it is missing the
> conversion from self.Types <-> std::string.
Since the vectors are of different types, I think the code generated
code would have to
do the equivalent of?
std::vector<std::tuple<std::string, uint8_t>> data{};
m.read(data);
std::vector<std::tuple<Types, uint8_t>> apiData{};
for (const auto& [arg0, arg1]: data)
apiData.emplace_back(convertStringToEnum(arg0), arg1))
o->createStuff(apiData);
That's a pretty big change from what's there today. Think that's possible
to do generically?
> [1] A fully-qualified string is something like
> xyz.openbmc-project.InterfaceClass.EnumType.EnumValue.
More information about the openbmc
mailing list