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