Traveling heavily recently, I've become fatigued from typing all the WiFi passphrases. My phone can happily connect via a QR code. Why does my laptop required so much typing, I asked. So I proposed a simple project.
Researching how I might use my web-cam to connect to WiFi networks, I came across the Network Manager and Rust's Zbus article on rbs.io. I use NewtworkManager
and I enjoy working with rust
. I know next to nothing about DBus, but I thought some knowledge of hacking Linux networks couldn't do me any harm. Besides I had some free time.
The above article set me on the right path. The zbus
documentation is still a little obscure in some salient details, however. Hopefully this post will help fill those in. The finished code is hosted in the scampi repo.
I first needed to generate a settings.rs
with zbus-xmlgen
as described in the above article. It is straightforward to create a connection by building the nested structures of HashMap
s also described there. While that solution works, it is tedious, unsightly and doesn't make the most of rust's type system. Finding the issue for using DeserializeStruct
with nested structs closed, I hoped there might now be a more ergonomic way forward.
With the help of the zbus book I managed to piece together a solution that feels a little more rust-like. Of course there are many pieces to the puzzle. You need serde and the zvariant::Type macro. But all that is gleaned fairly easily from the documentation, I think. The more salient discovery was that zbus allows declaring DBbus signatures on your types. This is done via a macro, like so:
#[zvariant(signature = "a{sa{sv}}")]`
struct MyType{..}
Declaring the correct signature(a{sa{sv}}
) on the struct passed to NetworkManager
's Settings.add_connection()
allowed it to navigate Dbus
's type system. Its children don't have any children of their own, so SerializedDict
and DeserializeDict
works fine on them.
For a more complete example you can have a look at the code.
I believe I could go further and replace some fields defined as String
with more appropriate types, but it's one more thing to learn and I think this is good enough for now.
Originally published in my blog.
Top comments (0)