#ifndef SCI_H_ #define SCI_H_ /* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file sci.h * \brief The sci comm. layer structures for fulminata. * \ingroup host * * This file descibe the content of sci structures used by fulminata sci layer * * \todo */ #include "maximus/common/types/sci_types.h" #include "host/fwd.h" #include "host/station.h" #include "host/netclock.h" #include "host/fcall.h" #include "host/system.h" struct station_ctx; struct netclock_msg_hdr; struct fcall_msg_hdr; struct station_msg_hdr; struct phy_msg_hdr; struct ether_msg_hdr; /** common sci message header */ #define sci_msg_hdr Sci_Msg_Header typedef struct sci_msg_hdr sci_msg_hdr_t; /** type of sci message; used by sci msg header */ typedef enum Sci_Msg_Type sci_msg_type_t; /** sci message ID */ typedef int sci_msg_id_t; /** sci buffer structure */ struct sci_msg { struct sci_msg_hdr *sci_hdr; /** pointer to sci header */ union { struct netclock_msg_hdr *netclock; struct fcall_msg_hdr *fcall; struct station_msg_hdr *station; struct phy_msg_hdr *phy; struct ether_msg_hdr *ether; void *generic; } hdr; /** pointer to msg subtype header */ unsigned char *data; /** data buffer */ unsigned char *data_begin; /** start of payload inside buffer */ unsigned char *data_end; /** end of payload */ int length; /** total length msg */ int max_size; /** maximum size of data buffer */ }; //#define netclock_hdr s1._netclock_hdr //#define fcall_hdr s1._fcall_hdr //#define station_hdr s1._station_hdr //#define generic_hdr s1._generic_hdr /** sci callback structure */ struct sci_callback { int (*function)(struct sci_msg *msg, void *data); void *data; }; /** sci layer context */ struct sci_ctx { struct station_ctx *station; /** currently used station context */ struct sci_callback msg_callback[SCI_MSG_TYPE_NB]; /** table of all callback functions */ int current_msg_id; }; //BEGIN_DECLS /** * create a new sci message. * \param size max size of message * \return the new sci msg, NULL if failed, with errno * - EINVAL is size < sizeof(sci_msg_hdr_t) or > SCI_MSG_MAX_SIZE */ sci_msg_t *sci_msg_new(int max_size); /** * sci message destruction with memory freeing. * \param msg msg context to destroy */ void sci_msg_free(sci_msg_t *msg); /** * sci message init if a static msg structure is used (instead of dynamic). * \param msg pointer to msg context to initialize * \param buffer pointer to a data buffer with allocated space * \param max_size buffer max size * \return 0 if ok, -1 if failed with errno= * - EINVAL if msg of buffer is NULL, or if size is < sizeof(sci_msg_hdr_t) or >= SCI_MSG_MAX_SIZE */ int sci_msg_init(sci_msg_t *msg, unsigned char *buffer, int max_size); /** * sci message adding of new data with pointers update. * \param msg msg where to add data * \param length length of data to add * \return length if ok, -1 if failed with errno= * - EINVAL if msg is NULL * - ENOSPC if length is bigger than free space into buffer */ int sci_msg_push(sci_msg_t *msg, int length); /** * sci message removing of data with pointers update. * \param msg msg where to remove data * \param length length of data to remove * \return number of bytes stored, -1 if failed with errno= * - EINVAL if msg or data is NULL */ int sci_msg_pop(sci_msg_t *msg, int length); /** * sci context, called during station context creation. * \param station station which uses the sci context * \return the new sci context, NULL if station is NULL */ sci_ctx_t *sci_new(struct station_ctx *station); /** * sci context destruction with memory freeing. * \param sci sci context to destroy */ void sci_free(sci_ctx_t *sci); /** * initialize a static sci context, called during station context creation. * \param sci sci context to initialize * \param station station which uses the sci context * \return 0 if ok, -1 if failed with errno= * - EINVAL if sci or station is NULL */ int sci_init(sci_ctx_t *sci, struct station_ctx *station); /** * register a callback function to process a message * \param sci current sci context * \param type message type index * \param function pointer to the callback function to process the received message * \param data user data to be included into callback function as 'data' parameter * \return 0 if ok, -1 if failed with errno: * - EINVAL if sci is null or type is wrong */ int sci_register_callback( sci_ctx_t *sci, sci_msg_type_t type, int(*function)(sci_msg_t *msg, void *data), void *data); /** * fill a blank sci header with needed msg type and length * a sci_msg_push() is used to get free space to store the header inside message * \param sci current sci context * \param msg sci message to fill header * \param type type of message * \param flags flags of message * \return 0 if ok, -1 if failed with errno: * - EINVAL if sci or msg are NULL, or if type or length are out of range * - ENOSPC if there is no space left for sci header */ int sci_fill_hdr( sci_ctx_t *sci, sci_msg_t *msg, sci_msg_type_t type, int flags); /** * sends a sci message to output pipe * \param sci current sci context * \param msg sci message to send to the pipe * \return length of sent data, -1 if failed with errno: * - EINVAL if sci or msg are NULL * - all errno generated by write() sys call */ int sci_send(sci_ctx_t *sci, sci_msg_t *msg); /** * receive a sci message from input pipe and process the registred callback * \param sci current sci context * \return 0 if ok, -1 if failed with errno: * - EINVAL if sci is NULL * - ENOSPC if msg length is > SCI_MSG_MAX_SIZE * - all errno generated by read() sys call */ int sci_recv(sci_ctx_t *sci); void sci_msg_dump(sci_msg_t *msg, int fd, char *buffer, int size); //END_DECLS #endif /*SCI_H_*/