How to specify composite types in signal handlers
I’m writing a signal handler for signal-cli’s D-Bus service; the MessageReceived signal has two arrays in its type signature ("x" "s" "ay" "s" "as"). How should I specify a signal handler for that signal? Here’s what I’ve got so far:
(dbus:define-dbus-object signal-service (:path "/org/asamk/Signal"))
(dbus:define-dbus-signal-handler (signal-service message-received) ((timestamp :int64) (source :string) (group-id (:array :byte)) (message :string) (attachments (:array :string)))
(:interface "org.asamk.Signal")
(with-open-file (log #P"/tmp/messages" :if-exists :append :direction :output :if-does-not-exist :create)
(format log "~&~a ~a ~a ~a ~a~%" timestamp source group-id message attachments)))
I did read the source and noticed that DEFINE-DBUS-SIGNAL-HANDLER uses SECOND on the parameters, so it looks like I oughtn’t use e.g (group-id :array :byte). I also looked through all the previous issues & in the examples directory for hints.
The example above has no effect, not even a SLIME debugger. I’ve also tried the name on-message-received.
The dbus:sigexp function can be used to translate from string representation to list representation:
CL-USER> (dbus:sigexp "xsaysas")
(:INT64 :STRING (:ARRAY :BYTE) :STRING (:ARRAY :STRING))
So it should be (group-id (:array :byte)).
There is another issue, the third point noted by loke in [0]. Since I've not used this library in some time, I've not fixed it. Patches are welcome though...
EDIT I notice, however, that you did set the path to the sender's. Did you add a match rule [1] so that you can receive broadcasted signals?
[0] http://irclog.tymoon.eu/freenode/%23lisp?around=1479361159#1479361159 [1] https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
I notice, however, that you did set the path to the sender's.
Hmmm, I was simply copying the publish example. Should it have looked like this instead?
(dbus:define-dbus-object signal-service (:path "/com/example/Signal"))
(dbus:define-dbus-signal-handler (signal-service message-received) ((timestamp :int64) (source :string) (group-id (:array :byte)) (message :string) (attachments (:array :string)))
(:interface "org.asamk.Signal")
(with-open-file (log #P"/tmp/messages" :if-exists :append :direction :output :if-does-not-exist :create)
(format log "~&~a ~a ~a ~a ~a~%" timestamp source group-id message attachments)))
(handler-case
(dbus:with-open-bus (bus (dbus:session-server-addresses))
(dbus:add-match bus :type :signal :interface "org.asamk.Signal")
(format t "Bus connection name: ~A~%" (dbus:bus-name bus))
(dbus:publish-objects bus))
(end-of-file ()
:disconnected-by-bus))
No, the path was OK. Does it not work?
You can trace dbus:receive-message to see whether messages are received.
You can also try sending a signal using the command line utility dbus-send.
I note that in their example they use the system bus, not the session bus.