## prelude-msg

prelude-msg — Prelude Messaging API

## Synopsis

    typedef     prelude_msg_t;
    enum        prelude_msg_priority_t;
    int         prelude_msg_read                (prelude_msg_t **msg,
                                                 prelude_io_t *pio);
    int         prelude_msg_forward             (prelude_msg_t *msg,
                                                 prelude_io_t *dst,
                                                 prelude_io_t *src);
    int         prelude_msg_get                 (prelude_msg_t *msg,
                                                 uint8_t *tag,
                                                 uint32_t *len,
                                                 void **buf);
    void        prelude_msg_recycle             (prelude_msg_t *msg);
    void        prelude_msg_mark_end            (prelude_msg_t *msg);
    int         prelude_msg_dynamic_new         (prelude_msg_t **ret,
                                                 int (*flush_msg_cb) (prelude_msg_t **msg, void *data),
                                                 void *data);
    int         prelude_msg_new                 (prelude_msg_t **ret,
                                                 size_t msgcount,
                                                 size_t msglen,
                                                 uint8_t tag,
                                                 prelude_msg_priority_t priority);
    int         prelude_msg_set                 (prelude_msg_t *msg,
                                                 uint8_t tag,
                                                 uint32_t len,
                                                 const void *data);
    int         prelude_msg_write               (prelude_msg_t *msg,
                                                 prelude_io_t *dst);
    void        prelude_msg_set_tag             (prelude_msg_t *msg,
                                                 uint8_t tag);
    void        prelude_msg_set_priority        (prelude_msg_t *msg,
                                                 prelude_msg_priority_t priority);
    uint8_t     prelude_msg_get_tag             (prelude_msg_t *msg);
    prelude_msg_priority_t prelude_msg_get_priority
                                                (prelude_msg_t *msg);
    uint32_t    prelude_msg_get_len             (prelude_msg_t *msg);
    uint32_t    prelude_msg_get_datalen         (prelude_msg_t *msg);

## Description

This Mesaging API is used for differents Prelude program to communicate together. It feature compatibility between version, and use a way to describe data similar to XML.

The Message header contain the protocol version, which is only to be used in case the main protocol structure change (compatibility break), The tag describe the kind of message, The fragment field may be used if a message is sent in several time, The priority may be used by the receiving end to priorityze task, The datalen contain the size of the whole message in network byte order

       8bits    8bits   8bits     8bits                32bits
    +--------+--------+--------+----------+------------------------------+
    |version |   tag  |priority| fragment |            datalen           |
    +--------+--------+--------+----------+------------------------------+

Then the message itself contain submessage composed of : A tag describing the kind of payload, the len of the payload (in network byte order), the payload itself, and an end of message byte (0xff) in order to resynchronize in case of problem.

      8bits              32bits                                   8bits
    +--------+--------------------------------+-----------------+--------+
    |  tag   |             len                |     payload     |  0xff  |
    +--------+--------------------------------+-----------------+--------+

## Details

### prelude_msg_t

    typedef struct prelude_msg prelude_msg_t;

### enum prelude_msg_priority_t

    typedef enum {
            PRELUDE_MSG_PRIORITY_NONE = 0,
            PRELUDE_MSG_PRIORITY_LOW  = 1,
            PRELUDE_MSG_PRIORITY_MID  = 2,
            PRELUDE_MSG_PRIORITY_HIGH = 3
    } prelude_msg_priority_t;

### prelude_msg_read ()

    int         prelude_msg_read                (prelude_msg_t **msg,
                                                 prelude_io_t *pio);

Read a message on `pio` into `msg`. If `msg` is NULL, it is allocated. This function will never block.

`msg` : | Pointer on a prelude_msg_t object address.
`pio` : | Pointer on a prelude_io_t object.
Returns : | 0 if reading the message is complete, or a prelude_error_t error if an error occured. Take particular attention to PRELUDE_ERROR_EAGAIN and PRELUDE_ERROR_EOF.

### prelude_msg_forward ()

    int         prelude_msg_forward             (prelude_msg_t *msg,
                                                 prelude_io_t *dst,
                                                 prelude_io_t *src);

`prelude_msg_forward()` read the message corresponding to the `msg` object containing the message header previously gathered using `prelude_msg_read_header()` from the `src` object, and transfer it to `dst`. The header is also transfered.

`msg` : | Pointer on a prelude_msg_t object containing a message header.
`dst` : | Pointer on a prelude_io_t object to send message to.
`src` : | Pointer on a prelude_io_t object to read message from.
Returns : | 0 on success, or a negative value if an error occured.

### prelude_msg_get ()

    int         prelude_msg_get                 (prelude_msg_t *msg,
                                                 uint8_t *tag,
                                                 uint32_t *len,
                                                 void **buf);

`prelude_msg_get()` read the next data chunk contained in the message. `tag` is updated to contain the kind of data the chunk contain. `len` is updated to contain the len of the data chunk. `buf` is updated to point on the data chunk.

`msg` : | Pointer on a prelude_msg_t object representing the message to get data from.
`tag` : | Pointer on a 8 bits unsigned integer to store the message tag.
`len` : | Pointer on a 32 bits unsigned integer to store the message len to.
`buf` : | Address of a pointer to store the buffer starting address.
Returns : | 0 on success, or a prelude_error_t value on error.

