示例#1
0
文件: bus.py 项目: rheenen/txdbus
    def rawDBusMessageReceived(self, raw_msg):
        msg = message.parseMessage(raw_msg)
        mt = msg._messageType

        if not self.uniqueName:
            self.bus.clientConnected(self)

        if not self._called_hello and mt == 1:
            if msg.destination == 'org.freedesktop.DBus':
                if msg.member == 'Hello':

                    r = message.MethodReturnMessage(msg.serial,
                                                    body=[self.uniqueName],
                                                    signature='s')

                    self._called_hello = True
                    self.sendMessage(r)

                    return

            else:
                self.transport.loseConnection()

        msg.sender = self.uniqueName

        msg._marshal(
            False)  # re-marshal with the sender set and same serial number

        self.bus.messageReceived(self, msg)
示例#2
0
            def send_reply(return_values):
                if isinstance(return_values, (list, tuple)):
                    if m.nret == 1:
                        return_values = [return_values]
                else:
                    return_values = [return_values]

                r = message.MethodReturnMessage(msg.serial,
                                                body=return_values,
                                                destination=msg.sender,
                                                signature=m.sigOut)
                self.conn.sendMessage(r)
示例#3
0
    def handleMethodCallMessage(self, msg):
        """
        Handles DBus MethodCall messages on behalf of the DBus Connection and
        dispatches them to the appropriate exported object
        """
        if msg.interface == 'org.freedesktop.DBus.Peer' and msg.member == 'Ping':

            r = message.MethodReturnMessage(msg.serial, destination=msg.sender)

            self.conn.sendMessage(r)
            return

        #Try to get object from complete object path
        o = self.exports.get(msg.path, None)

        if msg.interface == 'org.freedesktop.DBus.Introspectable' and (
                msg.member == 'Introspect'):

            xml = None

            if o is not None:
                #We have an object, so extract full introspection XML from it
                xml = introspection.generateIntrospectionXML(
                    o.getObjectPath(), o.getInterfaces())
            else:
                #We have no object, perhaps this is a partial path
                xml = introspection.generateIntrospectionXMLForPartialPath(
                    msg.path, self.exports.keys())

            if xml is not None:
                r = message.MethodReturnMessage(msg.serial,
                                                body=[xml],
                                                destination=msg.sender,
                                                signature='s')

                self.conn.sendMessage(r)

                return

        if o is None:
            self._send_err(
                msg, 'org.freedesktop.DBus.Error.UnknownObject',
                '%s is not an object provided by this process.' % (msg.path))
            return

        if msg.interface == 'org.freedesktop.DBus.ObjectManager' and (
                msg.member == 'GetManagedObjects'):

            i_and_p = self.getManagedObjects(o.getObjectPath())

            r = message.MethodReturnMessage(msg.serial,
                                            body=[i_and_p],
                                            destination=msg.sender,
                                            signature='a{oa{sa{sv}}}')

            self.conn.sendMessage(r)

            return

        i = None

        for x in o.getInterfaces():
            if msg.interface:
                if x.name == msg.interface:
                    i = x
                    break
            else:
                if msg.member in x.methods:
                    i = x
                    break

        m = None
        if i:
            m = i.methods.get(msg.member, None)

        if m is None:
            self._send_err(
                msg, 'org.freedesktop.DBus.Error.UnknownMethod',
                'Method "%s" with signature "%s" on interface "%s" doesn\'t exist'
                % (msg.member, msg.signature or '', msg.interface or '(null)'))
            return

        msig = msg.signature if msg.signature is not None else ''
        esig = m.sigIn if m.sigIn is not None else ''

        if esig != msig:
            self._send_err(
                msg, 'org.freedesktop.DBus.Error.InvalidArgs',
                'Call to %s has wrong args (%s, expected %s)' %
                (msg.member, msg.signature or '', m.sigIn or ''))
            return

        d = defer.maybeDeferred(o.executeMethod, i, msg.member, msg.body,
                                msg.sender)

        if msg.expectReply:

            def send_reply(return_values):
                if isinstance(return_values, (list, tuple)):
                    if m.nret == 1:
                        return_values = [return_values]
                else:
                    return_values = [return_values]

                r = message.MethodReturnMessage(msg.serial,
                                                body=return_values,
                                                destination=msg.sender,
                                                signature=m.sigOut)
                self.conn.sendMessage(r)

            def send_error(err):
                e = err.value
                errMsg = err.getErrorMessage()
                name = None

                if hasattr(e, 'dbusErrorName'):
                    name = e.dbusErrorName

                if name is None:
                    name = 'org.txdbus.PythonException.' + e.__class__.__name__

                try:
                    marshal.validateErrorName(name)
                except error.MarshallingError, e:
                    errMsg = ('!!(Invalid error name "%s")!! ' % name) + errMsg
                    name = 'org.txdbus.InvalidErrorName'

                r = message.ErrorMessage(name,
                                         msg.serial,
                                         body=[errMsg],
                                         signature='s',
                                         destination=msg.sender)
                self.conn.sendMessage(r)

            d.addCallback(send_reply)
            d.addErrback(send_error)