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.

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

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

Instance Method Details

#add_param(type, val) ⇒ Object

Add a parameter val of type type to the message.



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

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.



137
138
139
140
141
142
143
144
145
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
# File 'lib/dbus/message.rb', line 137

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

  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.



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

def reply_to(m)
  @message_type = METHOD_RETURN
  @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.



267
268
269
270
# File 'lib/dbus/message.rb', line 267

def unmarshall(buf)
  ret, size = 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.



225
226
227
228
229
230
231
232
233
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
# File 'lib/dbus/message.rb', line 225

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)
  dummy, @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