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)".freeze
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
# 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

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.



114
115
116
# 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) ⇒ Object

Create a regular reply to a message m.



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

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.



128
129
130
131
132
# File 'lib/dbus/message.rb', line 128

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

#annotate_exception(ex) ⇒ 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



234
235
236
237
238
# 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

#marshallObject

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



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
# 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) ⇒ 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.



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

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

#to_sObject



101
102
103
104
105
106
# 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) ⇒ 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.



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
228
229
230
# 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