Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot seem to get Export to work. #184

Open
KBassford opened this issue Nov 19, 2019 · 7 comments
Open

Cannot seem to get Export to work. #184

KBassford opened this issue Nov 19, 2019 · 7 comments

Comments

@KBassford
Copy link

KBassford commented Nov 19, 2019

Hi Folks,

I hate to do this again, but I can't seem to get the export function to work (outside of the "Foo" function under Server.go).

Here's what I have ...
Creates a structure to extend the Dbus connection with out interface and path ...

type dbusobj struct {
	Conn  *dbus.Conn
	Iface string
	Path  dbus.ObjectPath
}

Created a function to populate it ...

func newDbusObject(conn *dbus.Conn, iface string, path dbus.ObjectPath) dbusobj {
	pdbo := new(dbusobj)
	pdbo.Conn = conn
	pdbo.Iface = iface
	pdbo.Path = path
	return *pdbo
}

Gave it a means of exporting to the bus ...

func (dbo dbusobj) addSimpleMethod(method interface{}) error {
	err := dbo.Conn.Export(method, dbo.Path, dbo.Iface)
	if err != nil {
		return err
	}
	node := &introspect.Node{}
	node.Name = dbo.Iface
	iface := &introspect.Interface{}
	iface.Name = dbo.Iface
	mts := introspect.Methods(method)
	iface.Methods = mts
	node.Interfaces = append(node.Interfaces, *iface)
	dbusXMLStr := introspect.NewIntrospectable(node)
	fmt.Println("Method debug ...")  	// Debug
	printXML(fmt.Sprint(dbusXMLStr))  // Debug
	err = dbo.Conn.Export(dbusXMLStr, dbo.Path, "org.freedesktop.DBus.Introspectable")
	if err != nil {
		return err
	}
	return nil
}

(output of the debug ...)

Method debug ...
	<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
	 "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
	<node name="org.openxt.ndvm.wifi">
	  <interface name="org.openxt.ndvm.wifi">
	    <method name="Ping">
	      <arg type="s" direction="out">
	        </arg>
	      </method>
	    </interface>
	  <interface name="org.freedesktop.DBus.Introspectable">
	    <method name="Introspect">
	      <arg name="out" type="s" direction="out">
	        </arg>
	      </method>
	    </interface>
	  </node>

Implemented by (much in the same way as the "Foo" example) ....

	dbc := newDbusObject(conn, dbusiface, dbuspath)
	p := ping("Ping called!")
	err = dbc.addSimpleMethod(p)

Yet it never appears in the introspection, nor does it work.

<node>
	<interface name="org.openxt.ndvm.wifi">
		<method name="Foo">
			<arg direction="out" type="s"/>
		</method>
	</interface>
	<interface name="org.freedesktop.DBus.Introspectable">
		<method name="Introspect">
			<arg name="out" direction="out" type="s"/>
		</method>
	</interface>
</node>"

a. What am I doing wrong?
b. Is there a mailing list or some other means of obtaining help on godbus?
(Yes I posted on go-nuts, no reply so far.)
I hate to open issues just to ask questions.

@KBassford
Copy link
Author

KBassford commented Nov 20, 2019

Hi Folks,
Had some inspiration last night so I tried an experiment this morning. I removed the "Foo" routine since it was the last added and low and behold the "Ping" routine worked. So it would appear that each call to conn.Export() overwrites the previous call (it is not cumulative as I had expected). I presume this means that I have to use conn.ExportSubtree() or conn.ExportSubtreeWithMap() in order to map more than one function.
So the good news is I have a bit more understanding of how this works, the bad news is I have no example(s) to work from.

BTW: tried ...

	dbmethods = append(dbmethods, introspect.Methods(method)[0])
	// mts := introspect.Methods(method)
	iface.Methods = dbmethods

inside my addSimpleMethod() function. While it modifies the introspection table, it fails to retain all but the last exported function.

@jsouthworth
Copy link
Member

Yep it looks like we are lacking in official examples for this. I personally replace the default handler that works with export so I don't use it...

There are some examples in the test code here: https://github.com/godbus/dbus/blob/master/export_test.go
and here is the only official example (but I assume you've seen this):
https://github.com/godbus/dbus/blob/master/_examples/server.go

Hope this helps a bit.

@KBassford
Copy link
Author

KBassford commented Nov 20, 2019

I've been perusing export_test for answers. The server example is what I initially followed (and is grossly misleading in the way it adds "Foo"). Speaking of which, how does one make a reference to a method? (i.e. map[string]interface{} for use with ExportMethodTable()?) I tried "p := ping("Pong")", followed by "Table["Ping"] = p", but this does not seem to work.

I'm open to any suggestions on how to set up a server that can receive multiple methods.

@KBassford
Copy link
Author

KBassford commented Nov 20, 2019

Well, now I've inverted what I had. Used ...

err := dbo.Conn.ExportWithMap(server{}, methNames, dbo.Path, dbo.Iface)

re: export_test.go, func TestExportWithMap()
Now I have multiple functions I can address (in lowercase) with no introspection!
Why couldn't be easy to do both!

@KBassford
Copy link
Author

Found that in order for ExportWithMap() to work, all functions must return *dbus.Error"
Looks like issue #55 is still alive and well.

Example:

func (server) Foo() (string, *dbus.Error) {
	return "Bar!", nil
}

@KBassford
Copy link
Author

Here's what I have currently ...

func (dbo dbusobj) registerServerMethods() error {
	// Register all methods associated with out server.
	var methods []reflect.Method
	serverType := reflect.TypeOf(server{})
	for i := 0; i < serverType.NumMethod(); i++ {
		servmethod := serverType.Method(i)
		methods = append(methods, servmethod)
		fmt.Println("Server Method:", servmethod.Name)
		fmt.Println("Server Method:", servmethod)
		methNames[servmethod.Name] = strings.ToLower(servmethod.Name)
		err := dbo.Conn.ExportWithMap(server{}, methNames, dbo.Path, dbo.Iface)
		if err != nil {
			return err
		}
		// Try to introspect.
		node := &introspect.Node{}
		node.Name = dbo.Iface
		iface := &introspect.Interface{}
		iface.Name = dbo.Iface
		dbmethods = append(dbmethods, introspect.Methods(servmethod)[0])
		iface.Methods = dbmethods
		node.Interfaces = append(node.Interfaces, *iface)
		dbusXMLinsp := introspect.NewIntrospectable(node)
		fmt.Println("Method debug ...")   // Debug
		printXML(fmt.Sprint(dbusXMLinsp)) // Debug
		err = dbo.Conn.Export(dbusXMLinsp, dbo.Path, "org.freedesktop.DBus.Introspectable")
		if err != nil {
			return err
		}

	}
	return nil
}

This works perfectly for registering all the methods on the server, but once you get below "Try to introspect" line, things don't go so well. Is there a format that that I'm overlooking that would work for the dbus.Methods() call?

@krthy1728
Copy link

Does anybody know if a solution has been found to this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants