+XBT_PUBLIC(void) gras_msgtype_declare(const char *name,
+ gras_datadesc_type_t payload);
+XBT_PUBLIC(void) gras_msgtype_declare_v(const char *name,
+ short int version,
+ gras_datadesc_type_t payload);
+
+XBT_PUBLIC(gras_msgtype_t) gras_msgtype_by_name(const char *name);
+XBT_PUBLIC(gras_msgtype_t) gras_msgtype_by_name_or_null(const char *name);
+XBT_PUBLIC(gras_msgtype_t) gras_msgtype_by_namev(const char *name,
+ short int version);
+XBT_PUBLIC(gras_msgtype_t) gras_msgtype_by_id(int id);
+XBT_PUBLIC(const char *) gras_msgtype_get_name(gras_msgtype_t type);
+
+XBT_PUBLIC(void) gras_msgtype_dumpall(void);
+
+
+/** @} */
+/** @defgroup GRAS_msg_cb Callback declaration and use
+ * @ingroup GRAS_msg
+ *
+ *
+ * This is how to register a given function so that it gets called when a
+ * given type of message arrives.
+ *
+ * You can register several callbacks to the same kind of messages, and
+ * they will get stacked. The lastly added callback gets the message first.
+ * If it consumes the message, it should return a true value when done. If
+ * not, it should return 0, and the message will be passed to the second
+ * callback of the stack, if any.
+ *
+ * @{
+ */
+
+ /** \brief Context of callbacks (opaque structure, created by the middleware only, never by user) */
+typedef struct s_gras_msg_cb_ctx *gras_msg_cb_ctx_t;
+
+XBT_PUBLIC(void) gras_msg_cb_ctx_free(gras_msg_cb_ctx_t ctx);
+XBT_PUBLIC(gras_socket_t) gras_msg_cb_ctx_from(gras_msg_cb_ctx_t ctx);
+
+ /** \brief Type of message callback functions.
+ *
+ * \param expeditor: a socket to contact who sent this message
+ * \param payload: the message itself
+ *
+ * \return true if the message was consumed by the callback,
+ * false if the message was refused by the callback (and should be
+ * passed to the next callback of the stack for this message)
+ *
+ * Once a such a function is registered to handle messages of a given
+ * type with \ref gras_cb_register(), it will be called each time such
+ * a message arrives (unless a gras_msg_wait() intercepts it on arrival).
+ *
+ * If the callback accepts the message, it should free it after use.
+ */
+typedef int (*gras_msg_cb_t) (gras_msg_cb_ctx_t ctx, void *payload);
+
+ /**
+ * @brief Bind the given callback to the given message type (described by its name)
+ * @hideinitializer
+ *
+ * Several callbacks can be attached to a given message type. The lastly added one will get the message first, and
+ * if it returns a non-null value, the message will be passed to the second one.
+ * And so on until one of the callbacks accepts the message.
+ *
+ * Using gras_cb_register is a bit slower than using gras_cb_register_ since GRAS
+ * has to search for the given msgtype in the hash table, but you don't care in most case.
+ */
+#define gras_cb_register(msgtype_name, cb) gras_cb_register_(gras_msgtype_by_name(msgtype_name),cb)
+
+ /**
+ * @brief Unbind the given callback to the given message type (described by its name)
+ * @hideinitializer
+ *
+ * Using gras_cb_unregister is a bit slower than using gras_cb_unregister_ since GRAS
+ * has to search for the given msgtype in the hash table, but you don't care in most case.
+ */
+#define gras_cb_unregister(msgtype_name, cb) gras_cb_unregister_(gras_msgtype_by_name(msgtype_name),cb)
+
+XBT_PUBLIC(void) gras_cb_register_(gras_msgtype_t msgtype,
+ gras_msg_cb_t cb);
+XBT_PUBLIC(void) gras_cb_unregister_(gras_msgtype_t msgtype,
+ gras_msg_cb_t cb);
+
+/** @} */
+
+/** @defgroup GRAS_msg_exchange Message exchange
+ * @ingroup GRAS_msg
+ *
+ */
+/** @{ */
+
+/** \brief Send the data pointed by \a payload as a message \a msgname on the \a sock
+ * @hideinitializer
+ *
+ * Using gras_msg_wait() is a bit slower than using gras_msg_wait_() since GRAS
+ * has to search for the given msgtype in the hash table.
+ */
+#define gras_msg_send(sock,name,payload) gras_msg_send_(sock,gras_msgtype_by_name(name),payload)
+XBT_PUBLIC(void) gras_msg_send_(gras_socket_t sock,
+ gras_msgtype_t msgtype, void *payload);
+
+/** \brief Waits for a message to come in over a given socket
+ * @hideinitializer
+ * @param timeout: How long should we wait for this message.
+ * @param msgt_want: type of awaited msg
+ * @param[out] expeditor: where to create a socket to answer the incomming message
+ * @param[out] payload: where to write the payload of the incomming message
+ * @return the error code (or no_error).
+ *
+ * Every message of another type received before the one waited will be queued
+ * and used by subsequent call to this function or gras_msg_handle().
+ *
+ * Using gras_msg_wait() is a bit slower than using gras_msg_wait_() since GRAS
+ * has to search for the given msgtype in the hash table.
+ */