message.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef DBUS_MESSAGE_H_
  5. #define DBUS_MESSAGE_H_
  6. #include <dbus/dbus.h>
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include <memory>
  10. #include <string>
  11. #include <vector>
  12. #include "base/files/scoped_file.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/strings/string_piece.h"
  15. #include "dbus/dbus_export.h"
  16. #include "dbus/object_path.h"
  17. namespace google {
  18. namespace protobuf {
  19. class MessageLite;
  20. } // namespace protobuf
  21. } // namespace google
  22. namespace dbus {
  23. class MessageWriter;
  24. class MessageReader;
  25. // DBUS_TYPE_UNIX_FD was added in D-Bus version 1.4
  26. #if !defined(DBUS_TYPE_UNIX_FD)
  27. #define DBUS_TYPE_UNIX_FD ((int)'h')
  28. #endif
  29. // Returns true if Unix FD passing is supported in libdbus.
  30. // The check is done runtime rather than compile time as the libdbus
  31. // version used at runtime may be different from the one used at compile time.
  32. CHROME_DBUS_EXPORT bool IsDBusTypeUnixFdSupported();
  33. // Message is the base class of D-Bus message types. Client code must use
  34. // sub classes such as MethodCall and Response instead.
  35. //
  36. // The class name Message is very generic, but there should be no problem
  37. // as the class is inside 'dbus' namespace. We chose to name this way, as
  38. // libdbus defines lots of types starting with DBus, such as
  39. // DBusMessage. We should avoid confusion and conflict with these types.
  40. class CHROME_DBUS_EXPORT Message {
  41. public:
  42. // The message type used in D-Bus. Redefined here so client code
  43. // doesn't need to use raw D-Bus macros. DBUS_MESSAGE_TYPE_INVALID
  44. // etc. are #define macros. Having an enum type here makes code a bit
  45. // more type-safe.
  46. enum MessageType {
  47. MESSAGE_INVALID = DBUS_MESSAGE_TYPE_INVALID,
  48. MESSAGE_METHOD_CALL = DBUS_MESSAGE_TYPE_METHOD_CALL,
  49. MESSAGE_METHOD_RETURN = DBUS_MESSAGE_TYPE_METHOD_RETURN,
  50. MESSAGE_SIGNAL = DBUS_MESSAGE_TYPE_SIGNAL,
  51. MESSAGE_ERROR = DBUS_MESSAGE_TYPE_ERROR,
  52. };
  53. // The data type used in the D-Bus type system. See the comment at
  54. // MessageType for why we are redefining data types here.
  55. enum DataType {
  56. INVALID_DATA = DBUS_TYPE_INVALID,
  57. BYTE = DBUS_TYPE_BYTE,
  58. BOOL = DBUS_TYPE_BOOLEAN,
  59. INT16 = DBUS_TYPE_INT16,
  60. UINT16 = DBUS_TYPE_UINT16,
  61. INT32 = DBUS_TYPE_INT32,
  62. UINT32 = DBUS_TYPE_UINT32,
  63. INT64 = DBUS_TYPE_INT64,
  64. UINT64 = DBUS_TYPE_UINT64,
  65. DOUBLE = DBUS_TYPE_DOUBLE,
  66. STRING = DBUS_TYPE_STRING,
  67. OBJECT_PATH = DBUS_TYPE_OBJECT_PATH,
  68. ARRAY = DBUS_TYPE_ARRAY,
  69. STRUCT = DBUS_TYPE_STRUCT,
  70. DICT_ENTRY = DBUS_TYPE_DICT_ENTRY,
  71. VARIANT = DBUS_TYPE_VARIANT,
  72. UNIX_FD = DBUS_TYPE_UNIX_FD,
  73. };
  74. Message(const Message&) = delete;
  75. Message& operator=(const Message&) = delete;
  76. // Returns the type of the message. Returns MESSAGE_INVALID if
  77. // raw_message_ is NULL.
  78. MessageType GetMessageType();
  79. // Returns the type of the message as string like "MESSAGE_METHOD_CALL"
  80. // for instance.
  81. std::string GetMessageTypeAsString();
  82. DBusMessage* raw_message() { return raw_message_; }
  83. // Sets the destination, the path, the interface, the member, etc.
  84. bool SetDestination(const std::string& destination);
  85. bool SetPath(const ObjectPath& path);
  86. bool SetInterface(const std::string& interface);
  87. bool SetMember(const std::string& member);
  88. bool SetErrorName(const std::string& error_name);
  89. bool SetSender(const std::string& sender);
  90. void SetSerial(uint32_t serial);
  91. void SetReplySerial(uint32_t reply_serial);
  92. // SetSignature() does not exist as we cannot do it.
  93. // Gets the destination, the path, the interface, the member, etc.
  94. // If not set, an empty string is returned.
  95. std::string GetDestination();
  96. ObjectPath GetPath();
  97. std::string GetInterface();
  98. std::string GetMember();
  99. std::string GetErrorName();
  100. std::string GetSender();
  101. std::string GetSignature();
  102. // Gets the serial and reply serial numbers. Returns 0 if not set.
  103. uint32_t GetSerial();
  104. uint32_t GetReplySerial();
  105. // Returns the string representation of this message. Useful for
  106. // debugging. The output is truncated as needed (ex. strings are truncated
  107. // if longer than a certain limit defined in the .cc file).
  108. std::string ToString();
  109. protected:
  110. // This class cannot be instantiated. Use sub classes instead.
  111. Message();
  112. virtual ~Message();
  113. // Initializes the message with the given raw message.
  114. void Init(DBusMessage* raw_message);
  115. private:
  116. // Helper function used in ToString().
  117. std::string ToStringInternal(const std::string& indent,
  118. MessageReader* reader);
  119. raw_ptr<DBusMessage, DanglingUntriaged> raw_message_;
  120. };
  121. // MessageCall is a type of message used for calling a method via D-Bus.
  122. class CHROME_DBUS_EXPORT MethodCall : public Message {
  123. public:
  124. // Creates a method call message for the specified interface name and
  125. // the method name.
  126. //
  127. // For instance, to call "Get" method of DBUS_INTERFACE_INTROSPECTABLE
  128. // interface ("org.freedesktop.DBus.Introspectable"), create a method
  129. // call like this:
  130. //
  131. // MethodCall method_call(DBUS_INTERFACE_INTROSPECTABLE, "Get");
  132. //
  133. // The constructor creates the internal raw message.
  134. MethodCall(const std::string& interface_name, const std::string& method_name);
  135. MethodCall(const MethodCall&) = delete;
  136. MethodCall& operator=(const MethodCall&) = delete;
  137. // Returns a newly created MethodCall from the given raw message of the
  138. // type DBUS_MESSAGE_TYPE_METHOD_CALL. Takes the ownership of |raw_message|.
  139. static std::unique_ptr<MethodCall> FromRawMessage(DBusMessage* raw_message);
  140. private:
  141. // Creates a method call message. The internal raw message is NULL.
  142. // Only used internally.
  143. MethodCall();
  144. };
  145. // Signal is a type of message used to send a signal.
  146. class CHROME_DBUS_EXPORT Signal : public Message {
  147. public:
  148. // Creates a signal message for the specified interface name and the
  149. // method name.
  150. //
  151. // For instance, to send "PropertiesChanged" signal of
  152. // DBUS_INTERFACE_INTROSPECTABLE interface
  153. // ("org.freedesktop.DBus.Introspectable"), create a signal like this:
  154. //
  155. // Signal signal(DBUS_INTERFACE_INTROSPECTABLE, "PropertiesChanged");
  156. //
  157. // The constructor creates the internal raw_message_.
  158. Signal(const std::string& interface_name, const std::string& method_name);
  159. Signal(const Signal&) = delete;
  160. Signal& operator=(const Signal&) = delete;
  161. // Returns a newly created SIGNAL from the given raw message of the type
  162. // DBUS_MESSAGE_TYPE_SIGNAL. Takes the ownership of |raw_message|.
  163. static std::unique_ptr<Signal> FromRawMessage(DBusMessage* raw_message);
  164. private:
  165. // Creates a signal message. The internal raw message is NULL.
  166. // Only used internally.
  167. Signal();
  168. };
  169. // Response is a type of message used for receiving a response from a
  170. // method via D-Bus.
  171. class CHROME_DBUS_EXPORT Response : public Message {
  172. public:
  173. // Returns a newly created Response from the given raw message of the
  174. // type DBUS_MESSAGE_TYPE_METHOD_RETURN. Takes the ownership of |raw_message|.
  175. static std::unique_ptr<Response> FromRawMessage(DBusMessage* raw_message);
  176. // Returns a newly created Response from the given method call.
  177. // Used for implementing exported methods. Does NOT take the ownership of
  178. // |method_call|.
  179. static std::unique_ptr<Response> FromMethodCall(MethodCall* method_call);
  180. // Returns a newly created Response with an empty payload.
  181. // Useful for testing.
  182. static std::unique_ptr<Response> CreateEmpty();
  183. Response(const Response&) = delete;
  184. Response& operator=(const Response&) = delete;
  185. protected:
  186. // Creates a Response message. The internal raw message is NULL.
  187. Response();
  188. };
  189. // ErrorResponse is a type of message used to return an error to the
  190. // caller of a method.
  191. class CHROME_DBUS_EXPORT ErrorResponse : public Response {
  192. public:
  193. // Returns a newly created Response from the given raw message of the
  194. // type DBUS_MESSAGE_TYPE_METHOD_RETURN. Takes the ownership of |raw_message|.
  195. static std::unique_ptr<ErrorResponse> FromRawMessage(
  196. DBusMessage* raw_message);
  197. // Returns a newly created ErrorResponse from the given method call, the
  198. // error name, and the error message. The error name looks like
  199. // "org.freedesktop.DBus.Error.Failed". Used for returning an error to a
  200. // failed method call. Does NOT take the ownership of |method_call|.
  201. static std::unique_ptr<ErrorResponse> FromMethodCall(
  202. MethodCall* method_call,
  203. const std::string& error_name,
  204. const std::string& error_message);
  205. ErrorResponse(const ErrorResponse&) = delete;
  206. ErrorResponse& operator=(const ErrorResponse&) = delete;
  207. private:
  208. // Creates an ErrorResponse message. The internal raw message is NULL.
  209. ErrorResponse();
  210. };
  211. // MessageWriter is used to write outgoing messages for calling methods
  212. // and sending signals.
  213. //
  214. // The main design goal of MessageReader and MessageWriter classes is to
  215. // provide a type safe API. In the past, there was a Chrome OS blocker
  216. // bug, that took days to fix, that would have been prevented if the API
  217. // was type-safe.
  218. //
  219. // For instance, instead of doing something like:
  220. //
  221. // // We shouldn't add '&' to str here, but it compiles with '&' added.
  222. // dbus_g_proxy_call(..., G_TYPE_STRING, str, G_TYPE_INVALID, ...)
  223. //
  224. // We want to do something like:
  225. //
  226. // writer.AppendString(str);
  227. //
  228. class CHROME_DBUS_EXPORT MessageWriter {
  229. public:
  230. // Data added with Append* will be written to |message|, which may be NULL
  231. // to create a sub-writer for passing to OpenArray, etc.
  232. explicit MessageWriter(Message* message);
  233. MessageWriter(const MessageWriter&) = delete;
  234. MessageWriter& operator=(const MessageWriter&) = delete;
  235. ~MessageWriter();
  236. // Appends a byte to the message.
  237. void AppendByte(uint8_t value);
  238. void AppendBool(bool value);
  239. void AppendInt16(int16_t value);
  240. void AppendUint16(uint16_t value);
  241. void AppendInt32(int32_t value);
  242. void AppendUint32(uint32_t value);
  243. void AppendInt64(int64_t value);
  244. void AppendUint64(uint64_t value);
  245. void AppendDouble(double value);
  246. void AppendString(base::StringPiece value);
  247. void AppendObjectPath(const ObjectPath& value);
  248. // Appends a file descriptor to the message.
  249. // The FD will be duplicated so you still have to close the original FD.
  250. void AppendFileDescriptor(int value);
  251. // Opens an array. The array contents can be added to the array with
  252. // |sub_writer|. The client code must close the array with
  253. // CloseContainer(), once all contents are added.
  254. //
  255. // |signature| parameter is used to supply the D-Bus type signature of
  256. // the array contents. For instance, if you want an array of strings,
  257. // then you pass "s" as the signature.
  258. //
  259. // See the spec for details about the type signatures.
  260. // http://dbus.freedesktop.org/doc/dbus-specification.html
  261. // #message-protocol-signatures
  262. //
  263. void OpenArray(const std::string& signature, MessageWriter* sub_writer);
  264. // Do the same for a variant.
  265. void OpenVariant(const std::string& signature, MessageWriter* sub_writer);
  266. // Do the same for Struct and dict entry. They don't need the signature.
  267. void OpenStruct(MessageWriter* sub_writer);
  268. void OpenDictEntry(MessageWriter* sub_writer);
  269. // Close the container for a array/variant/struct/dict entry.
  270. void CloseContainer(MessageWriter* sub_writer);
  271. // Appends the array of bytes. Arrays of bytes are often used for
  272. // exchanging binary blobs hence it's worth having a specialized
  273. // function.
  274. void AppendArrayOfBytes(const uint8_t* values, size_t length);
  275. // Appends array of int32_ts.
  276. void AppendArrayOfInt32s(const int32_t* values, size_t length);
  277. // Appends array of uint32_ts.
  278. void AppendArrayOfUint32s(const uint32_t* values, size_t length);
  279. // Appends the array of doubles. Used for audio mixer matrix doubles.
  280. void AppendArrayOfDoubles(const double* values, size_t length);
  281. // Appends the array of strings. Arrays of strings are often used for
  282. // exchanging lists of names hence it's worth having a specialized
  283. // function.
  284. void AppendArrayOfStrings(const std::vector<std::string>& strings);
  285. // Appends the array of object paths. Arrays of object paths are often
  286. // used when exchanging object paths, hence it's worth having a
  287. // specialized function.
  288. void AppendArrayOfObjectPaths(const std::vector<ObjectPath>& object_paths);
  289. // Appends the protocol buffer as an array of bytes. The buffer is serialized
  290. // into an array of bytes before communication, since protocol buffers are not
  291. // a native dbus type. On the receiving size the array of bytes needs to be
  292. // read and deserialized into a protocol buffer of the correct type. There are
  293. // methods in MessageReader to assist in this. Return true on success and
  294. // false when serialization fails.
  295. bool AppendProtoAsArrayOfBytes(const google::protobuf::MessageLite& protobuf);
  296. // Appends the byte wrapped in a variant data container. Variants are
  297. // widely used in D-Bus services so it's worth having a specialized
  298. // function. For instance, The third parameter of
  299. // "org.freedesktop.DBus.Properties.Set" is a variant.
  300. void AppendVariantOfByte(uint8_t value);
  301. void AppendVariantOfBool(bool value);
  302. void AppendVariantOfInt16(int16_t value);
  303. void AppendVariantOfUint16(uint16_t value);
  304. void AppendVariantOfInt32(int32_t value);
  305. void AppendVariantOfUint32(uint32_t value);
  306. void AppendVariantOfInt64(int64_t value);
  307. void AppendVariantOfUint64(uint64_t value);
  308. void AppendVariantOfDouble(double value);
  309. void AppendVariantOfString(const std::string& value);
  310. void AppendVariantOfObjectPath(const ObjectPath& value);
  311. private:
  312. // Helper function used to implement AppendByte etc.
  313. void AppendBasic(int dbus_type, const void* value);
  314. // Helper function used to implement AppendVariantOfByte() etc.
  315. void AppendVariantOfBasic(int dbus_type, const void* value);
  316. raw_ptr<Message, DanglingUntriaged> message_;
  317. DBusMessageIter raw_message_iter_;
  318. bool container_is_open_;
  319. };
  320. // MessageReader is used to read incoming messages such as responses for
  321. // method calls.
  322. //
  323. // MessageReader manages an internal iterator to read data. All functions
  324. // starting with Pop advance the iterator on success.
  325. class CHROME_DBUS_EXPORT MessageReader {
  326. public:
  327. // The data will be read from the given |message|, which may be NULL to
  328. // create a sub-reader for passing to PopArray, etc.
  329. explicit MessageReader(Message* message);
  330. MessageReader(const MessageReader&) = delete;
  331. MessageReader& operator=(const MessageReader&) = delete;
  332. ~MessageReader();
  333. // Returns true if the reader has more data to read. The function is
  334. // used to iterate contents in a container like:
  335. //
  336. // while (reader.HasMoreData())
  337. // reader.PopString(&value);
  338. bool HasMoreData();
  339. // Gets the byte at the current iterator position.
  340. // Returns true and advances the iterator on success.
  341. // Returns false if the data type is not a byte.
  342. bool PopByte(uint8_t* value);
  343. bool PopBool(bool* value);
  344. bool PopInt16(int16_t* value);
  345. bool PopUint16(uint16_t* value);
  346. bool PopInt32(int32_t* value);
  347. bool PopUint32(uint32_t* value);
  348. bool PopInt64(int64_t* value);
  349. bool PopUint64(uint64_t* value);
  350. bool PopDouble(double* value);
  351. bool PopString(std::string* value);
  352. bool PopObjectPath(ObjectPath* value);
  353. bool PopFileDescriptor(base::ScopedFD* value);
  354. // Sets up the given message reader to read an array at the current
  355. // iterator position.
  356. // Returns true and advances the iterator on success.
  357. // Returns false if the data type is not an array
  358. bool PopArray(MessageReader* sub_reader);
  359. bool PopStruct(MessageReader* sub_reader);
  360. bool PopDictEntry(MessageReader* sub_reader);
  361. bool PopVariant(MessageReader* sub_reader);
  362. // Gets the array of bytes at the current iterator position.
  363. // Returns true and advances the iterator on success.
  364. //
  365. // Arrays of bytes are often used for exchanging binary blobs hence it's
  366. // worth having a specialized function.
  367. //
  368. // Ownership of the memory pointed to by |bytes| remains with the
  369. // MessageReader; |bytes| must be copied if the contents will be referenced
  370. // after the MessageReader is destroyed.
  371. bool PopArrayOfBytes(const uint8_t** bytes, size_t* length);
  372. // Gets the array of int32_ts at the current iterator position.
  373. bool PopArrayOfInt32s(const int32_t** signed_ints, size_t* length);
  374. // Gets the array of uint32_ts at the current iterator position.
  375. bool PopArrayOfUint32s(const uint32_t** unsigned_ints, size_t* length);
  376. // Gets the array of doubles at the current iterator position.
  377. bool PopArrayOfDoubles(const double** doubles, size_t* length);
  378. // Gets the array of strings at the current iterator position. |strings| is
  379. // cleared before being modified. Returns true and advances the iterator on
  380. // success.
  381. //
  382. // Arrays of strings are often used to communicate with D-Bus
  383. // services like KWallet, hence it's worth having a specialized
  384. // function.
  385. bool PopArrayOfStrings(std::vector<std::string>* strings);
  386. // Gets the array of object paths at the current iterator position.
  387. // |object_paths| is cleared before being modified. Returns true and advances
  388. // the iterator on success.
  389. //
  390. // Arrays of object paths are often used to communicate with D-Bus
  391. // services like NetworkManager, hence it's worth having a specialized
  392. // function.
  393. bool PopArrayOfObjectPaths(std::vector<ObjectPath>* object_paths);
  394. // Gets the array of bytes at the current iterator position. It then parses
  395. // this binary blob into the protocol buffer supplied.
  396. // Returns true and advances the iterator on success. On failure returns false
  397. // and emits an error message on the source of the failure. The two most
  398. // common errors come from the iterator not currently being at a byte array or
  399. // the wrong type of protocol buffer is passed in and the parse fails.
  400. bool PopArrayOfBytesAsProto(google::protobuf::MessageLite* protobuf);
  401. // Gets the byte from the variant data container at the current iterator
  402. // position.
  403. // Returns true and advances the iterator on success.
  404. //
  405. // Variants are widely used in D-Bus services so it's worth having a
  406. // specialized function. For instance, The return value type of
  407. // "org.freedesktop.DBus.Properties.Get" is a variant.
  408. bool PopVariantOfByte(uint8_t* value);
  409. bool PopVariantOfBool(bool* value);
  410. bool PopVariantOfInt16(int16_t* value);
  411. bool PopVariantOfUint16(uint16_t* value);
  412. bool PopVariantOfInt32(int32_t* value);
  413. bool PopVariantOfUint32(uint32_t* value);
  414. bool PopVariantOfInt64(int64_t* value);
  415. bool PopVariantOfUint64(uint64_t* value);
  416. bool PopVariantOfDouble(double* value);
  417. bool PopVariantOfString(std::string* value);
  418. bool PopVariantOfObjectPath(ObjectPath* value);
  419. // Get the data type of the value at the current iterator
  420. // position. INVALID_DATA will be returned if the iterator points to the
  421. // end of the message.
  422. Message::DataType GetDataType();
  423. // Get the DBus signature of the value at the current iterator position.
  424. // An empty string will be returned if the iterator points to the end of
  425. // the message.
  426. std::string GetDataSignature();
  427. private:
  428. // Returns true if the data type at the current iterator position
  429. // matches the given D-Bus type, such as DBUS_TYPE_BYTE.
  430. bool CheckDataType(int dbus_type);
  431. // Helper function used to implement PopByte() etc.
  432. bool PopBasic(int dbus_type, void* value);
  433. // Helper function used to implement PopArray() etc.
  434. bool PopContainer(int dbus_type, MessageReader* sub_reader);
  435. // Helper function used to implement PopVariantOfByte() etc.
  436. bool PopVariantOfBasic(int dbus_type, void* value);
  437. raw_ptr<Message, DanglingUntriaged> message_;
  438. DBusMessageIter raw_message_iter_;
  439. };
  440. } // namespace dbus
  441. #endif // DBUS_MESSAGE_H_