FW: Main event loop in networkmanager.



________________________________________
From: Anders Gnistrup
Sent: Wednesday, August 03, 2011 3:12 PM
To: Andrew Bird (Sphere Systems)
Subject: RE: Main event loop in networkmanager.

Thanks Andrew

Hurra, it did solve my problems. I did had to make some minor changes to my code but is does seems to work.

I have done some testing and also solved the problem in some skeleton code.
Other people might be interrested in the solution, how to make a XML proxy interface for dbus.

from twisted.internet import protocol, reactor, defer, threads
from twisted.protocols import basic
from twisted.web import resource, server, xmlrpc
from twisted.application import internet, service
from twisted.python import log

import dbus
from dbus.mainloop.glib import DBusGMainLoop

NM_SERVICE = 'org.freedesktop.NetworkManager'
NM_OBJPATH = '/org/freedesktop/NetworkManager'
NM_INTFACE = NM_SERVICE

loop = DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus(mainloop=loop)

obj = bus.get_object(NM_SERVICE, NM_OBJPATH)


class NetcfgService():
    def xmlResource(self):
        """ Description : returns the XML resource interface to be published using
                          a listen protocol on a TCP connection. """
        x = NetcfgXMLProtocol()

        obj.GetDevices(dbus_interface=NM_INTFACE,
                       reply_handler=self.method_cb,
                       error_handler=log.err)

        obj.connect_to_signal('DeviceAdded', self.signal_cb,
                                dbus_interface=NM_INTFACE)

        obj.connect_to_signal('StateChanged', self.signal_cb,
                                dbus_interface=NM_INTFACE)

        return x;

    def method_cb(self, arg):
        print "method returned %s" % str(arg)

    def signal_cb(self, arg):
        print "signal fired with %s" % str(arg)

class NetcfgXMLProtocol(xmlrpc.XMLRPC):
    """ Description: Helper class for NetCfgService.
        The echo service is used for testing and should replace the dummy routine in
        xmlResource. """

    def xmlrpc_fault(self):
        raise xmlrpc.Fault(123, "The fault procedure is faulty.")

    def xmlrpc_version(self):
        """ Return the current version of the interface. """
        return "0.1"

    def xmlrpc_echo(self,x):
        """ Debug handling to make sure that interface is up and running.
            the received string is sent back (echoed) """
        return x

# Run this as root. If not, networkmanager will fail to activate connections.
application = service.Application('leardal ', uid=0, gid=0)
r = NetcfgService()
serviceCollection = service.IServiceCollection(application)
internet.TCPServer(8000, server.Site(r.xmlResource())).setServiceParent(serviceCollection)

Ps. If someone have a some nice enhancement don't keep quiet.

Regards Anders



________________________________________
From: Andrew Bird (Sphere Systems) [ajb spheresystems co uk]
Sent: Wednesday, August 03, 2011 11:02 AM
To: Anders Gnistrup
Cc: networkmanager-list gnome org
Subject: Re: Main event loop in networkmanager.

On Wednesday 03 August 2011, Anders Gnistrup wrote:
> Hi
>
> FIrst post to this maillist.
>
> My problem is that I need to receive signal from the networkmanager.
> This is done using connect_to_signal and it seems quite easy.
> But when testing I get the error message -> create a glib event loop.
> And thats My problem. I already have a loop.
>
> The short description of my application is a interface able to configure
> some wireless network interfaces from a remote host using a XMLrpc from
> twisted. (There is no screen on target platform)
>
> the application loop is a XMLrpc interface (reactor), where several rpc is
> available. Some of these graps information from the networkmanager dbus
> interface. This is OK, because it is a synchronous API. But when adding a
> new connection (using addConnection), the succes/fail is a signal
> (networkmanager version 0.84). So I need to create a asynchronous loop. (I
> know this is changed in networkmanager version 0.9)
>
> So I have two solutions:
> 1) Tell the networkmanger signal to use my loop. (seems impossible, if
> please tell me how) 2) Create a second thread and start a loop using:
>    from dbus.mainloop.glib import DBusGMainLoop
>    DBusGMainLoop(set_as_default=True)
>    additional code ......
>    loop = gobject.MainLoop()
>    loop.run
>
> The second solution creates new problems. I need to make data thread safe,
> and there is no need for two thread. It's only signals!
>
> I have searched the net for a solution for (1), but I can't find any
> (2) is possible but does not seems "right"
>

Hi Anders,
        Can't you select the glib loop in twisted? Here's a test program I just
wrote that works for me.

Hope it helps,

Andrew


import dbus
from dbus.mainloop.glib import DBusGMainLoop
from twisted.application.service import Application, Service
from twisted.python import log

NM_SERVICE = 'org.freedesktop.NetworkManager'
NM_OBJPATH = '/org/freedesktop/NetworkManager'
NM_INTFACE = NM_SERVICE

loop = DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus(mainloop=loop)

obj = bus.get_object(NM_SERVICE, NM_OBJPATH)


class MyService(Service):

    def method_cb(self, arg):
        print "method returned %s" % str(arg)

    def signal_cb(self, arg):
        print "signal fired with %s" % str(arg)

    def startService(self):
        print "startService"

        obj.GetDevices(dbus_interface=NM_INTFACE,
                       reply_handler=self.method_cb,
                       error_handler=log.err)

        obj.connect_to_signal('DeviceAdded', self.signal_cb,
                                dbus_interface=NM_INTFACE)

service = MyService()
application = Application('Mytest')
service.setServiceParent(application)


# start as follows
# /usr/bin/twistd --nodaemon --python=mytest.py --reactor=glib2


2011-08-03 09:55:03+0100 [-] Log opened.
2011-08-03 09:55:03+0100 [-] twistd 10.2.0 (/usr/bin/python 2.7.1) starting
up.
2011-08-03 09:55:03+0100 [-] reactor class:
twisted.internet.glib2reactor.Glib2Reactor.
2011-08-03 09:55:03+0100 [-] startService
2011-08-03 09:55:04+0100 [-] method returned
dbus.Array([dbus.ObjectPath('/org/freedesktop/NetworkManager/Devices/0')],
signature=dbus.Signature('o'))
2011-08-03 09:55:34+0100 [-] signal fired with
/org/freedesktop/NetworkManager/Devices/1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]