5 Link-Specific Interfaces 7 Link Components
Link Library Programming Guide  / 

6 Communication Interfaces

The link model needs to define a structure that represents all kinds of messages that can be sent over the link. This structure should “inherit” from link_message_t, by placing it first in the struct (so that a pointer to a datagram_link_message_t can be cast to a link_message_t pointer).

typedef struct {
        link_message_t common;               /* should always be first */
        /* The actual data in the message - in our case an allocated
           byte string owned by this structure. */
        bytes_t payload;
} datagram_link_message_t;

New messages are allocated with MM_MALLOC(), and SIMLINK_init_message() is used to fill in the “common” part:

static link_message_t *
new_datagram_message(const uint8 *data, size_t len)
{
        datagram_link_message_t *m = MM_MALLOC(1, datagram_link_message_t);
        SIMLINK_init_message(&m->common);
        uint8 *d = MM_MALLOC(len, uint8);
        memcpy(d, data, len);
        m->payload = (bytes_t){.data = d, .len = len};
        return &m->common;
}

Finally, the message is dispatched using the SIMLINK_send_message() or SIMLINK_send_message_multi() functions.

static void
receive(conf_object_t *NOTNULL ep, bytes_t msg)
{
        SIMLINK_send_message(ep, LINK_BROADCAST_ID,
                             new_datagram_message(msg.data, msg.len));
}

Messages are delivered to the endpoints’ deliver() callback registered by the link. The callback is responsible for translating the message into something the receiving device will understand.

static void
deliver(conf_object_t *ep, const link_message_t *lm)
{
        const datagram_link_message_t *m =
                (const datagram_link_message_t *)lm;
        conf_object_t *dev = SIMLINK_endpoint_device(ep);
        const char *port = SIMLINK_endpoint_port(ep);
        const datagram_link_interface_t *dli =
                SIM_c_get_port_interface(dev, "datagram_link", port);
        if (dli)
                dli->receive(dev, m->payload);
        else
                SIM_LOG_ERROR(ep, 0, "Device does not implement"
                              " datagram_link interface");
}
5 Link-Specific Interfaces 7 Link Components