godbus/dbus

Export for iwd agent

Closed this issue · 1 comments

Hi,

I'm writing a client for iwd and got stuck with registering a "provide password to connect to network" - handler.

As I understand, one has to RegisterAgent with a path where iwd can then call the handler to get the passphrase for connecting to an access point.

type IAgent struct{}

var agent IAgent

func (a IAgent) RequestPassphrase(net dbus.ObjectPath) string {
	log.Println("------------ RequestPassphrase")
	return "bla"
}

func registerAgent() {
	conn, err := dbus.ConnectSystemBus()
	if err != nil {
		log.Fatalln("can't connect to system bus")
	}
	defer conn.Close()

	path := dbus.ObjectPath("/test/agent/11")

	// --- export ---
	err = conn.ExportAll(agent, path, "net.connman.iwd.Agent")
	if err != nil {
		log.Println("export err:", err)
	}

	// --- register agent ---
	manager := conn.Object("net.connman.iwd", "/net/connman/iwd")
	call := manager.Call("net.connman.iwd.AgentManager.RegisterAgent", 0, path)
	if call.Err != nil {
		log.Println("call error:", call.Err)
	}
}

On initiating a "connect to network", I expect RequestPassword to be called by iwd. Instead, I get No Agent registered, which, by looking at the iwd code, means it couldn't find the method on the dbus.

If I run this python code in another terminal, it triggers in the same scenario (when I try to connect to a network in my Go-application)

class Agent(dbus.service.Object):
    passphrase = None

    @dbus.service.method("net.connman.iwd.Agent", in_signature="o", out_signature="s")
    def RequestPassphrase(self, path):
        print(f"RequestPassphrase {path}")
        passphrase = input("Answer: ")
        print(f"returning {passphrase}")
        return passphrase

if __name__ == "__main__":

    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    bus = dbus.SystemBus()
    manager = dbus.Interface(
        bus.get_object("net.connman.iwd", "/net/connman/iwd"),
        "net.connman.iwd.AgentManager",
    )

    path = "/test/agent/11"  # + str(randrange(100))
    object = Agent(bus, path)

    try:
        manager.RegisterAgent(path)
    except:
        print("Cannot register iwd agent.")

    mainloop = GLib.MainLoop()
    mainloop.run()

Original python source: https://git.kernel.org/pub/scm/network/wireless/iwd.git/tree/test/simple-agent
Iwd agent dbus api: https://git.kernel.org/pub/scm/network/wireless/iwd.git/tree/doc/agent-api.txt

This is kind of different from other godbus use-cases I've seen (examples, other issues here, ...), because I'm exporting to... the namespace of another process... Perhaps I don't really understand the mechanism...

Any tips would be appreciated.

My code was almost ok; I just have to keep the connection open.
Sorry if I wasted anyone's time.