#3 Introspection for top-level nodes in dbusxml2qt3

Open
opened 7 months ago by deloptes · 25 comments

Basic information

  • TDE version: 14.1.0
  • Distribution: Debian Stretch
  • Hardware: amd64

Description

When looking in TDE/tdelibs#9, it turns out that it is not clear how one would create interface to top-level nodes that have children but do not accommodate any interface (except Introspectable by default)

https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format states:

Only the root element can omit the node name, as it’s known to be the object that was introspected. If the root does have a name attribute, it must be an absolute object path. If child have object paths, they must be relative.

If a child has any sub-elements, then they must represent a complete introspection of the child. If a child is empty, then it may or may not have sub-elements; the child must be introspected in order to find out. The intent is that if an object knows that its children are “fast” to introspect it can go ahead and return their information, but otherwise it can omit it.

So it should be able to generate node class with Introspectable interface out of

<node>
  <node name="hardwarecontrol" />
</node>

which it does not

Steps to reproduce

  1. execute dbus-send --print-reply=literal --system --dest=org.trinitydesktop.hardwarecontrol /org/trinitydesktop org.freedesktop.DBus.Introspectable.Introspect > /tmp/test.xml
  2. cd /tmp && dbusxml2qt3 test.xml
dbusxml2qt3: introspection data file 'test.xml' does not contain any valid interface descriptions

that comes from dbus-1-tqt/tools/dbusxml2qt3/main.cpp

My question here is how is it supposed to work properly? Is it a bug or is it a feature.

<!-- This is a comment. Please fill in the required fields below. The comments provide instructions on how to do so. Note: You do not need to remove comments. --> ## Basic information - TDE version: 14.1.0 - Distribution: Debian Stretch - Hardware: amd64 <!-- Use SL/* labels to set the severity level. Please do not set a milestone. --> ## Description When looking in https://mirror.git.trinitydesktop.org/gitea/TDE/tdelibs/issues/9, it turns out that it is not clear how one would create interface to top-level nodes that have children but do not accommodate any interface (except Introspectable by default) https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format states: >Only the root element can omit the node name, as it’s known to be the object that was introspected. If the root does have a name attribute, it must be an absolute object path. If child have object paths, they must be relative. > >If a child has any sub-elements, then they must represent a complete introspection of the child. If a child is empty, then it may or may not have sub-elements; the child must be introspected in order to find out. The intent is that if an object knows that its children are “fast” to introspect it can go ahead and return their information, but otherwise it can omit it. So it should be able to generate node class with Introspectable interface out of ``` <node> <node name="hardwarecontrol" /> </node> ``` which it does not ## Steps to reproduce 1. execute `dbus-send --print-reply=literal --system --dest=org.trinitydesktop.hardwarecontrol /org/trinitydesktop org.freedesktop.DBus.Introspectable.Introspect > /tmp/test.xml` 2. `cd /tmp && dbusxml2qt3 test.xml` ``` dbusxml2qt3: introspection data file 'test.xml' does not contain any valid interface descriptions ``` that comes from dbus-1-tqt/tools/dbusxml2qt3/main.cpp My question here is how is it supposed to work properly? Is it a bug or is it a feature.
MicheleC commented 7 months ago
Owner

I see no error.
In 1. you are introspecting “org.trinitydesktop” and the answer tells you there is a service called “hardwarecontrol”. There is no interface in the reply because you are not introspecting at interface level. You need to use

dbus-send --print-reply=literal --system --dest=org.trinitydesktop.hardwarecontrol /org/trinitydesktop/hardwarecontrol org.freedesktop.DBus.Introspectable.Introspect

if you want to introspect the interface provided by “org.trinitydesktop.hardwarecontrol”

You can try these other example for further studies.

dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 /org/freedesktop/PolicyKit1 org.freedesktop.DBus.Introspectable.Introspect

dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 /org/freedesktop org.freedesktop.DBus.Introspectable.Introspect
I see no error.<br> In 1. you are introspecting "org.trinitydesktop" and the answer tells you there is a service called "hardwarecontrol". There is no interface in the reply because you are not introspecting at interface level. You need to use ``` dbus-send --print-reply=literal --system --dest=org.trinitydesktop.hardwarecontrol /org/trinitydesktop/hardwarecontrol org.freedesktop.DBus.Introspectable.Introspect ``` if you want to introspect the interface provided by "org.trinitydesktop.hardwarecontrol" You can try these other example for further studies. ``` dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 /org/freedesktop/PolicyKit1 org.freedesktop.DBus.Introspectable.Introspect dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 /org/freedesktop org.freedesktop.DBus.Introspectable.Introspect ```
deloptes commented 7 months ago
Poster

