2003-08-01 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Sat, 2 Aug 2003 03:39:35 +0000 (03:39 +0000)
committerHavoc Pennington <hp@redhat.com>
Sat, 2 Aug 2003 03:39:35 +0000 (03:39 +0000)
* 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

12 files changed:
ChangeLog
dbus/dbus-bus.c
dbus/dbus-connection.c
dbus/dbus-message-builder.c
dbus/dbus-message.c
dbus/dbus-message.h
dbus/dbus-object-registry.c
dbus/dbus-object.c
dbus/dbus-protocol.h
doc/dbus-specification.sgml
test/data/invalid-messages/bad-endian.message
test/data/valid-messages/simplest-manual.message

index e7daf2b..2e96182 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 
index 6ab1ecc..214978d 100644 (file)
@@ -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))
index 4b72d60..ced50bd 100644 (file)
@@ -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);
index 390dda7..fc85fc3 100644 (file)
@@ -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'))
                 {
index 5222660..c39ca3b 100644 (file)
@@ -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);
 
index bd52bd1..d2c14c7 100644 (file)
@@ -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,
index a550f8e..a4d9221 100644 (file)
@@ -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 = &registry->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))
     {
index c3f1536..5582f94 100644 (file)
@@ -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
index 0498886..dcb7a04 100644 (file)
@@ -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
index 68a71ce..a53be53 100644 (file)
               </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>
                 </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
         </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>
                 <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>
index 7a7b75d..b143235 100644 (file)
@@ -1,7 +1,7 @@
 ## message with invalid endianness tag
 
 BYTE 'i'
-BYTE 0
+BYTE 1
 BYTE 0
 BYTE 0
 LENGTH Header