summaryrefslogtreecommitdiff
path: root/cesar/host/station/station.h
blob: 8c6fd11c3e0d1dcb14978112feb9c237b07c8797 (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
210
211
212
213
214
215
216
217
#ifndef STATION_H_
#define STATION_H_

/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */

/**
 * \file    station.h
 * \brief   The station structures for fulminata.
 * \ingroup host
 *
 * This file descibe the content of station structure used by fulminata station
 *
 * \todo
 */

#include <sys/types.h>
#include "maximus/common/types/system_types.h"
#include "host/config.h"
#include "host/fwd.h"
#include "host/sci/sci.h"
#include "host/netclock/netclock.h"
#include "host/fcall/fcall.h"
#include "host/system/system.h"

#define STATION_PIPE_PATH "/tmp"
#define STATION_PIPE_PREFIX "station"
#define STATION_SOCK_PATH STATION_PIPE_PATH
#define STATION_SOCK_PREFIX STATION_PIPE_PREFIX
#define STATION_MAX_LOG_SIZE 4096
#define STATION_MAX_LOG_MSG " [...] <WARNING> Log exceeds max size"
#define STATION_MAX_SOCK_BUFFER_SIZE (256*1024)
#define STATION_MAX_FD 16

#define TICK_PERIOD_NS 40 /** period of a tick in nanosecond */
#define TICK_HZ 25000000 /** frequence of tick (tick number per second) */

#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif

struct sci_ctx;
struct netclock_ctx;
struct fcall_ctx;
struct probe_ctx;
struct system_ctx;
struct netclock_callback_t;

typedef enum {
    STATION_STATUS_INIT = 0,
    STATION_STATUS_RUNNING,
    STATION_STATUS_IDLE,
    STATION_STATUS_ERROR,
    STATION_STATUS_NB
} station_status_t;

typedef enum
{
    STATION_LOG_NONE,
    STATION_LOG_ERROR,
    STATION_LOG_WARNING,
    STATION_LOG_NOTICE,
    STATION_LOG_INFO,
    STATION_LOG_DEBUG,
    STATION_LOG_NB
} station_log_level_t;

#define STATION_LOGTYPE_STATION     0x00000001
#define STATION_LOGTYPE_NETCLOCK    0x00000002
#define STATION_LOGTYPE_FCALL       0x00000004
#define STATION_LOGTYPE_SCI         0x00000008
#define STATION_LOGTYPE_PROBE       0x00000010
#define STATION_LOGTYPE_MISC        0x00000020
#define STATION_LOGTYPE_PHY         0x00000040
#define STATION_LOGTYPE_ETHER       0x00000080
#define STATION_LOGTYPE_LEON_TIMER  0x00000100
#define STATION_LOGTYPE_ALL         0xffffffff

/** station context structure to manage a station process */
struct station_ctx
{
    station_status_t status; /** init status of station */
    pid_t id; /** station identifier (pid process) */
    struct sci_ctx *sci;
    struct netclock_ctx *netclock;
    struct fcall_ctx *fcall;
    struct probe_ctx *probe;
    struct system_ctx *system;
    tick_t current_tick_tck; /** current global clock tick got from sci msg */
    u32 seed; /** station seed (may be needed for cesar initialization) */
#ifdef STATION_SOCK
    int sock_fd; /** file descriptor for messaging input/output */
    int sock_pair_fd; /** file descriptor for socket pair, used by unit test */
    char sock_name[MAXPATHLEN]; /** filename of messaging input/output */
#else /* STATION_SOCK */
    int pipe_in_fd; /** file descriptor for messaging input pipe */
    char pipe_in_name[MAXPATHLEN]; /** filename of messaging input file */
    int pipe_out_fd; /** file descriptor for messaging output pipe */
    char pipe_out_name[MAXPATHLEN]; /** filename of messaging output pipe */
#endif /* STATION_SOCK */
    int pipe_log_fd; /** output pipe file desc to send debug data */
    char pipe_log_name[MAXPATHLEN]; /** output pipe filename to send debug data */
    station_log_level_t log_level;
    unsigned long log_mask;
    struct netclock_callback *ecos_tick_cb;
    //int is_unit_test;
};

//BEGIN_DECLS

extern station_ctx_t my_station;

/**
 * station creation, issued from the fulminata process creation.
 * \return the new created station context, NULL if problem with errno generated by open() call
 */
station_ctx_t *station_new(void);

/**
 * station destruction with memory freeing.
 * \param station station context to destroy
 */
void station_free(station_ctx_t *station);

/**
 * station context initialization, with pipe opening
 * \param station pointer to station context to initialize
 * \return 0 if ok, -1 if failed with errno=
 * - EINVAL if station is NULL
 * - all errno generated by open() call
 */
int station_init(station_ctx_t *station);

/**
 * station context to clean and reset, with pipe closing
 * \param station pointer to station context to stop
 */
void station_down(station_ctx_t *station);

/**
 * station is into idle state; it sends a sci 'idle' message and waits for sci message reception
 * \param station the current station context
 * \return 0 when message has been received and process<br>
 * -1 if an error happened with errno=<br>
 * <ul><li>EINVAL: station is invalid<br>
 * <li>all error codes from recv() call</ul>
 */
int station_idle(station_ctx_t *station);

/**
 * schedule an eCos tick event (every 10ms)
 * \param station pointer to station context
 * \param tick tick for event scheduling
 * \return 0 if ok, -1 if failed with errno=
 * - EINVAL if station id NULL or if wanted tick is to old
 */
int station_ecos_set_itimer(station_ctx_t *station, tick_t tick);

static inline int station_is_initialized(station_ctx_t *station)
{
#ifdef STATION_SOCK
    return (station->sock_fd >= 0);
#else /* STATION_SOCK */
    return ((station->pipe_in_fd >= 0) && (station->pipe_out_fd >= 0));
#endif /* STATION_SOCK */
}

/**
 * set the station log level
 * \param station pointer to station context
 * \param level new log level
 * \return 0 if ok, -1 if failed with errno=
 * - EINVAL if station is NULL or level is out of range
 */
int station_log_set_level(station_ctx_t *station, station_log_level_t level);

/**
 * set the station log mask
 * \param station pointer to station context
 * \param mask new log mask
 */
extern inline void station_log_set_mask(station_ctx_t *station, unsigned long mask)
{
    station->log_mask = mask;
}

/**
 * get the station log mask
 * \param station pointer to station context
 * \return the current log mask
 */
extern inline unsigned long station_log_get_mask(station_ctx_t *station)
{
    return station->log_mask;
}

/**
 * send message to station log system
 * \param station pointer to station context
 * \param level level of log message
 * \param format string structure describing the data log format
 * \param ... suite of parameters to fit the format
 */
void station_log(station_ctx_t *station,
                 station_log_level_t level,
                 unsigned long type,
                 const char *format,
                 ...);

//END_DECLS

#endif /*STATION_H_*/