### prelude_msg_recycle ()

    void        prelude_msg_recycle             (prelude_msg_t *msg);

Recycle `msg` so you can write at it again, even thought it was written.

`msg` : | Pointer on prelude_msg_t object.

### prelude_msg_mark_end ()

    void        prelude_msg_mark_end            (prelude_msg_t *msg);

Mark end of message in the `msg` buffer, so you can continue adding different message in the same buffer.

`msg` : | Pointer on prelude_msg_t object.

### prelude_msg_dynamic_new ()

    int         prelude_msg_dynamic_new         (prelude_msg_t **ret,
                                                 int (*flush_msg_cb) (prelude_msg_t **msg, void *data),
                                                 void *data);

Allocate a new prelude_msg_t object. `prelude_msg_set()` can then be used to add chunk of data to the message, and `prelude_msg_mark_start()` to separate different message in the same buffer.

This function use memory chunk of static size to store the message in. If the size of the data you want to store is bigger than the actual chunk size, `flush_msg_cb` callback will be called for the current message to be flushed, and the returned message will be used in order to store remaining data.

`ret` : | Pointer where to store the create prelude_msg_t.
`flush_msg_cb` : | Callback function to call when the buffer need to be flushed.
`data` : | Data to pass to the `flush_msg_cb` callback function.
Returns : | 0 on success, a negative value if an error occured.

### prelude_msg_new ()

    int         prelude_msg_new                 (prelude_msg_t **ret,
                                                 size_t msgcount,
                                                 size_t msglen,
                                                 uint8_t tag,
                                                 prelude_msg_priority_t priority);

Allocate a new prelude_msg_t object and store it into `ret`. `prelude_msg_set()` can then be used to add chunk of data to the message, and `prelude_msg_write()` to send it.

`ret` : | Pointer where to store the created prelude_msg_t.
`msgcount` : | Number of chunk of data the created object can accept.
`msglen` : | Maximum number of bytes the object should handle for all the chunks.
`tag` : | A tag identifying the kind of message.
`priority` : | The priority of this message.
Returns : | 0 on success, a negative value if an error occured.

### prelude_msg_set ()

    int         prelude_msg_set                 (prelude_msg_t *msg,
                                                 uint8_t tag,
                                                 uint32_t len,
                                                 const void *data);

`prelude_msg_set()` append `len` bytes of data from the `data` buffer to the `msg` object representing a message. The data is tagged with `tag`.

`msg` : | Pointer on a prelude_msg_t object to store the data to.
`tag` : | 8 bits unsigned integer describing the kind of data.
`len` : | len of the data chunk.
`data` : | Pointer to the starting address of the data.
Returns : | 0 on success, or a negative value if the remaining space is not available. You might check the return value mostly if using a dynamic message through `prelude_msg_dynamic_new()`

### prelude_msg_write ()

    int         prelude_msg_write               (prelude_msg_t *msg,
                                                 prelude_io_t *dst);

`prelude_msg_write()` write the message corresponding to the `msg` object to `dst`. The message should have been created using the `prelude_msg_new()` and `prelude_msg_set()` functions.

`msg` : | Pointer on a prelude_msg_t object containing the message.
`dst` : | Pointer on a prelude_io_t object to send the message to.
Returns : | 0 on success, or a negative value if an error occured.

### prelude_msg_set_tag ()

    void        prelude_msg_set_tag             (prelude_msg_t *msg,
                                                 uint8_t tag);

Tag `msg`.

`msg` : | Pointer on a prelude_msg_t object.
`tag` : | Tag to associate with `msg`.

### prelude_msg_set_priority ()

    void        prelude_msg_set_priority        (prelude_msg_t *msg,
                                                 prelude_msg_priority_t priority);

Associate `priority` with `msg`.

`msg` : | Pointer on a prelude_msg_t object.
`priority` : | Priority to associate with `msg`.

### prelude_msg_get_tag ()

    uint8_t     prelude_msg_get_tag             (prelude_msg_t *msg);

`prelude_msg_get_tag()` return the tag contained in the `msg` header.

`msg` : | Pointer on a prelude_msg_t object.
Returns : | A tag.

### prelude_msg_get_priority ()

    prelude_msg_priority_t prelude_msg_get_priority
                                                (prelude_msg_t *msg);

`prelude_msg_get_priority()` return the priority contained in the `msg` header.

`msg` : | Pointer on a prelude_msg_t object.
Returns : | A priority.

### prelude_msg_get_len ()

    uint32_t    prelude_msg_get_len             (prelude_msg_t *msg);

`prelude_msg_get_len()` return the currently used len for the `msg` message.

`msg` : | Pointer on a prelude_msg_t object.
Returns : | Len of the message.

### prelude_msg_get_datalen ()

    uint32_t    prelude_msg_get_datalen         (prelude_msg_t *msg);

`prelude_msg_get_datalen()` return the len of the whole message contained in the `msg` header.

`msg` : | Pointer on a prelude_msg_t object.
Returns : | Len of the message.

## See Also

prelude-msgbuf