Help needed with OBus

For a fun project (implementing a status program for i3bar, don’t laugh! :sweat_smile:) I need to interact with several resources, i.e. Network Manager, UPower and UDisks2.

A quick search pointed me to OBus, which seems to have everything I need and much more.

The problem is that I rapidly got lost into the impressively vast (and undocumented…) API and the few examples are not of great help, maybe because React is heavily present and I never used it.

Where should I start from for listening to “changes” in the active connections? I need something like a “big picture” to understand the various modules present in the library.

1 Like

@Freyr666 might help you here as the project developer.

For example OBus_signal has a make function and it’s obviously used to create a (React style?) signal. The arguments are an 'a OBus_member.Signal.t and a OBus_proxy.t. What is the difference between OBus_signal.t and OBus_member.Signal.t? And what is a “proxy”?

Then make_any seems very similar to make but a OBus_peer.t is its second argument… and it creates an (OBus_proxy.t * 'a) t.

I’m confused…

Yeah, it’s complicated because D-Bus is complex.

Proxy and peer are D-Bus entities. You can get yourself familiar with them in the d-bus tutorial.

As for how to use a d-bus object:

let main () =
   (* Create a bus *)
   let bus = OBus_bus.system () in
   (* Create a proxy for your object *)
   let proxy = OBus_proxy.make ~peer:(...) ~path:["org"; "path"; "to"; "object"] in
   (* Call methods via OBus_method *)
   let _ = OBus_method.call m_MethodName proxy argument
   (* Get or set the property values via OBus_property *)
   let property = OBus_property.make p_PropName proxy in
   let _ = OBus_property.get property in
   (* Attach callbacks to signalls using OBus_signal *)
   let signal = OBus_signal.make s_SignalName proxy in
   OBus_signal.connect signal >>= fun react_signal ->
   (* here you have a React signal which you can attach to *)

All you need is to generate OCaml interface out of D-Bus’s XML description using obus-gen-interface, it’ll generate an ml file representing D-Bus object’s interface and containing fields lime m_MethodName s_SignalName p_PropertyName for each method, property, signal etc.

Then you can call these using interfaces from this set of modules. These contains comments, you mostly need only OBus_method, OBus_signal and OBus_property.

What is the difference between OBus_signal.t and OBus_member.Signal.t ?

The former is the type representing signal you can attach to and work with, the latter represents a member of the D-Bus object’s interface encapsulating information needed to work with the signal (address, arguments’ types etc).

All the OBus_member types are representing various members of object’s interface: methods, signals, properties. You work with these members using corresponding modules from protocol. I.e. you use OBus_method module to would with a field of type OBus_member.Method.t, or OBus_signal for OBus_member.Signal.t.

Then make_any seems very similar to make but a OBus_peer.t is its second argument… and it creates an (OBus_proxy.t * 'a) t .

Proxy represents an object. Peer represents an application, which can have various objects. OBus_signal.make_any create a signal not for an object, but for all objects of the Peer. Signal returns then not only a value, but also an object which signaled it.

2 Likes

First: thanks for the detailed reply. I’m going to read it very carefully.

Meanwhile I was reading the source code when I realized that it is actually well documented. But the HTML produced by odig had no comments at all, this is why I was so confused.

I just submitted a very small pull request to create the complete documentation.

@Freyr666 the D-Bus tutorial is definitely a “must read”, thanks again.

I’m a little bit surprised by this. I just tried on my machine (obus.1.2.2, odoc.1.4.2 and odig.0.0.4) and there’s no less documentation that can be found in the doc strings.

These incantations should not be needed. AFAIK this will generate the HTML documentation “on the side” but it shouldn’t be that different from what odig generate: obus installs its cmti files so odig can do its job.

Could you please indicate what the problem is in more details ?

I cannot reproduce the problem :neutral_face:

Forget the noise, please.

1 Like

Just to conclude the thread, thanks to @Freyr666 I was able to read the info I need from Network Manager.

OBus is actually straightforward to use. For the future reader: you must have the fundamentals of D-Bus before using OBus and the tutorial suggested by @Freyr666 is enough.

For @dbuenzli: I tried to reproduce the odig problem, rebuilding the switch from scratch on 2 different machines without success. It’s definitively “not an issue”.

Maybe it would be worthwhile pointing to the dbus tutorial in the obus readme?

1 Like

Yeah, I think so. Maybe also add a simple tutorial as well.