# class DBus::Message

# D-Bus message class¶ ↑

Class that holds any type of message that travels over the bus.

### Constants

DESTINATION
ERROR

  Error message type.

ERROR_NAME
INTERFACE
INVALID

  FIXME: following message type constants should be under Message::Type IMO well, yeah sure

  Invalid message type.

MEMBER
MESSAGE_SIGNATURE

  Type of a message (by specification).

METHOD_CALL

  Method call message type.

METHOD_RETURN

  Method call return value message type.

NO_AUTO_START

  Message flag signifying that no automatic start is required/must be performed.

NO_REPLY_EXPECTED

  Message flag signyfing that no reply is expected.

PATH

  FIXME: what are these? a message element constant enumeration? See method below, in a message, you have and array of optional parameters that come with an index, to determine their meaning. The values are in spec, more a definition than an enumeration.

REPLY_SERIAL
SENDER
SIGNAL

  Signal message type.

SIGNATURE

### Attributes

destination[RW]

The destination connection of the object that must be used/was used.

error_name[RW]

The name of the error (in case of an error message type).

interface[RW]

The interface of the object that must be used/was used.

member[RW]

The interface member (method/signal name) of the object that must be used/was used.

message_type[R]

The type of the message.

params[R]

The parameters of the message.

path[RW]

The path of the object instance the message must be sent to/is sent from.

protocol[R]

The protocol.

reply_serial[RW]

The serial number of the message this message is a reply for.

sender[RW]

The sender of the message.

serial[R]

The serial of the message.

signature[RW]

The signature of the message contents.

### Public Class Methods

error(m, error_name, description = nil) click to toggle source

Create an error reply to a message m.

    # File lib/dbus/message.rb, line 114
    def self.error(m, error_name, description = nil)
      ErrorMessage.new(error_name, description).reply_to(m)
    end

method_return(m) click to toggle source

Create a regular reply to a message m.

    # File lib/dbus/message.rb, line 109
    def self.method_return(m)
      MethodReturnMessage.new.reply_to(m)
    end

new(mtype = INVALID) click to toggle source

Create a message with message type mtype with default values and a unique serial number.

    # File lib/dbus/message.rb, line 80
    def initialize(mtype = INVALID)
      @message_type = mtype

      @flags = 0
      @protocol = 1
      @body_length = 0
      @signature = ""
      @@serial_mutex.synchronize do
        @serial = @@serial
        @@serial += 1
      end
      @params = []
      @destination = nil
      @interface = nil
      @error_name = nil
      @member = nil
      @path = nil
      @reply_serial = nil
      @flags = NO_REPLY_EXPECTED if mtype == METHOD_RETURN
    end

### Public Instance Methods

add_param(type, val) click to toggle source

Add a parameter val of type type to the message.

    # File lib/dbus/message.rb, line 128
    def add_param(type, val)
      type = type.chr if type.is_a?(Fixnum)
      @signature += type.to_s
      @params << [type, val]
    end

annotate_exception(ex) click to toggle source

Make a new exception from ex, mark it as being caused by this message @api private

    # File lib/dbus/message.rb, line 234
    def annotate_exception(ex)
      new_ex = ex.exception("#{ex}; caused by #{self}")
      new_ex.set_backtrace(ex.backtrace)
      new_ex
    end

marshall() click to toggle source

Marshall the message with its current set parameters and return it in a packet form.

    # File lib/dbus/message.rb, line 150
    def marshall
      if @path == "/org/freedesktop/DBus/Local"
        raise InvalidDestinationName
      end

      params = PacketMarshaller.new
      @params.each do |param|
        params.append(param[0], param[1])
      end
      @body_length = params.packet.bytesize

      marshaller = PacketMarshaller.new
      marshaller.append(Type::BYTE, HOST_END)
      marshaller.append(Type::BYTE, @message_type)
      marshaller.append(Type::BYTE, @flags)
      marshaller.append(Type::BYTE, @protocol)
      marshaller.append(Type::UINT32, @body_length)
      marshaller.append(Type::UINT32, @serial)

      headers = []
      headers << [PATH,         ["o", @path]]         if @path
      headers << [INTERFACE,    ["s", @interface]]    if @interface
      headers << [MEMBER,       ["s", @member]]       if @member
      headers << [ERROR_NAME,   ["s", @error_name]]   if @error_name
      headers << [REPLY_SERIAL, ["u", @reply_serial]] if @reply_serial
      headers << [DESTINATION,  ["s", @destination]]  if @destination
      #           SENDER is not sent, the message bus fills it in instead
      headers << [SIGNATURE,    ["g", @signature]]    if @signature != ""
      marshaller.append("a(yv)", headers)

      marshaller.align(8)
      @params.each do |param|
        marshaller.append(param[0], param[1])
      end
      marshaller.packet
    end

reply_to(m) click to toggle source

Mark this message as a reply to a another message m, taking the serial number of m as reply serial and the sender of m as destination.

    # File lib/dbus/message.rb, line 121
    def reply_to(m)
      @reply_serial = m.serial
      @destination = m.sender
      self
    end

to_s() click to toggle source

    # File lib/dbus/message.rb, line 101
    def to_s
      "#{message_type} sender=#{sender} -> dest=#{destination} "        "serial=#{serial} reply_serial=#{reply_serial} "        "path=#{path}; interface=#{interface}; member=#{member} "        "error_name=#{error_name}"
    end

unmarshall_buffer(buf) click to toggle source

Unmarshall a packet contained in the buffer buf and set the parameters of the message object according the data found in the buffer. @return [Array(Message,Integer)]

    the detected message (self) and
    the index pointer of the buffer where the message data ended.

    # File lib/dbus/message.rb, line 193
    def unmarshall_buffer(buf)
      buf = buf.dup
      endianness = if buf[0] == "l"
                     LIL_END
                   else
                     BIG_END
                   end
      pu = PacketUnmarshaller.new(buf, endianness)
      mdata = pu.unmarshall(MESSAGE_SIGNATURE)
      _, @message_type, @flags, @protocol, @body_length, @serial,
        headers = mdata

      headers.each do |struct|
        case struct[0]
        when PATH
          @path = struct[1]
        when INTERFACE
          @interface = struct[1]
        when MEMBER
          @member = struct[1]
        when ERROR_NAME
          @error_name = struct[1]
        when REPLY_SERIAL
          @reply_serial = struct[1]
        when DESTINATION
          @destination = struct[1]
        when SENDER
          @sender = struct[1]
        when SIGNATURE
          @signature = struct[1]
        end
      end
      pu.align(8)
      if @body_length > 0 && @signature
        @params = pu.unmarshall(@signature, @body_length)
      end
      [self, pu.idx]
    end