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



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/dbus/message.rb', line 80

def initialize(mtype = INVALID)
  @message_type = mtype

  @flags = 0
  @protocol = 1
  @body_length = 0
  @signature = String.new
  @@serial_mutex.synchronize do
    @serial = @@serial
    @@serial += 1
  end
  @params = Array.new
  @destination = nil
  @interface = nil
  @error_name = nil
  @member = nil
  @path = nil
  @reply_serial = nil

  if mtype == METHOD_RETURN
    @flags = NO_REPLY_EXPECTED
  end
end

Instance Attribute Details

#destinationObject

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



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

def destination
  @destination
end

#error_nameObject

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



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

def error_name
  @error_name
end

#interfaceObject

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



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

def interface
  @interface
end

#memberObject

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



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

def member
  @member
end

#message_typeObject (readonly)

The type of the message.



53
54
55
# File 'lib/dbus/message.rb', line 53

def message_type
  @message_type
end

#paramsObject (readonly)

The parameters of the message.



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

def params
  @params
end

#pathObject

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



55
56
57
# File 'lib/dbus/message.rb', line 55

def path
  @path
end

#protocolObject (readonly)

The protocol.



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

def protocol
  @protocol
end

#reply_serialObject

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



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

def reply_serial
  @reply_serial
end

#senderObject

The sender of the message.



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

def sender
  @sender
end

#serialObject (readonly)

The serial of the message.



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

def serial
  @serial
end

#signatureObject

The signature of the message contents.



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

def signature
  @signature
end

Class Method Details

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

Create an error reply to a message m.



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

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

.method_return(m) ⇒ Object

Create a regular reply to a message m.



105
106
107
# File 'lib/dbus/message.rb', line 105

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

Instance Method Details

#add_param(type, val) ⇒ Object

Add a parameter val of type type to the message.



124
125
126
127
128
# File 'lib/dbus/message.rb', line 124

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

#marshallObject

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



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/dbus/message.rb', line 146

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)
  marshaller.array(Type::Parser.new("y").parse[0]) do
    if @path
      marshaller.struct do
        marshaller.append(Type::BYTE, PATH)
        marshaller.append(Type::BYTE, 1)
        marshaller.append_simple_string("o")
        marshaller.append(Type::OBJECT_PATH, @path)
      end
    end
    if @interface
      marshaller.struct do
        marshaller.append(Type::BYTE, INTERFACE)
        marshaller.append(Type::BYTE, 1)
        marshaller.append_simple_string("s")
        marshaller.append(Type::STRING, @interface)
      end
    end
    if @member
      marshaller.struct do
        marshaller.append(Type::BYTE, MEMBER)
        marshaller.append(Type::BYTE, 1)
        marshaller.append_simple_string("s")
        marshaller.append(Type::STRING, @member)
      end
    end
    if @error_name
      marshaller.struct do
        marshaller.append(Type::BYTE, ERROR_NAME)
        marshaller.append(Type::BYTE, 1)
        marshaller.append_simple_string("s")
        marshaller.append(Type::STRING, @error_name)
      end
    end
    if @reply_serial
      marshaller.struct do
        marshaller.append(Type::BYTE, REPLY_SERIAL)
        marshaller.append(Type::BYTE, 1)
        marshaller.append_simple_string("u")
        marshaller.append(Type::UINT32, @reply_serial)
      end
    end
    if @destination
      marshaller.struct do
        marshaller.append(Type::BYTE, DESTINATION)
        marshaller.append(Type::BYTE, 1)
        marshaller.append_simple_string("s")
        marshaller.append(Type::STRING, @destination)
      end
    end
    if @signature != ""
      marshaller.struct do
        marshaller.append(Type::BYTE, SIGNATURE)
        marshaller.append(Type::BYTE, 1)
        marshaller.append_simple_string("g")
        marshaller.append(Type::SIGNATURE, @signature)
      end
    end
  end
  marshaller.align(8)
  @params.each do |param|
    marshaller.append(param[0], param[1])
  end
  marshaller.packet
end

#reply_to(m) ⇒ Object

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.



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

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

#unmarshall(buf) ⇒ Object

Unmarshall the data of a message found in the buffer buf using Message#unmarshall_buf. Return the message.



276
277
278
279
# File 'lib/dbus/message.rb', line 276

def unmarshall(buf)
  ret, _ = unmarshall_buffer(buf)
  ret
end

#unmarshall_buffer(buf) ⇒ Object

Unmarshall a packet contained in the buffer buf and set the parameters of the message object according the data found in the buffer. Return the detected message and the index pointer of the buffer where the message data ended.



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/dbus/message.rb', line 234

def unmarshall_buffer(buf)
  buf = buf.dup
  if buf[0] == ?l
    endianness = LIL_END
  else
    endianness = 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 and @signature
    @params = pu.unmarshall(@signature, @body_length)
  end
  [self, pu.idx]
end