Very good, so let us think about what dbusxml2qt3 should generatein the case

dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 /org/freedesktop/PolicyKit1 org.freedesktop.DBus.Introspectable.Introspect
   <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
                      "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.50.3 -->
<node>
  <node name="Authority"/>
</node>

I have no exact solution. The fact is that it does not work ATM:

$ dbusxml2qt3 polkit.xml
dbusxml2qt3: introspection data file 'polkit.xml' does not contain any valid interface descriptions

With the root node it is the same

$ dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 / org.freedesktop.DBus.Introspectable.Introspect
   <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
                      "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!-- GDBus 2.50.3 -->
<node>
  <node name="org"/>
</node>

Ideally dbusxml2qt3 should generate code that could be used to browse(go) to the next level in the path as implemented in org.trinitydesktop.hardwarecontrol and the examples given by you (PolicyKit1). In fact to get access to the interface dbusxml2qt3 generates a node class only if there is name attribute in the root. If I take the output from dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 /org/freedesktop/PolicyKit1/Authority org.freedesktop.DBus.Introspectable.Introspect, dbusxml2qt3 says:

dbusxml2qt3 -n a -N MaClass polkit1.xml
ClassGenerator: processing interface 'org.freedesktop.DBus.Properties'
ClassGenerator: processing interface 'org.freedesktop.DBus.Introspectable'
ClassGenerator: processing interface 'org.freedesktop.DBus.Peer'
ClassGenerator: processing interface 'org.freedesktop.PolicyKit1.Authority'

dbusxml2qt3: cannot generate node without class name.

There is a missing link

Very good, so let us think about what dbusxml2qt3 should generatein the case ``` dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 /org/freedesktop/PolicyKit1 org.freedesktop.DBus.Introspectable.Introspect <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <!-- GDBus 2.50.3 --> <node> <node name="Authority"/> </node> ``` I have no exact solution. The fact is that it does not work ATM: ``` $ dbusxml2qt3 polkit.xml dbusxml2qt3: introspection data file 'polkit.xml' does not contain any valid interface descriptions ``` With the root node it is the same ``` $ dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 / org.freedesktop.DBus.Introspectable.Introspect <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <!-- GDBus 2.50.3 --> <node> <node name="org"/> </node> ``` Ideally dbusxml2qt3 should generate code that could be used to browse(go) to the next level in the path as implemented in org.trinitydesktop.hardwarecontrol and the examples given by you (PolicyKit1). In fact to get access to the interface dbusxml2qt3 generates a node class only if there is name attribute in the root. If I take the output from `dbus-send --print-reply=literal --system --dest=org.freedesktop.PolicyKit1 /org/freedesktop/PolicyKit1/Authority org.freedesktop.DBus.Introspectable.Introspect`, dbusxml2qt3 says: ``` dbusxml2qt3 -n a -N MaClass polkit1.xml ClassGenerator: processing interface 'org.freedesktop.DBus.Properties' ClassGenerator: processing interface 'org.freedesktop.DBus.Introspectable' ClassGenerator: processing interface 'org.freedesktop.DBus.Peer' ClassGenerator: processing interface 'org.freedesktop.PolicyKit1.Authority' ``` **dbusxml2qt3: cannot generate node without class name.** There is a missing link
MicheleC commented 7 months ago
Owner

If you are at interface level, I assume from your comment that dbusxml2qt3 will generate a qt class that represent the binding to the respective dbus interface.
I am not sure what dbusxml2qt3 should generate in case we are at a higher level, but I guess that without the details of an interface there is no much to generate other than an empty class. Which is probably you get an error when you try to do that :wink:

I may take a look at the source code of this tool (which I didn’t even know before you pointed out, thanks) at a later time and perhaps understand more about it, but IMO it seems a tool to map a dbus interface into a TQt class, so that you can use a TQt object to make transparent calls to a dbus service. I don’t see much need to generate something at higher level, because it would be unusuable without the details of the interface.

