Class: DBus::Message

Inherits:
Object
  • Object
show all
Defined in:
lib/dbus/message.rb

Overview

D-Bus message class

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

Direct Known Subclasses

ErrorMessage, MethodReturnMessage

Constant Summary collapse

MESSAGE_SIGNATURE =

Type of a message (by specification).

"yyyyuua(yv)"
INVALID =

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

Invalid message type.

0
METHOD_CALL =

Method call message type.

1
METHOD_RETURN =

Method call return value message type.

2
ERROR =

Error message type.

3
SIGNAL =

Signal message type.

4
TYPE_NAMES =

Names used by signal match rules

["invalid", "method_call", "method_return", "error", "signal"].freeze
NO_REPLY_EXPECTED =

Message flag signyfing that no reply is expected.

0x1
NO_AUTO_START =

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

0x2
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.

1
INTERFACE =
2
MEMBER =
3
ERROR_NAME =
4
REPLY_SERIAL =
5
DESTINATION =
6
SENDER =
7
SIGNATURE =
8
@@serial =

The serial number of the message.

1
@@serial_mutex =

Mutex that protects updates on the serial number.

Mutex.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mtype = INVALID) ⇒ Message

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



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/dbus/message.rb', line 87

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

Instance Attribute Details

#destinationObject

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



69
70
71
# File 'lib/dbus/message.rb', line 69

def destination
  @destination
end

#error_nameObject

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



67
68
69
# File 'lib/dbus/message.rb', line 67

def error_name
  @error_name
end

#interfaceObject

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



62
63
64
# File 'lib/dbus/message.rb', line 62

def interface
  @interface
end

#memberObject

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



65
66
67
# File 'lib/dbus/message.rb', line 65

def member
  @member
end

#message_typeObject (readonly)

The type of the message.



58
59
60
# File 'lib/dbus/message.rb', line 58

def message_type
  @message_type
end

#paramsObject (readonly)

The parameters of the message.



83
84
85
# File 'lib/dbus/message.rb', line 83

def params
  @params
end

#pathObject

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



60
61
62
# File 'lib/dbus/message.rb', line 60

def path
  @path
end

#protocolObject (readonly)

The protocol.



78
79
80
# File 'lib/dbus/message.rb', line 78

def protocol
  @protocol
end

#reply_serialInteger

Returns (u32) The serial number of the message this message is a reply for.

Returns:

  • (Integer)

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



76
77
78
# File 'lib/dbus/message.rb', line 76

def reply_serial
  @reply_serial
end

#senderObject

The sender of the message.



71
72
73
# File 'lib/dbus/message.rb', line 71

def sender
  @sender
end

#serialInteger (readonly)

Returns (u32) The serial of the message.

Returns:

  • (Integer)

    (u32) The serial of the message.



81
82
83
# File 'lib/dbus/message.rb', line 81

def serial
  @serial
end

#signatureObject

The signature of the message contents.



73
74
75
# File 'lib/dbus/message.rb', line 73

def signature
  @signature
end

Class Method Details

.error(msg, error_name, description = nil) ⇒ Object

Create an error reply to a message msg.



127
128
129
# File 'lib/dbus/message.rb', line 127

def self.error(msg, error_name, description = nil)
  ErrorMessage.new(error_name, description).reply_to(msg)
end

.method_return(msg) ⇒ Object

Create a regular reply to a message msg.



122
123
124
# File 'lib/dbus/message.rb', line 122

def self.method_return(msg)
  MethodReturnMessage.new.reply_to(msg)
end

Instance Method Details

#add_param(type, val) ⇒ Object

Add a parameter val of type type to the message.



141
142
143
144
145
# File 'lib/dbus/message.rb', line 141

def add_param(type, val)
  type = type.chr if type.is_a?(Integer)
  @signature += type.to_s
  @params << [type, val]
end

#annotate_exception(exc) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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



241
242
243
244
245
# File 'lib/dbus/message.rb', line 241

def annotate_exception(exc)
  new_exc = exc.exception("#{exc}; caused by #{self}")
  new_exc.set_backtrace(exc.backtrace)
  new_exc
end

#marshallObject

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



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/dbus/message.rb', line 163

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.ord)
  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

#message_type_sString

Returns name of message type, as used in match rules: “method_call”, “method_return”, “signal”, “error”.

Returns:

  • (String)

    name of message type, as used in match rules: “method_call”, “method_return”, “signal”, “error”



117
118
119
# File 'lib/dbus/message.rb', line 117

def message_type_s
  TYPE_NAMES[message_type] || "unknown_type_#{message_type}"
end

#reply_to(msg) ⇒ Object

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



134
135
136
137
138
# File 'lib/dbus/message.rb', line 134

def reply_to(msg)
  @reply_serial = msg.serial
  @destination = msg.sender
  self
end

#to_sObject



108
109
110
111
112
113
# File 'lib/dbus/message.rb', line 108

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) ⇒ Array(Message,Integer)

Unmarshall a packet contained in the buffer buf and set the parameters of the message object according the data found in the buffer.

Returns:

  • (Array(Message,Integer))

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



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/dbus/message.rb', line 206

def unmarshall_buffer(buf)
  pu = PacketUnmarshaller.new(buf, RawMessage.endianness(buf[0]))
  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_body
  if @body_length.positive? && @signature
    @params = pu.unmarshall(@signature, @body_length)
  end
  [self, pu.consumed_size]
end