summaryrefslogtreecommitdiff
path: root/cesar/host/sci.h
blob: 823a76034e44f441dfea33d0bfbe42ebb2f332f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#ifndef SCI_H_
#define SCI_H_

/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
 
 /**
 * \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_*/