If you are at interface level, I assume from your comment that dbusxml2qt3 will generate a qt class that represent the binding to the respective dbus interface.<br> I am not sure what dbusxml2qt3 should generate in case we are at a higher level, but I guess that without the details of an interface there is no much to generate other than an empty class. Which is probably you get an error when you try to do that :wink: I may take a look at the source code of this tool (which I didn't even know before you pointed out, thanks) at a later time and perhaps understand more about it, but IMO it seems a tool to map a dbus interface into a TQt class, so that you can use a TQt object to make transparent calls to a dbus service. I don't see much need to generate something at higher level, because it would be unusuable without the details of the interface.
deloptes commented 7 months ago
Poster

Hi, yes take your time if you like. We are not in hurry with this. I think the discussion is important for improving this part.

IMO at root node level dbusxml2qt3 should accept the missing name (it is legal according docs) I will investigate in the code and in the option to double check this.

Furthermore it should generate a node interface to access the embedded node, so that you can obtain the information and be able to navigate further down the path.

Thus the example

<node>
  <node name="org"/>
</node>

Should produce the root node class and a class for the org node. You can repeat the step with the org node etc. Preferably there should be an option to generate only the org node code and the code for the next node (i.e. trinitydesktop). So you would be able to access (Introspectable interface)

/org
    /trinitydesktop
                   /........

This problem is only related to the interface code generated by dbusxml2qt3. The proxy code is easy. I guess as KDE was not using dbus interfaces were not really required.

Hi, yes take your time if you like. We are not in hurry with this. I think the discussion is important for improving this part. IMO at root node level dbusxml2qt3 should accept the missing name (it is legal according docs) I will investigate in the code and in the option to double check this. Furthermore it should generate a node interface to access the embedded node, so that you can obtain the information and be able to navigate further down the path. Thus the example ``` <node> <node name="org"/> </node> ``` Should produce the root node class and a class for the org node. You can repeat the step with the org node etc. Preferably there should be an option to generate only the org node code and the code for the next node (i.e. trinitydesktop). So you would be able to access (Introspectable interface) ``` /org /trinitydesktop /........ ``` This problem is only related to the interface code generated by dbusxml2qt3. The proxy code is easy. I guess as KDE was not using dbus interfaces were not really required.
MicheleC commented 7 months ago
Owner

I don’t think what you are suggesting is doable in a reasonable way. At the time and on the computer you use dbusxml2qt3, you may have some service available on dbus. At a later stage those services may be different or not available. Even worst when you try on a different computer.

Just an example: org.freedesktop.login1 is available on my debian, but in slackware it is not available at all.

So if you want to use dbusxml2qt3 to generate the list of nodes from “org”, you may endup with something that works on some systems and not in other. I have probably explained this very badly, but I hope you get my point ;-)

I don't think what you are suggesting is doable in a reasonable way. At the time and on the computer you use dbusxml2qt3, you may have some service available on dbus. At a later stage those services may be different or not available. Even worst when you try on a different computer. Just an example: org.freedesktop.login1 is available on my debian, but in slackware it is not available at all. So if you want to use dbusxml2qt3 to generate the list of nodes from "org", you may endup with something that works on some systems and not in other. I have probably explained this very badly, but I hope you get my point ;-)
deloptes commented 7 months ago
Poster

Hi Michele, I also could not explain exactly what I mean, but a revelation came to me few days ago.

What dbusxml2qt3 is missing is the ability to create code for the child of type ‘node’, so that you can walk through the path. I started playing with it and it seem to be not that complicated to implement. The code needs to be modified to accept following use cases

Case 1. root element with interface and child node with optional Instrospection

<node>
  <interface>
        ...
  </interface>
  <node name="A"/>
</node>

name in root element can be omitted, if present should start with ‘/’, so if our root element is ‘org’, this is equivalent to:

<node name="/org">
  <interface>
        ...
  </interface>
  <node name="A"/>
</node>

Case 2. Child node with interface and child with optional Introspection

<node>
  <node name="A">
      <interface>
           ...
      </interface>
      <node name="B"/>
  </node
</node>

Case 3. root element with child with a child with interface

<node>
  <node name="A">
      <node name="B">
         <interface>
              ...
         </interface>
      </node>
  </node
</node>

or simply

<node name="/org/A/B">
   <interface>
        ...
   </interface>
</node>

I believe if you are able to tell dbusxml2qt3 at which level you want to generate the code and what is the context, it would work.

The missing part of ‘node’ should be however added in any case. And this was my point. ATM it would generate the node only at root level, but will ignore the child of type ‘node’.

I hope this makes it better understand the point

Hi Michele, I also could not explain exactly what I mean, but a revelation came to me few days ago. What dbusxml2qt3 is missing is the ability to create code for the child of type 'node', so that you can walk through the path. I started playing with it and it seem to be not that complicated to implement. The code needs to be modified to accept following use cases Case 1. root element with interface and child node with optional Instrospection ``` <node> <interface> ... </interface> <node name="A"/> </node> ``` name in root element can be omitted, if present should start with '/', so if our root element is 'org', this is equivalent to: ``` <node name="/org"> <interface> ... </interface> <node name="A"/> </node> ``` Case 2. Child node with interface and child with optional Introspection ``` <node> <node name="A"> <interface> ... </interface> <node name="B"/> </node </node> ``` Case 3. root element with child with a child with interface ``` <node> <node name="A"> <node name="B"> <interface> ... </interface> </node> </node </node> ``` or simply ``` <node name="/org/A/B"> <interface> ... </interface> </node> ``` I believe if you are able to tell dbusxml2qt3 at which level you want to generate the code and what is the context, it would work. The missing part of 'node' should be however added in any case. And this was my point. ATM it would generate the node only at root level, but will ignore the child of type 'node'. I hope this makes it better understand the point
MicheleC commented 7 months ago
Owner

Re “What dbusxml2qt3 is missing is the ability to create code for the child of type ‘node’”

Yes, in theory it could be done, but not sure what is the target you are trying to reach and if it is worth it. For example if you try to generate from “org”, you will end up with classes with all available services in your system. I don’t think this is what you wanted, is it? IMO, starting at service level (as it is now) is a good entry point, anything above that would simply be too broad scope. Just my two cents :smile:

Re "What dbusxml2qt3 is missing is the ability to create code for the child of type ‘node’" Yes, in theory it could be done, but not sure what is the target you are trying to reach and if it is worth it. For example if you try to generate from "org", you will end up with classes with all available services in your system. I don't think this is what you wanted, is it? IMO, starting at service level (as it is now) is a good entry point, anything above that would simply be too broad scope. Just my two cents :smile:
deloptes commented 7 months ago
Poster

I do not think it is correct how it works at the moment, because children from type ‘node’ are ignored and dbusxml2qt3 does not take into account the hierarchy. Thus it is not possible to produce

/org
    /trinitydesktop
                   /........

