Home > Blockchain >  Exporting dbus interface in go seems not to work as expected
Exporting dbus interface in go seems not to work as expected

Time:02-03

First of all Hello to everybody who read this,

I have currently a Problem while implementing a Go dbus interface. The Problem is that I am defining an interface with to methods "Ping" and "Zing" this seems to work. But when I export them and want to call them (via d-feet) only the last exported Method work. So for my Opionion the Export funtion only export one method at the time and overwrites the previous. I also tried to to it with ExportAll, but this also dont work. If anybody has an idea or just a hint for me, it would be great!

Below you see my source code:

package main
                                                                                                                                                                  
import (
        "fmt"
        "os"
        "github.com/godbus/dbus"
        "github.com/godbus/dbus/introspect"
)
type ping string

func (p ping) Ping() (string, *dbus.Error) {
        fmt.Println(p)
        return string(p), nil
}

type zing string

func (z zing) Zing() (string, *dbus.Error) {
        fmt.Println(z)
        return string(z), nil
}

func main() {
        conn, err := dbus.ConnectSystemBus()
        if err != nil {
                panic(err)
        }
        replyP, errP := conn.RequestName("test.Ping", dbus.NameFlagDoNotQueue)
        if errP != nil {
                panic(errP)
        }
        if replyP != dbus.RequestNameReplyPrimaryOwner {
                fmt.Fprintln(os.Stderr, "name already taken")
                os.Exit(1)
        }

        z := zing("Zong")
        p := ping("Pong")
        var intro = &introspect.Node{
                //Name: "/",
                Interfaces: []introspect.Interface{
                        introspect.IntrospectData,
                        {
                                Name:    "test.test",
                                Methods: []introspect.Method{
                                        {
                                                Name: "Zing",
                                                Args: []introspect.Arg{
                                                        {"out", "s", "out"},
                                                },
                                        },
                                        {
                                                Name: "Ping",
                                                Args: []introspect.Arg{
                                                        {"out", "s", "out"},
                                                },
                                        },
                                },
                        },
                },
        }

        conn.Export(z, "/", "test.test")
        conn.Export(p, "/", "test.test")

        conn.Export(introspect.NewIntrospectable(intro), "/", "org.freedesktop.DBus.Introspectable")

        fmt.Printf("Listening on %s / %s ...\n", "test.test", "/...")
        select {}
}

CodePudding user response:

Today after reading a bunch of Documentation and Source Code, I finally got my Problem solved. The key is, that when you have a dbus Interface with two or more methods, you MUST define ONE new Datatype, that gets Exported afterwards. For this I create a new Type type ping struct{}. It is basicly an empty struct, so it can handle everything. Than the new Type take place at the implementation of the functions/method that gets calls via dbus. Finally you have to Initalize and Export it to the dbus p := ping{} and conn.Export(p, "/", "test.test") . I hope that I can help anybody with that example. If you have any Questions about this, just leave a Comment.

package main

import (
        "fmt"
        "os"
        "github.com/godbus/dbus"
        "github.com/godbus/dbus/introspect"
)

type ping struct{}

func (z ping) Ping(s string, i uint8) (*dbus.Error) {
        fmt.Println(s, i)
        return nil
}

func (p ping) Zing(t string) (*dbus.Error) {
        fmt.Println(t)
        return nil
}

func main() {
        conn, err := dbus.ConnectSystemBus()
        if err != nil {
                panic(err)
        }
        replyP, errP := conn.RequestName("test.Ping", dbus.NameFlagDoNotQueue)
        if errP != nil {
                panic(errP)
        }
        if replyP != dbus.RequestNameReplyPrimaryOwner {
                fmt.Fprintln(os.Stderr, "name already taken")
                os.Exit(1)
        }

        p := ping{}
        var intro = &introspect.Node{
                Name: "/",
                Interfaces: []introspect.Interface{
                        introspect.IntrospectData,
                        {
                                Name:    "test.test",
                                Methods: []introspect.Method{
                                        {
                                                Name: "Zing",
                                                Args: []introspect.Arg{
                                                        {"str", "s", "in"},
                                                },
                                        },
                                        {
                                                Name: "Ping",
                                                Args: []introspect.Arg{
                                                        {"str", "s", "in"},
                                                        {"int", "y", "in"},
                                                },
                                        },
                                },
                        },
                },
        }

        conn.Export(p, "/", "test.test")
        conn.Export(introspect.NewIntrospectable(intro), "/", "org.freedesktop.DBus.Introspectable")

        fmt.Printf("Listening on %s / %s \n", "test.test", "/...")
        select {}
}
  •  Tags:  
  • Related