summaryrefslogtreecommitdiff
path: root/cesar/lib/stats.h
blob: 6c784f471fe26a5ac2fe8b01145ccb7ecb3ff4c3 (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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#ifndef lib_stats_h
#define lib_stats_h
/* Cesar project {{{
 *
 * Copyright (C) 2009 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    lib/stats.h
 * \brief   Stats system.
 * \ingroup lib
 *
 * The stats module provides access in read or write mode to different types
 * of statistics (pointer to a value or callback). Basically, you can:
 *   - register in read/write mode statistics to add them to the book of
 *   statistics,
 *   - retrieve the whole list of statistics.
 *
 * Statistics are organized by page. Each page can contains the same amount of
 * statistics contained in an MME (VS_GET_STATS). Pages does not include
 * statistics in write only mode.
 */

#include "config/stats.h"
#include "bitstream.h"

enum lib_stats_types_t
{
    LIB_STATS_1_BYTE = 1,
    LIB_STATS_2_BYTE = 2,
    LIB_STATS_4_BYTE = 4,
    LIB_STATS_8_BYTE = 8
};
typedef enum lib_stats_types_t lib_stats_types_t;

enum lib_stats_level_t
{
    LIB_STATS_USER = 0x00,
    LIB_STATS_DEBUG,
    LIB_STATS_TOTAL
};
typedef enum lib_stats_level_t lib_stats_level_t;

/**
 * Access mode of the statistics.
 */
enum lib_stats_access_t
{
    /**
     * Access in read mode only.
     */
    LIB_STATS_ACCESS_READ_ONLY = 1,
    /**
     * Access in write mode only.
     */
    LIB_STATS_ACCESS_WRITE_ONLY = 2,
    /**
     * Access in read/write mode.
     */
    LIB_STATS_ACCESS_READ_WRITE = 3,
};
typedef enum lib_stats_access_t lib_stats_access_t;

/**
 * Callback to read a statistic.
 */
typedef void *(*lib_stats_cb_r_t) (void);

/**
 * Callback to write to a statistic.
 * \param  val  the new value
 */
typedef void (*lib_stats_cb_w_t) (u64 val);

/**
 * Travel callback.
 * \param  user  user parameter
 * \param  name  stat name
 * \param  value stat value
 * \param  type  stat type
 */
typedef void (*lib_stats_travel_cb_t) (void *user,
                                       const char *name,
                                       u64 value,
                                       lib_stats_types_t type);

BEGIN_DECLS

#if CONFIG_STATS

/**
 * Init stat book.
 *
 * Prepare the book so that one empty page is available.
 */
void
lib_stats_init (void);

/**
 * Uninit stat book.
 *
 * Clear all the pages and stats of the book.
 */
void
lib_stats_uninit (void);

/**
 * Return the number of pages available.
 * \param  level  statistics level requested
 * \return  the number of pages available for the requested level
 */
u8
lib_stats_get_nb_pages (lib_stats_level_t level);

/**
 * Write one page of stats to the bitstream.
 * \param  bitstream  bitstream where to write the page
 * \param  page  page number requested (starting from 0)
 * \param  level  statistics level requested
 *
 * Page does not include the statistics in write only mode.
 */
void
lib_stats_get_page (bitstream_t *bitstream, u8 page,
                    lib_stats_level_t level);

/**
 * Call the travel callback for every stats.
 * \param  cb  travel callback
 * \param  user  user data given to travel callback
 * \param  max_level  maximum stat level
 */
void
lib_stats_travel (lib_stats_travel_cb_t cb, void *user,
                  lib_stats_level_t max_level);

/**
 * Write to a statistic.
 * \param  name  name of the statistic to write
 * \param  value  string corresponding to the value to write
 * \return  true if the statistics has been written, false otherwise
 *
 * This function is quite long (it goes through the whole book). If you have
 * another way to directly access the statistic pointer, use it!
 */
bool
lib_stats_write_stat (const char *name, const char *value);

/**
 * Write to many statistics.
 * \param  stats  string containing many statistics to write/configure
 * \return  true if the string is correctly formated and all statistics has
 * been correctly written. False otherwise
 *
 * stats is in the format of the config field, DRV_STA_SET_CONFIG:
 * "name_1:value name_2:value". The string must end by a '\0'.
 */
bool
lib_stats_write_stats (const char *stats);

/**
 * Add a new stat to the stat book using pointer to value.
 * \param  name  string to be displayed before the stat value (no copy of the
 * name is done)
 * \param  value  pointer to the value of the stat
 * \param  mode  access mode
 * \param  type  type and max size of the value in octet
 * \param  level  statistics level requested
 */
void
lib_stats_set_stat_value (const char *name, void *value,
                          lib_stats_access_t mode,
                          lib_stats_types_t type,
                          lib_stats_level_t level);

/**
 * Add a new stat to the stat book using callback.
 * \param  name  string to be displayed before the stat value (no copy of the
 * name is done)
 * \param  callback_read  callback to retrieve the statistics value (can be
 * set to NULL if you do not want to enable read access)
 * \param  callback_write  callback to write the statistics value (can be set
 * to NULL if you do not want to enable write access)
 * \param  type  type and max size of the value in octet
 *
 * callback_read should return a pointer to the type of this statistic. You
 * must cast it when registering. For example:
 * \code
 * static u8 my_val = 0;
 * u8 *
 * cb_r (void)
 * {
 *     return &my_val;
 * }
 * // ...
 * lib_stats_set_stat_callback ("my_cb", (lib_stats_cb_r_t) cb_r, NULL,
 * LIB_STATS_1_BYTE);
 * \endcode
 */
void
lib_stats_set_stat_callback (const char *name, lib_stats_cb_r_t callback_read,
                             lib_stats_cb_w_t callback_write,
                             lib_stats_types_t type,
                             lib_stats_level_t level);

#else /* !CONFIG_STATS */

#define lib_stats_init() ((void) 0)
#define lib_stats_uninit() ((void) 0)
#define lib_stats_set_stat_value(name, value, mode, type, level) ((void) 0)
#define lib_stats_set_stat_callback(name, cb_r, cb_w, type, level) ((void) 0)
#define lib_stats_get_page(bitstream, page, level) ((void) 0)
#define lib_stats_write_stat(name, value) ((void) 0)
#define lib_stats_write_stats(stats) ((void) 0)

#endif /* !CONFIG_STATS */

#define LIB_STATS_MAX_PAGE_SIZE (1024 - 1) /* 1 octet is used for total page number */

/**
 * Add a new stat to the stat book using a pointer to a value without
 * specifying its type.
 * \param  name  string to be displayed before the stat value (no copy of the
 * name is done)
 * \param  mode  access mode
 * \param  value  pointer to the value of the stat
 */
#define lib_stats_set_stat_value_notype(name, value, mode, level) \
    lib_stats_set_stat_value ((name), (value), (mode), sizeof (*(value)), level)

END_DECLS

#endif