I do not want to generate everything from ‘/org’ and then from ‘trinitydesktop’. What I want is to be able to generate the code for this path automatically. To achieve this it should either be able to generate the code for the child of type ‘node’, or when I have the xml as returned i.e from hardwarecontrol and I tell dbusxml2qt3 that it is at /org/trinitydesktop/hardwarecontrol and dbusxml2qt3 should generate the code for the classes orgnode,trinitydesktopnode and hardwarecontrolnode, where the introspection and interface can be found. I think may be latter is easier to implement (it can use the path to produce the code for the two levels above hardwarecontrol. This will still not cover all the use cases, but is a good start. Once again it is related only to interfaces.

I do not think it is correct how it works at the moment, because children from type 'node' are ignored and dbusxml2qt3 does not take into account the hierarchy. Thus it is not possible to produce ``` /org /trinitydesktop /........ ``` I do not want to generate everything from '/org' and then from 'trinitydesktop'. What I want is to be able to generate the code for this path automatically. To achieve this it should either be able to generate the code for the child of type 'node', or when I have the xml as returned i.e from hardwarecontrol and I tell dbusxml2qt3 that it is at /org/trinitydesktop/hardwarecontrol and dbusxml2qt3 should generate the code for the classes orgnode,trinitydesktopnode and hardwarecontrolnode, where the introspection and interface can be found. I think may be latter is easier to implement (it can use the path to produce the code for the two levels above hardwarecontrol. This will still not cover all the use cases, but is a good start. Once again it is related only to interfaces.
MicheleC commented 7 months ago
Owner

I don’t want to discourage you from trying to implement it, but the way you are planning it out does not seem right. Either you generate a class for all the subnodes or you don’t do generation of subnodes at all.

Imagine you have 10 subnodes. If you generate a class for only some of the subchildren, then what happens when you need the other services? Think of org.freedekstop, which can have a lot of different services.

Anyhow as said, feel free to work on it and if you come up with something clean and that works, we can add it to the current code :smile:

I don't want to discourage you from trying to implement it, but the way you are planning it out does not seem right. Either you generate a class for all the subnodes or you don't do generation of subnodes at all. Imagine you have 10 subnodes. If you generate a class for only some of the subchildren, then what happens when you need the other services? Think of org.freedekstop, which can have a lot of different services. Anyhow as said, feel free to work on it and if you come up with something clean and that works, we can add it to the current code :smile:
deloptes commented 7 months ago
Poster

May be it is still not clear what I meant, while I understand what you mean, I want to generate the appropriate nodes for this service only: org.trinitydesktop.x where you have in tdelibs/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c following

    if(strcmp("/", path) == 0) {
        strncat(data, "  <node name=\"org\" />\n", size-strlen(data));
    }
    else if(strcmp("/org", path) == 0) {
        strncat(data, "  <node name=\"trinitydesktop\" />\n", size-strlen(data));
    }
    else if(strcmp("/org/trinitydesktop", path) == 0) {
        strncat(data, "  <node name=\"hardwarecontrol\" />\n", size-strlen(data));
    }

which would mean to have similar behavior in class generated by dbusxml2qt3

It would mean that in the node class generated you should ability to return introspection for the child nodes

    TQDomDocument doc;
    TQDomElement nodeElement = doc.createElement("node");
    TQDomElement childNodeElement1 = doc.createElement("node");
    childNodeElement1.setAttribute ( "name", "/org" ) 
    buildIntrospectionData(childNodeElement1);

    TQDomElement childNodeElement2 = doc.createElement("node");
    childNodeElement2.setAttribute ( "name", "trinitydesktop" ) 
    buildIntrospectionData(childNodeElement2);
    childNodeElement1.appendChild(childNodeElement2);
    nodeElement.appendChild(childNodeElement1);

    doc.appendChild(nodeElement);

It’s just an example … not sure exactly where and how but buildIntrospectionData should return, what is now returned by the example from tde_dbus_hardwarecontrol.c

Alternatively I could think of manually creating such class that can be used in such cases … or template.

May be it is still not clear what I meant, while I understand what you mean, I want to generate the appropriate nodes for this service only: org.trinitydesktop.x where you have in tdelibs/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c following ``` if(strcmp("/", path) == 0) { strncat(data, " <node name=\"org\" />\n", size-strlen(data)); } else if(strcmp("/org", path) == 0) { strncat(data, " <node name=\"trinitydesktop\" />\n", size-strlen(data)); } else if(strcmp("/org/trinitydesktop", path) == 0) { strncat(data, " <node name=\"hardwarecontrol\" />\n", size-strlen(data)); } ``` which would mean to have similar behavior in class generated by dbusxml2qt3 It would mean that in the node class generated you should ability to return introspection for the child nodes ``` TQDomDocument doc; TQDomElement nodeElement = doc.createElement("node"); TQDomElement childNodeElement1 = doc.createElement("node"); childNodeElement1.setAttribute ( "name", "/org" ) buildIntrospectionData(childNodeElement1); TQDomElement childNodeElement2 = doc.createElement("node"); childNodeElement2.setAttribute ( "name", "trinitydesktop" ) buildIntrospectionData(childNodeElement2); childNodeElement1.appendChild(childNodeElement2); nodeElement.appendChild(childNodeElement1); doc.appendChild(nodeElement); ``` It's just an example ... not sure exactly where and how but buildIntrospectionData should return, what is now returned by the example from tde_dbus_hardwarecontrol.c Alternatively I could think of manually creating such class that can be used in such cases ... or template.
MicheleC commented 7 months ago
Owner

I got what you mean. But for example running

buildIntrospectionData(childNodeElement1);

how do you tell the program to call the introspection for trinitydesktop and not freedesktop? and if we have multiple services, implemented into difference part of the code, how would they coexist?

IMO, you should consider the opposite approach. Get the xml code for the service you need. Then since you know the path of the service, you can create a function to build the remaining TQDomElement and child nodes and append the node with the service information in the inner part. This should be much easier and cleaner to implement.

I got what you mean. But for example running > buildIntrospectionData(childNodeElement1); how do you tell the program to call the introspection for trinitydesktop and not freedesktop? and if we have multiple services, implemented into difference part of the code, how would they coexist? IMO, you should consider the opposite approach. Get the xml code for the service you need. Then since you know the path of the service, you can create a function to build the remaining TQDomElement and child nodes and append the node with the service information in the inner part. This should be much easier and cleaner to implement.
deloptes commented 7 months ago
Poster

Thank you, indeed the last you mention is what I also mean. I have the XML of the service to be build so when I provide the path to dbusxml2qt3 it should generate the code for “the remaining TQDomElement and child nodes and append the node with the service information in the inner part”. This is exactly missing at the moment.

I admit that I did not have such clear understanding and was thinking, I need a class for each node, but you are right, it could be managed in the root node class, which is generated even now. When implementing one may decide which part of the code to use. Glad that we look at it now from the same angle. Thanks once again!

At the moment it is too busy here, but in Feb. it might be possible to do something. I found it pretty easy and fun generating and implementing dbus code this way.

Let’s see what the future will bring.

Thank you, indeed the last you mention is what I also mean. I have the XML of the service to be build so when I provide the path to dbusxml2qt3 it should generate the code for "the remaining TQDomElement and child nodes and append the node with the service information in the inner part". This is exactly missing at the moment. I admit that I did not have such clear understanding and was thinking, I need a class for each node, but you are right, it could be managed in the root node class, which is generated even now. When implementing one may decide which part of the code to use. Glad that we look at it now from the same angle. Thanks once again! At the moment it is too busy here, but in Feb. it might be possible to do something. I found it pretty easy and fun generating and implementing dbus code this way. Let's see what the future will bring.
deloptes commented 4 months ago
Poster

Michele, I did first PoC, but before changing more of the code in dbusxml2qt, I would like to sync with you, or whoever would like to help me avoid mistakes - not that I am afraid, but time is precious.

Attached the desired view and a code example.

Notes:

With the changes in issue/5/dbusxml2qt3, I can generate all the code except the dummy node. This dummy node I use to handle the hierarchy in the path. So if I could bring dbusxml2qt to generate it for me, I would only need to create the main.cpp and the implementation (testservice.cpp and header files) to be able to use any service, the way we discussed it. It means dbus made easy for TDE :)

I did modify main.cpp in my copy of dbusxml2qt to create dummy node class, but class and method generators need to be adjusted/extended as well, to create the suggested code. If you compare ServiceNode with DummyNode, you will see dummy is close variation of the former.

On the other hand dummy being dummy can be used in any context … so perhaps copy is the cheapest way and a howto is more worth investing time.

Let me know what you think.

Thanks in advance

Build:
git clone https://mirror.git.trinitydesktop.org/gitea/deloptes/dbus-1-tqt-example
cd dbus-1-tqt-example/4d
bash  ../build_4d.sh  
Run:
./tqdbusexample
Test:
dbus-send --print-reply --session --dest=org.example.Service / \
   org.freedesktop.DBus.Introspectable.Introspect
dbus-send --print-reply --session --dest=org.example.Service /org \
   org.freedesktop.DBus.Introspectable.Introspect
dbus-send --print-reply --session --dest=org.example.Service /org/example \
   org.freedesktop.DBus.Introspectable.Introspect
dbus-send --print-reply --session --dest=org.example.Service /org/example/service \
   org.freedesktop.DBus.Introspectable.Introspect

dbus-send --print-reply --session --dest=org.example.Service \
  /org/example/service  \
  org.example.Service.ListSorter array:string:"x","a","c","b"

Michele, I did first PoC, but before changing more of the code in dbusxml2qt, I would like to sync with you, or whoever would like to help me avoid mistakes - not that I am afraid, but time is precious. Attached the desired view and a code example. #####Notes:##### With the changes in issue/5/dbusxml2qt3, I can generate all the code except the dummy node. This dummy node I use to handle the hierarchy in the path. So if I could bring dbusxml2qt to generate it for me, I would only need to create the main.cpp and the implementation (testservice.cpp and header files) to be able to use any service, the way we discussed it. It means dbus made easy for TDE :) I did modify main.cpp in my copy of dbusxml2qt to create dummy node class, but class and method generators need to be adjusted/extended as well, to create the suggested code. If you compare ServiceNode with DummyNode, you will see dummy is close variation of the former. On the other hand dummy being dummy can be used in any context ... so perhaps copy is the cheapest way and a howto is more worth investing time. Let me know what you think. Thanks in advance #####Build:##### ``` git clone https://mirror.git.trinitydesktop.org/gitea/deloptes/dbus-1-tqt-example cd dbus-1-tqt-example/4d bash ../build_4d.sh ``` #####Run:##### ``` ./tqdbusexample ``` #####Test:##### ``` dbus-send --print-reply --session --dest=org.example.Service / \ org.freedesktop.DBus.Introspectable.Introspect dbus-send --print-reply --session --dest=org.example.Service /org \ org.freedesktop.DBus.Introspectable.Introspect dbus-send --print-reply --session --dest=org.example.Service /org/example \ org.freedesktop.DBus.Introspectable.Introspect dbus-send --print-reply --session --dest=org.example.Service /org/example/service \ org.freedesktop.DBus.Introspectable.Introspect dbus-send --print-reply --session --dest=org.example.Service \ /org/example/service \ org.example.Service.ListSorter array:string:"x","a","c","b" ```
deloptes commented 4 months ago
Poster
Note:

I had to create a repo for the code - please use https://mirror.git.trinitydesktop.org/gitea/deloptes/dbus-1-tqt-example as mentioned above

######Note:###### I had to create a repo for the code - please use https://mirror.git.trinitydesktop.org/gitea/deloptes/dbus-1-tqt-example as mentioned above
MicheleC commented 4 months ago
Owner

Hi Emanoil,

I had a look at the code and the PoC work has some good potential. I will need to make some time to test it out properly in the future, but at first sight it makes creating TDE dbus services very easy.

Regarding the dummy node, being generic we can make it a default in the code and make it available as part of the dbus-1-tqt library. Maybe with a more meaning name :smile:

Hi Emanoil, I had a look at the code and the PoC work has some good potential. I will need to make some time to test it out properly in the future, but at first sight it makes creating TDE dbus services very easy. Regarding the dummy node, being generic we can make it a default in the code and make it available as part of the dbus-1-tqt library. Maybe with a more meaning name :smile:
deloptes commented 4 months ago
Poster

I will add a new example - lets say “4e”, where one could create multilevel interface like when using object manager at root level

    <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
    "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
    <node>
        <interface name="org.freedesktop.DBus.Introspectable">
            <method name="Introspect">
                <arg name="xml" type="s" direction="out" />
            </method>
        </interface>
        <interface name="org.freedesktop.DBus.ObjectManager">
            <method name="GetManagedObjects">
                <arg name="objects" type="a{oa{sa{sv}}}" direction="out" />
            </method>
            <signal name="InterfacesAdded">
                <arg name="object" type="o" />
                <arg name="interfaces" type="a{sa{sv}}" />
            </signal>
            <signal name="InterfacesRemoved">
                <arg name="object" type="o" />
                <arg name="interfaces" type="as" />
            </signal>
        </interface>
    </node>

and the service from example “4d”

    <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
                          "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
    <node name="/org/example/service">
        <interface name="org.example.Service">
            <method name="ListSorter">
                <arg name="input" type="as" direction="in" />
                <arg name="output" type="as" direction="out" />
            </method>
        </interface>
    </node>

So we should see (be able to interact with)

/org.freedesktop.DBus.Introspectable
/org.freedesktop.DBus.ObjectManager
/org
    /example
            /service
                    /org.freedesktop.DBus.Introspectable
                    /org.example.Service

(more fitness for the brain) :)

