Closed hamid-rostami closed 4 years ago
This is strange, the output signature looks like it can be either 'i' or 's'?
<method name="New">
<arg type="s" direction="in"/>
<arg type="i" direction="out"/>
<arg type="s" direction="out"/>
</method>
It's been a while since I worked with D-Bus introspect xml, I'm not sure what that means. Looking it up now.
That is a legitimate way to define multiple output arguments, but it isn't supported by the proxy. It only supports a single return type.
In your mocked test that worked what did the signature look like?
There is a chance that if you change line 180 of proxy.py: https://github.com/ccxtechnologies/adbus/blob/f976d5046c7305db6f00188815c909e737f2f1b2/adbus/client/proxy.py#L180
To:
self.return_signature += x.attrib['type']
it may work.
It'll be easier for you to test since you have all of your tooling setup.
Hi @charleseidsness, thanks for your response.
You're right, output signature of mock-up is different from main program. Return type of mock-up:
‣ Type=method_return Endian=l Flags=1 Version=1 Priority=0 Cookie=4 ReplyCookie=3
Sender=:1.169 Destination=:1.172
UniqueName=:1.169
MESSAGE "(is)" {
STRUCT "is" {
INT32 10;
STRING "success";
};
};
Return type of main program:
‣ Type=method_return Endian=l Flags=1 Version=1 Priority=0 Cookie=47 ReplyCookie=3
Sender=:1.111 Destination=:1.147
UniqueName=:1.111
MESSAGE "is" {
INT32 6;
STRING "";
};
About changing in proxy.py
source line 180
. The result is no exception occurs anymore, but still just int
part returned from proxy.
If I should test something else, I'll be appreciate if you tell me.
D-Bus supports multiple in and out values for method calls. The multiple ins map nicely to multiple arguments in Python, but there isn't a straight-forward equivalent to multiple outs.
We could convert it to a tuple if there are multiple outs, it may make sense with the Python unpacking syntax.
I don't have an easy way to test it, but it may be as simple as fudging the return signature into a struct. You'd have to count how many out definitions there are if you have more than 1 out enclose it in "()".
Something like this:
self.arg_signatures = []
self.return_signature = ''
num_outs = 0
for x in etree.iter():
if x.tag == 'method':
self.name = x.attrib['name']
if x.tag == 'arg':
if x.attrib['direction'] == 'out':
self.return_signature += x.attrib['type']
num_outs += 1
elif x.attrib['direction'] == 'in':
self.arg_signatures.append(x.attrib['type'])
if num_outs > 1:
self.return_signature = "(" + self.return_signature + ")"
Nice idea, but unfortunately didn't work.
The reason of failure, I guess, is that the program is asking for (is)
, and there's no such a thing.
Here is occurred exception:
File "client.py", line 18, in <module>
asyncio.run(main())
File "/usr/local/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/local/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "client.py", line 15, in main
ret = await proxy.New("body")
File "/usr/local/lib/python3.7/site-packages/adbus/client/proxy.py", line 202, in __call__
timeout_ms=self.timeout_ms
File "/usr/local/lib/python3.7/site-packages/adbus/client/call.py", line 48, in call
raise call.response
File "adbus/sdbus/call.pyx", line 13, in adbus.sdbus.call_callback
File "adbus/sdbus/message.pyx", line 221, in adbus.sdbus.Message.read
File "adbus/sdbus/message.pyx", line 170, in adbus.sdbus.Message._read_struct
adbus.sdbus.SdbusError: Failed to enter structure b'is'
Thanks for trying.
I'll have to add this as a new feature, it may be a few days before I have some time to look at it.
I hope you get free time soon, feel free to ask me if I can help.
I created a branch with a few updates for this new feature. I don't have time to test it (or even build it right now) but it should get things started. If you get a chance to test it that would be a big help.
Great work @charleseidsness, Problem fixed, now it's working for both services (mock-up and my C program) Do I need to provide log or something ?
That's great, I'll issue a PR.
I have a dbus server with specific method with name
New
. Its Output signature is"is"
. When I call it usingbusctl
, there is no error. But when I usingadbus
, my client program can't grabstring
part of output and below exception occurs. So I can't using proxy for client and have to useadbus.client
by assign"i"
toresponse_signature
to drop"s"
part.Here is my test client with
adbus
:Output of
busctl
in monitor mode:Another point is, I implemented a mock-up server using
adbus
with same input/output signature, the client (written usingadbus
) runs successfully and no exception occurs. (My main server written inC
usingsd-bus
library)This is my mock-up server program: