diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | dbus/dbus-bus.c | 16 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 6 | ||||
-rw-r--r-- | dbus/dbus-message-builder.c | 8 | ||||
-rw-r--r-- | dbus/dbus-message.c | 174 | ||||
-rw-r--r-- | dbus/dbus-message.h | 16 | ||||
-rw-r--r-- | dbus/dbus-object-registry.c | 85 | ||||
-rw-r--r-- | dbus/dbus-object.c | 5 | ||||
-rw-r--r-- | dbus/dbus-protocol.h | 1 | ||||
-rw-r--r-- | doc/dbus-specification.sgml | 58 | ||||
-rw-r--r-- | test/data/invalid-messages/bad-endian.message | 2 | ||||
-rw-r--r-- | test/data/valid-messages/simplest-manual.message | 2 |
12 files changed, 309 insertions, 73 deletions
@@ -1,5 +1,14 @@ 2003-08-01 Havoc Pennington <hp@pobox.com> + * dbus/dbus-object-registry.c (_dbus_object_registry_handle_and_unlock): + implement + + * dbus/dbus-message.c (dbus_message_get_type): new function + + * doc/dbus-specification.sgml: add "type" byte to messages + +2003-08-01 Havoc Pennington <hp@pobox.com> + * dbus/dbus-protocol.h (DBUS_MESSAGE_TYPE_*): introduce a message type enum to distinguish kinds of message (DBUS_HEADER_FLAG_NO_REPLY_EXPECTED): flag for a message diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index 6ab1eccc..214978da 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -398,8 +398,8 @@ dbus_bus_register (DBusConnection *connection, return TRUE; } - message = dbus_message_new (DBUS_MESSAGE_HELLO, - DBUS_SERVICE_DBUS); + message = dbus_message_new_method_call (DBUS_MESSAGE_HELLO, + DBUS_SERVICE_DBUS); if (!message) @@ -516,8 +516,8 @@ dbus_bus_acquire_service (DBusConnection *connection, _dbus_return_val_if_fail (service_name != NULL, 0); _dbus_return_val_if_error_is_set (error, 0); - message = dbus_message_new (DBUS_MESSAGE_ACQUIRE_SERVICE, - DBUS_SERVICE_DBUS); + message = dbus_message_new_method_call (DBUS_MESSAGE_ACQUIRE_SERVICE, + DBUS_SERVICE_DBUS); if (message == NULL) @@ -590,8 +590,8 @@ dbus_bus_service_exists (DBusConnection *connection, _dbus_return_val_if_fail (service_name != NULL, FALSE); _dbus_return_val_if_error_is_set (error, FALSE); - message = dbus_message_new (DBUS_MESSAGE_SERVICE_EXISTS, - DBUS_SERVICE_DBUS); + message = dbus_message_new_method_call (DBUS_MESSAGE_SERVICE_EXISTS, + DBUS_SERVICE_DBUS); if (message == NULL) { _DBUS_SET_OOM (error); @@ -652,8 +652,8 @@ dbus_bus_activate_service (DBusConnection *connection, DBusMessage *msg; DBusMessage *reply; - msg = dbus_message_new (DBUS_MESSAGE_ACTIVATE_SERVICE, - DBUS_SERVICE_DBUS); + msg = dbus_message_new_method_call (DBUS_MESSAGE_ACTIVATE_SERVICE, + DBUS_SERVICE_DBUS); if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, service_name, DBUS_TYPE_UINT32, flags, DBUS_TYPE_INVALID)) diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 4b72d600..ced50bd1 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -722,7 +722,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport) if (io_path_cond == NULL) goto error; - disconnect_message = dbus_message_new (DBUS_MESSAGE_LOCAL_DISCONNECT, NULL); + disconnect_message = dbus_message_new_signal (DBUS_MESSAGE_LOCAL_DISCONNECT); if (disconnect_message == NULL) goto error; @@ -1615,8 +1615,8 @@ dbus_connection_send_with_reply (DBusConnection *connection, dbus_message_handler_ref (reply_handler); - reply = dbus_message_new_error_reply (message, DBUS_ERROR_NO_REPLY, - "No reply within specified time"); + reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY, + "No reply within specified time"); if (!reply) { CONNECTION_UNLOCK (connection); diff --git a/dbus/dbus-message-builder.c b/dbus/dbus-message-builder.c index 390dda75..fc85fc32 100644 --- a/dbus/dbus-message-builder.c +++ b/dbus/dbus-message-builder.c @@ -393,8 +393,14 @@ _dbus_message_data_load (DBusString *dest, goto parse_failed; } + if (!_dbus_string_append_byte (dest, DBUS_MESSAGE_TYPE_METHOD_CALL)) + { + _dbus_warn ("could not append message type\n"); + goto parse_failed; + } + i = 0; - while (i < 3) + while (i < 2) { if (!_dbus_string_append_byte (dest, '\0')) { diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 52226603..c39ca3b4 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -73,6 +73,11 @@ typedef struct */ } HeaderField; +#define BYTE_ORDER_OFFSET 0 +#define TYPE_OFFSET 1 +#define FLAGS_OFFSET 2 +#define VERSION_OFFSET 3 + /** * @brief Internals of DBusMessage * @@ -803,6 +808,7 @@ _dbus_message_remove_size_counter (DBusMessage *message, static dbus_bool_t dbus_message_create_header (DBusMessage *message, + int type, const char *name, const char *service) { @@ -811,6 +817,9 @@ dbus_message_create_header (DBusMessage *message, if (!_dbus_string_append_byte (&message->header, message->byte_order)) return FALSE; + if (!_dbus_string_append_byte (&message->header, type)) + return FALSE; + flags = 0; if (!_dbus_string_append_byte (&message->header, flags)) return FALSE; @@ -818,9 +827,6 @@ dbus_message_create_header (DBusMessage *message, if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION)) return FALSE; - if (!_dbus_string_append_byte (&message->header, 0)) - return FALSE; - message->header_fields[FIELD_HEADER_LENGTH].offset = 4; if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0)) return FALSE; @@ -944,10 +950,11 @@ dbus_message_new_empty_header (void) /** - * Constructs a new message. Returns #NULL if memory can't be - * allocated for the message. The service may be #NULL in which case - * no service is set; this is appropriate when using D-BUS in a - * peer-to-peer context (no message bus). + * Constructs a new message to invoke a method on a remote + * object. Returns #NULL if memory can't be allocated for the + * message. The service may be #NULL in which case no service is set; + * this is appropriate when using D-BUS in a peer-to-peer context (no + * message bus). * * @param name name of the message * @param destination_service service that the message should be sent to or #NULL @@ -955,8 +962,8 @@ dbus_message_new_empty_header (void) * @see dbus_message_unref() */ DBusMessage* -dbus_message_new (const char *name, - const char *destination_service) +dbus_message_new_method_call (const char *name, + const char *destination_service) { DBusMessage *message; @@ -966,7 +973,9 @@ dbus_message_new (const char *name, if (message == NULL) return NULL; - if (!dbus_message_create_header (message, name, destination_service)) + if (!dbus_message_create_header (message, + DBUS_MESSAGE_TYPE_METHOD_CALL, + name, destination_service)) { dbus_message_unref (message); return NULL; @@ -976,37 +985,43 @@ dbus_message_new (const char *name, } /** - * Constructs a message that is a reply to some other - * message. Returns #NULL if memory can't be allocated - * for the message. + * Constructs a message that is a reply to a method call. Returns + * #NULL if memory can't be allocated for the message. * - * @param original_message the message which the created + * @param method_call the message which the created * message is a reply to. * @returns a new DBusMessage, free with dbus_message_unref() - * @see dbus_message_new(), dbus_message_unref() + * @see dbus_message_new_method_call(), dbus_message_unref() */ DBusMessage* -dbus_message_new_reply (DBusMessage *original_message) +dbus_message_new_method_return (DBusMessage *method_call) { DBusMessage *message; const char *sender, *name; - _dbus_return_val_if_fail (original_message != NULL, NULL); + _dbus_return_val_if_fail (method_call != NULL, NULL); - sender = get_string_field (original_message, + sender = get_string_field (method_call, FIELD_SENDER, NULL); - name = get_string_field (original_message, + name = get_string_field (method_call, FIELD_NAME, NULL); /* sender is allowed to be null here in peer-to-peer case */ - - message = dbus_message_new (name, sender); - + + message = dbus_message_new_empty_header (); if (message == NULL) return NULL; + + if (!dbus_message_create_header (message, + DBUS_MESSAGE_TYPE_METHOD_RETURN, + name, sender)) + { + dbus_message_unref (message); + return NULL; + } if (!dbus_message_set_reply_serial (message, - dbus_message_get_serial (original_message))) + dbus_message_get_serial (method_call))) { dbus_message_unref (message); return NULL; @@ -1016,40 +1031,78 @@ dbus_message_new_reply (DBusMessage *original_message) } /** + * Constructs a new message representing a signal emission. Returns + * #NULL if memory can't be allocated for the message. The name + * passed in is the name of the signal. + * + * @param name name of the signal + * @returns a new DBusMessage, free with dbus_message_unref() + * @see dbus_message_unref() + */ +DBusMessage* +dbus_message_new_signal (const char *name) +{ + DBusMessage *message; + + _dbus_return_val_if_fail (name != NULL, NULL); + + message = dbus_message_new_empty_header (); + if (message == NULL) + return NULL; + + if (!dbus_message_create_header (message, + DBUS_MESSAGE_TYPE_SIGNAL, + name, NULL)) + { + dbus_message_unref (message); + return NULL; + } + + return message; +} + +/** * Creates a new message that is an error reply to a certain message. + * Error replies are possible in response to method calls primarily. * - * @param original_message the original message + * @param reply_to the original message * @param error_name the error name * @param error_message the error message string or #NULL for none * @returns a new error message */ DBusMessage* -dbus_message_new_error_reply (DBusMessage *original_message, - const char *error_name, - const char *error_message) +dbus_message_new_error (DBusMessage *reply_to, + const char *error_name, + const char *error_message) { DBusMessage *message; const char *sender; DBusMessageIter iter; - _dbus_return_val_if_fail (original_message != NULL, NULL); + _dbus_return_val_if_fail (reply_to != NULL, NULL); _dbus_return_val_if_fail (error_name != NULL, NULL); - sender = get_string_field (original_message, + sender = get_string_field (reply_to, FIELD_SENDER, NULL); /* sender may be NULL for non-message-bus case or * when the message bus is dealing with an unregistered * connection. */ - - message = dbus_message_new (error_name, sender); - + message = dbus_message_new_empty_header (); if (message == NULL) return NULL; + + if (!dbus_message_create_header (message, + DBUS_MESSAGE_TYPE_ERROR, + error_name, sender)) + { + dbus_message_unref (message); + return NULL; + } if (!dbus_message_set_reply_serial (message, - dbus_message_get_serial (original_message))) + dbus_message_get_serial (reply_to))) { dbus_message_unref (message); return NULL; @@ -1201,6 +1254,28 @@ dbus_message_unref (DBusMessage *message) } /** + * Gets the type of a message. Types include + * DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_METHOD_RETURN, + * DBUS_MESSAGE_TYPE_ERROR, DBUS_MESSAGE_TYPE_SIGNAL, but other types + * are allowed and all code must silently ignore messages of unknown + * type. DBUS_MESSAGE_TYPE_INVALID will never be returned, however. + * + * + * @param message the message + * @returns the type of the message + */ +int +dbus_message_get_type (DBusMessage *message) +{ + int type; + + type = _dbus_string_get_byte (&message->header, 1); + _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID); + + return type; +} + +/** * Gets the name of a message. * * @param message the message @@ -3704,7 +3779,7 @@ dbus_message_set_is_error (DBusMessage *message, _dbus_return_if_fail (message != NULL); _dbus_return_if_fail (!message->locked); - header = _dbus_string_get_data_len (&message->header, 1, 1); + header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1); if (is_error_reply) *header |= DBUS_HEADER_FLAG_ERROR; @@ -3726,7 +3801,7 @@ dbus_message_get_is_error (DBusMessage *message) _dbus_return_val_if_fail (message != NULL, FALSE); - header = _dbus_string_get_const_data_len (&message->header, 1, 1); + header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1); return (*header & DBUS_HEADER_FLAG_ERROR) != 0; } @@ -4298,6 +4373,9 @@ _dbus_message_loader_return_buffer (DBusMessageLoader *loader, /** * Converts buffered data into messages. * + * @todo we need to check that the proper named header fields exist + * for each message type. + * * @param loader the loader. * @returns #TRUE if we had enough memory to finish. */ @@ -4311,22 +4389,22 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) { DBusMessage *message; const char *header_data; - int byte_order, header_len, body_len, header_padding; + int byte_order, message_type, header_len, body_len, header_padding; dbus_uint32_t header_len_unsigned, body_len_unsigned; header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16); _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data); - if (header_data[2] != DBUS_MAJOR_PROTOCOL_VERSION) + if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION) { _dbus_verbose ("Message has protocol version %d ours is %d\n", - (int) header_data[2], DBUS_MAJOR_PROTOCOL_VERSION); + (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION); loader->corrupted = TRUE; return TRUE; } - byte_order = header_data[0]; + byte_order = header_data[BYTE_ORDER_OFFSET]; if (byte_order != DBUS_LITTLE_ENDIAN && byte_order != DBUS_BIG_ENDIAN) @@ -4337,6 +4415,18 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) return TRUE; } + /* Unknown types are ignored, but INVALID is + * disallowed + */ + message_type = header_data[TYPE_OFFSET]; + if (message_type == DBUS_MESSAGE_TYPE_INVALID) + { + _dbus_verbose ("Message with bad type '%d' received\n", + message_type); + loader->corrupted = TRUE; + return TRUE; + } + header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4); body_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 8); @@ -5821,7 +5911,7 @@ _dbus_message_test (const char *test_data_dir) _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter)); - message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test"); + message = dbus_message_new_method_call ("test.Message", "org.freedesktop.DBus.Test"); _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test")); _dbus_message_set_serial (message, 1234); dbus_message_set_sender (message, "org.foo.bar"); @@ -5840,7 +5930,7 @@ _dbus_message_test (const char *test_data_dir) dbus_message_unref (message); /* Test the vararg functions */ - message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test"); + message = dbus_message_new_method_call ("test.Message", "org.freedesktop.DBus.Test"); _dbus_message_set_serial (message, 1); dbus_message_append_args (message, DBUS_TYPE_INT32, -0x12345678, @@ -5906,7 +5996,7 @@ _dbus_message_test (const char *test_data_dir) dbus_message_unref (message); dbus_message_unref (copy); - message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test"); + message = dbus_message_new_method_call ("test.Message", "org.freedesktop.DBus.Test"); _dbus_message_set_serial (message, 1); dbus_message_set_reply_serial (message, 0x12345678); diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index bd52bd1a..d2c14c78 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -57,17 +57,19 @@ struct DBusMessageIter void *pad3; }; +DBusMessage* dbus_message_new_method_call (const char *name, + const char *destination_service); +DBusMessage* dbus_message_new_method_return (DBusMessage *method_call); +DBusMessage* dbus_message_new_signal (const char *name); +DBusMessage* dbus_message_new_error (DBusMessage *reply_to, + const char *error_name, + const char *error_message); -DBusMessage* dbus_message_new (const char *name, - const char *destination_service); -DBusMessage* dbus_message_new_reply (DBusMessage *original_message); -DBusMessage* dbus_message_new_error_reply (DBusMessage *original_message, - const char *error_name, - const char *error_message); -DBusMessage *dbus_message_copy (const DBusMessage *message); +DBusMessage *dbus_message_copy (const DBusMessage *message); void dbus_message_ref (DBusMessage *message); void dbus_message_unref (DBusMessage *message); +int dbus_message_get_type (DBusMessage *message); const char* dbus_message_get_name (DBusMessage *message); const char* dbus_message_get_destination (DBusMessage *message); dbus_bool_t dbus_message_set_sender (DBusMessage *message, diff --git a/dbus/dbus-object-registry.c b/dbus/dbus-object-registry.c index a550f8e2..a4d92216 100644 --- a/dbus/dbus-object-registry.c +++ b/dbus/dbus-object-registry.c @@ -24,6 +24,7 @@ #include "dbus-connection-internal.h" #include "dbus-internals.h" #include "dbus-hash.h" +#include "dbus-protocol.h" #include <string.h> /** @@ -599,12 +600,64 @@ _dbus_object_registry_remove_and_unlock (DBusObjectRegistry *registry, (* vtable->unregistered) (&info); } +/** + * Handle a message, passing it to any objects in the registry that + * should receive it. + * + * @todo handle messages to an object ID, not just those to + * an interface name. + * + * @param registry the object registry + * @param message the message to handle + * @returns what to do with the message next + */ DBusHandlerResult _dbus_object_registry_handle_and_unlock (DBusObjectRegistry *registry, DBusMessage *message) { - /* FIXME */ - return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + DBusInterfaceEntry *iface_entry; + DBusObjectEntry *object_entry; + DBusObjectInfo info; + const DBusObjectVTable *vtable; + + _dbus_assert (registry != NULL); + _dbus_assert (message != NULL); + + if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL) + return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + + /* If the message isn't to a specific object ID, we send + * it to the first object that supports the given interface. + */ + iface_entry = lookup_interface (registry, + dbus_message_get_name (message), + FALSE); + + if (iface_entry == NULL) + return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + + _dbus_assert (iface_entry->n_objects > 0); + _dbus_assert (iface_entry->objects != NULL); + + object_entry = ®istry->entries[iface_entry->objects[0]]; + + + /* Once we have an object entry, pass message to the object */ + + _dbus_assert (object_entry->vtable != NULL); + + info_from_entry (registry, &info, object_entry); + vtable = object_entry->vtable; + + /* Drop lock and invoke application code */ +#ifdef DBUS_BUILD_TESTS + if (registry->connection) +#endif + _dbus_connection_unlock (registry->connection); + + (* vtable->message) (&info, message); + + return DBUS_HANDLER_RESULT_REMOVE_MESSAGE; } void @@ -665,6 +718,7 @@ add_and_remove_objects (DBusObjectRegistry *registry) "org.freedesktop.Test.Foo", NULL }; int i; + DBusMessage *message; i = 0; while (i < N_OBJECTS) @@ -761,6 +815,33 @@ add_and_remove_objects (DBusObjectRegistry *registry) ++i; } + message = dbus_message_new_method_call ("org.freedesktop.Test.Foo", NULL); + if (message != NULL) + { + if (_dbus_object_registry_handle_and_unlock (registry, message) != + DBUS_HANDLER_RESULT_REMOVE_MESSAGE) + _dbus_assert_not_reached ("message not handled\n"); + dbus_message_unref (message); + } + + message = dbus_message_new_method_call ("org.freedesktop.Test.Blah", NULL); + if (message != NULL) + { + if (_dbus_object_registry_handle_and_unlock (registry, message) != + DBUS_HANDLER_RESULT_REMOVE_MESSAGE) + _dbus_assert_not_reached ("message not handled\n"); + dbus_message_unref (message); + } + + message = dbus_message_new_method_call ("org.freedesktop.Test.NotRegisteredIface", NULL); + if (message != NULL) + { + if (_dbus_object_registry_handle_and_unlock (registry, message) != + DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS) + _dbus_assert_not_reached ("message handled but no handler was registered\n"); + dbus_message_unref (message); + } + i = 0; while (i < (N_OBJECTS - 30)) { diff --git a/dbus/dbus-object.c b/dbus/dbus-object.c index c3f1536d..5582f94a 100644 --- a/dbus/dbus-object.c +++ b/dbus/dbus-object.c @@ -273,6 +273,10 @@ dbus_callback_object_set_data (DBusCallbackObject *callback, * Sets the function to be used to handle messages to the * callback object. * + * @todo the thread locking on DBusCallbackObject is hosed; in this + * function in particular it's a joke since we don't take the same + * lock when _calling_ the callback function. + * * @param callback the callback * @param function the function */ @@ -287,7 +291,6 @@ dbus_callback_object_set_function (DBusCallbackObject *callback, _DBUS_UNLOCK (callback_object); } - /** @} */ #ifdef DBUS_BUILD_TESTS diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h index 04988862..dcb7a042 100644 --- a/dbus/dbus-protocol.h +++ b/dbus/dbus-protocol.h @@ -61,6 +61,7 @@ extern "C" { #define DBUS_MAXIMUM_NAME_LENGTH 256 /* Types of message */ +#define DBUS_MESSAGE_TYPE_INVALID 0 #define DBUS_MESSAGE_TYPE_METHOD_CALL 1 #define DBUS_MESSAGE_TYPE_METHOD_RETURN 2 #define DBUS_MESSAGE_TYPE_ERROR 3 diff --git a/doc/dbus-specification.sgml b/doc/dbus-specification.sgml index 68a71cec..a53be53d 100644 --- a/doc/dbus-specification.sgml +++ b/doc/dbus-specification.sgml @@ -135,6 +135,12 @@ </row> <row> <entry>1 byte</entry> + <entry>Type of message. Unknown types MUST be ignored. + Currently-defined types are described below. + </entry> + </row> + <row> + <entry>1 byte</entry> <entry>Bitwise OR of flags. Unknown flags MUST be ignored. Currently-defined flags are described below. </entry> @@ -149,12 +155,6 @@ </entry> </row> <row> - <entry>1 byte</entry> - <entry>A nul byte, reserved for future use. - Any value for this byte MUST be accepted. - </entry> - </row> - <row> <entry>4 bytes</entry> <entry>An unsigned 32-bit integer in the message's byte order, indicating the total length in bytes of @@ -182,7 +182,44 @@ </informaltable> </para> <para> - Flags that can appear in the second byte of the header: + Types that can appear in the second byte of the header: + <informaltable> + <tgroup cols=2> + <thead> + <row> + <entry>Decimal value</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>This is an invalid type, if seen in a message + the connection should be dropped immediately.</entry> + </row> + <row> + <entry>1</entry> + <entry>Method call.</entry> + </row> + </row> + <row> + <entry>2</entry> + <entry>Method reply with returned data.</entry> + </row> + <row> + <entry>3</entry> + <entry>Error.</entry> + </row> + <row> + <entry>4</entry> + <entry>Signal emission.</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + Flags that can appear in the third byte of the header: <informaltable> <tgroup cols=2> <thead> @@ -196,6 +233,13 @@ <entry>0x1</entry> <entry>This message is an error reply. If the first argument exists and is a string, it is an error message.</entry> </row> + <row> + <entry>0x2</entry> + <entry>This message does not expect method return replies or + error replies; the reply can be omitted as an + optimization. However, it is compliant with this specification + to return the reply despite this flag.</entry> + </row> </tbody> </tgroup> </informaltable> diff --git a/test/data/invalid-messages/bad-endian.message b/test/data/invalid-messages/bad-endian.message index 7a7b75d1..b1432359 100644 --- a/test/data/invalid-messages/bad-endian.message +++ b/test/data/invalid-messages/bad-endian.message @@ -1,7 +1,7 @@ ## message with invalid endianness tag BYTE 'i' -BYTE 0 +BYTE 1 BYTE 0 BYTE 0 LENGTH Header diff --git a/test/data/valid-messages/simplest-manual.message b/test/data/valid-messages/simplest-manual.message index 8eed1e5f..f0ecccdd 100644 --- a/test/data/valid-messages/simplest-manual.message +++ b/test/data/valid-messages/simplest-manual.message @@ -3,7 +3,7 @@ LITTLE_ENDIAN BYTE 'l' -BYTE 0 +BYTE 1 BYTE 0 BYTE 0 LENGTH Header |