I will add a new example - lets say "4e", where one could create multilevel interface like when using object manager at root level ``` <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node> <interface name="org.freedesktop.DBus.Introspectable"> <method name="Introspect"> <arg name="xml" type="s" direction="out" /> </method> </interface> <interface name="org.freedesktop.DBus.ObjectManager"> <method name="GetManagedObjects"> <arg name="objects" type="a{oa{sa{sv}}}" direction="out" /> </method> <signal name="InterfacesAdded"> <arg name="object" type="o" /> <arg name="interfaces" type="a{sa{sv}}" /> </signal> <signal name="InterfacesRemoved"> <arg name="object" type="o" /> <arg name="interfaces" type="as" /> </signal> </interface> </node> ``` and the service from example "4d" ``` <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node name="/org/example/service"> <interface name="org.example.Service"> <method name="ListSorter"> <arg name="input" type="as" direction="in" /> <arg name="output" type="as" direction="out" /> </method> </interface> </node> ``` So we should see (be able to interact with) ``` /org.freedesktop.DBus.Introspectable /org.freedesktop.DBus.ObjectManager /org /example /service /org.freedesktop.DBus.Introspectable /org.example.Service ``` (more fitness for the brain) :)
deloptes commented 4 months ago
Poster

Unfortunately I hit few bugs while doing so. One is related to how dbus-1-tqt treats the signature “a{oa{sa{sv}}}” as in <arg name="objects" type="a{oa{sa{sv}}}" direction="out" />.

I think I’ll file a bug if I have not done so and first look forward to solve it. Now I have to manually fix the generated objectmanagerinterface/proxy

Unfortunately I hit few bugs while doing so. One is related to how dbus-1-tqt treats the signature "a{oa{sa{sv}}}" as in `<arg name="objects" type="a{oa{sa{sv}}}" direction="out" />`. I think I'll file a bug if I have not done so and first look forward to solve it. Now I have to manually fix the generated objectmanagerinterface/proxy
MicheleC commented 4 months ago
Owner

No problem, take your time :smile:

No problem, take your time :smile:
deloptes commented 4 months ago
Poster

You may want to have a look at https://mirror.git.trinitydesktop.org/gitea/TDE/dbus-1-tqt/issues/7

and the proposed solution in https://mirror.git.trinitydesktop.org/gitea/TDE/dbus-1-tqt/pulls/8

I also updated the example accordingly (look at the logs). Now more or less it looks complete. What I am thinking of is adding an option and functionality like --child-node or --cn, so that you can pass the child node on the command line and do not need to edit the generated “rootnode.cpp”.

Let me know what you think.

Also perhaps a regression testing needs to be done for dbus-1-tqt/pulls/8, but I do not have any examples where objectPath is used except the ObjectManager.

I intend to test on all the interface definitions I collected with my bluez project and see if there are some issues.

You may want to have a look at https://mirror.git.trinitydesktop.org/gitea/TDE/dbus-1-tqt/issues/7 and the proposed solution in https://mirror.git.trinitydesktop.org/gitea/TDE/dbus-1-tqt/pulls/8 I also updated the example accordingly (look at the logs). Now more or less it looks complete. What I am thinking of is adding an option and functionality like --child-node or --cn, so that you can pass the child node on the command line and do not need to edit the generated "rootnode.cpp". Let me know what you think. Also perhaps a regression testing needs to be done for dbus-1-tqt/pulls/8, but I do not have any examples where objectPath is used except the ObjectManager. I intend to test on all the interface definitions I collected with my bluez project and see if there are some issues.
deloptes commented 4 months ago
Poster

solution and regression tested in https://mirror.git.trinitydesktop.org/gitea/TDE/dbus-1-tqt/pulls/8

After we close this, we can think of the proposed option as wish list item. I would rather prefer dummynode or whatever name we choose for it to be actually generated for convenience. Possibly we can call it emptynode.

solution and regression tested in https://mirror.git.trinitydesktop.org/gitea/TDE/dbus-1-tqt/pulls/8 After we close this, we can think of the proposed option as wish list item. I would rather prefer dummynode or whatever name we choose for it to be actually generated for convenience. Possibly we can call it emptynode.
MicheleC commented 4 months ago
Owner

Hi Emanoil, thanks for the good work. As I mentioned in a comment above, regarding the dummy node I also think it would be good to have it generated automatically. For the name, I suggest we call it “rootnode”.

Hi Emanoil, thanks for the good work. As I mentioned in a comment above, regarding the dummy node I also think it would be good to have it generated automatically. For the name, I suggest we call it "rootnode".
deloptes commented 4 months ago
Poster

Hi Michele, to my understanding root node is the one at top level, but this code can be used as base for any node at any level. I would keep the name “rootnode” only for the one at top level (see example 4e). What about “basenode”, “basicnode”, “levelnode”, “treenode”, “leavenode” or these starting with “dbus” -> “dbustreenode”.

Hi Michele, to my understanding root node is the one at top level, but this code can be used as base for any node at any level. I would keep the name "rootnode" only for the one at top level (see example 4e). What about "basenode", "basicnode", "levelnode", "treenode", "leavenode" or these starting with "dbus" -> "dbustreenode".
deloptes commented 4 months ago
Poster

Another possible name would be “anynode” or “dbusanynode” as the word any has appropriate semantic and would cover the case when you use this also for rootnode (see example 4d). I would suggest “anynode”.

Another possible name would be "anynode" or "dbusanynode" as the word any has appropriate semantic and would cover the case when you use this also for rootnode (see example 4d). I would suggest "anynode".
MicheleC commented 4 months ago
Owner

Slavek and I were thinking about “dbusBaseNode”. How does it sound?

Slavek and I were thinking about "dbusBaseNode". How does it sound?
deloptes commented 4 months ago
Poster

sounds nice to me I am not so picky

sounds nice to me I am not so picky
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
Cancel
Save
There is no content yet.