aboutsummaryrefslogtreecommitdiff
path: root/libwes/include/libwes.h
blob: f3431d6833037dedb077e8309a09b2ffaf4adcc4 (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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/* ****************************************************************************
 * libwes.h -- bibliothèque d'interaction avec le WES de Cartelectronic.
 * Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
 *
 * This project is governed by the CeCILL license under French law and
 * abiding by the rules of distribution of free software. You can use,
 * modify and/or redistribute the software under the terms of the
 * CeCILL license as circulated by CEA, CNRS and INRIA at the
 * following URL: "http://www.cecill.info".
 *
 * As a counterpart to the access to the source code and rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty and the project's author, the holder of the
 * economic rights, and the successive licensors have only limited liability.
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading, using, modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean that it is complicated to manipulate, and that also therefore
 * means that it is reserved for developers and experienced professionals
 * having in-depth computer knowledge. Users are therefore encouraged to load
 * and test the software's suitability as regards their requirements in
 * conditions enabling the security of their systems and/or data to be
 * ensured and, more generally, to use and operate it in the same conditions
 * as regards security.
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL license and that you accept its terms.
 * ************************************************************************* */
#ifndef  LIBWES_H
# define LIBWES_H 20180611
# ifdef __cplusplus
extern "C" {
# endif
# include <stddef.h>
# include <ctype.h>

/* La ressource de type WES est rendue opaque. */

struct WES;
typedef struct WES WES;

/* Adresse réseau.
 * Pour le moment, seules les adresses IPv4 et IPv6 sont gérées.
 * Un appareil peut avoir à la fois une adresse IPv4 et une adresse IPv6. */

# define WESNONET 0 /* entrée invalide */
# define WESINET  1 /* ipv4 and ipv6 */

# define WESHASIPv4  1 /* option pour `data.inet.has`: a une adresse ipv4 */
# define WESHASIPv6  2 /* option pour `data.inet.has`: a une adresse ipv6 */

typedef struct {
	int type;
	union {
		struct {
			int has;
			unsigned char ipv4[4];
			unsigned char ipv6[16];
		} inet;
	} data;
} wes_addr_t;

/* Codes d'erreur/de retour. */

# define wes_error_ok        0 /* Pas de souc'. */
# define wes_error_unknown   1 /* Erreur inconnue. */
# define wes_error_op        2 /* Cette opération n'est pas permise. */
# define wes_error_alloc     3 /* Une allocation mémoire a échoué. */
# define wes_error_val       4 /* L'un des arguments est invalide. */
# define wes_error_iter      5 /* Plus d'éléments dans un itérateur. */

# define wes_error_nohost   10 /* Le serveur n'a pas pu être atteint. */
# define wes_error_conn     11 /* La connexion a été réinitialisée. */
# define wes_error_notfound 12 /* Une ressource n'a pas été trouvée. */
# define wes_error_timeout  13 /* Un délai a expiré. */
# define wes_error_auth     14 /* Une authentification a échoué. */
# define wes_error_space    15 /* On a manqué d'espace. */

/* ---
 * Logging.
 * --- */

/* Définition des niveaux. */

# define wes_log_debug   0 /* informations de débug */
# define wes_log_info    0 /* (idem) */
# define wes_log_warn   10 /* avertissements */
# define wes_log_error  20 /* erreurs non fatales */
# define wes_log_fatal  30 /* erreurs fatales */
# define wes_log_notice 40 /* messages type copyright etc. */
# define wes_log_none   40 /* minimum de messages */

typedef int wes_loglevel_t;

/* ---
 * Éléments pour les requêtes CGI/HTTP.
 * --- */

/* Méthode HTTP à utiliser pour exécuter le script CGI (surtout pour les
 * arguments). */

typedef enum wes_http_method {
	WESHTTPMETHOD_GET,
	WESHTTPMETHOD_POST
} wes_http_method_t;

typedef wes_http_method_t wes_cgi_method_t;

# define WESCGIMETHOD_GET  WESHTTPMETHOD_GET
# define WESCGIMETHOD_POST WESHTTPMETHOD_POST

/* Argument avec valeur éventuelle à passer. */

typedef struct wes_http_arg {
	const char *name;
	const char *value; /* peut être `NULL` ! */
} wes_http_arg_t;

typedef wes_http_arg_t wes_cgi_arg_t;

# define WESHTTPARG(NAME, VALUE) {(NAME), (VALUE)}
# define  WESCGIARG(NAME, VALUE) WESHTTPARG(NAME, VALUE)

/* Requête de variable CGI.
 * Ce bloc contient à la fois les éléments de requête et les réponses à
 * remplir, à la manière des `sg_io_hdr_t` de l'interface utilisateur
 * de Linux. */

typedef struct wes_cgi {
	/* Requête (entrée).
	 * Requiert une variable et un format. */

	const char *var;
	const char *format;

	/* Réponse (sortie).
	 * `buffer`: buffer à remplir avec la réponse.
	 * `len`: longueur du buffer (incluant le '\0' à insérer).
	 * `full`: longueur attendue du buffer (en cas de ré-appel) ;
	 * `lines`: nombre de lignes de réponses (donc nombre de retours à la
	 * ligne trouvables dans le buffer + 1). */

	char *buffer;
	size_t len, full;
	int lines;

	int wescgi__align;
} wes_cgi_t;

/* Cette macro permet de définir le contenu d'une instance de type `wescgi_t`
 * de façon rétrocompatible au niveau de l'API, et plus simplement qu'en
 * le faisant manuellement. */

# define WESCGI(VAR, FORMAT, BUFFER, LEN) \
	{(VAR), (FORMAT), (BUFFER), (LEN), 0, 0, 0}

/* ---
 * Définition des structures utilisées pour la configuration.
 * --- */

/* Élément de configuration. */

typedef struct wes_cfg_key {
	struct wescfgkey *next;

	size_t keysz; /* Taille de la clé de configuration */
	size_t valsz; /* Taille de la valeur */
	char data[];
} wes_cfg_key_t;

/* Section de configuration.
 * Une section contient à la fois :
 * - des options de configuration et leur valeur, sous la forme d'une liste
 *   chaînée de `wescfg_t`, détectées en `<key>=<val><CRLF>` ;
 * - ce qui reste (« text »), détectées en `<key><CRLF>` (sans '='). */

typedef struct wes_cfg_sec {
	struct wes_cfg_sec *next;

	wes_cfg_key_t *child;
	size_t keysz;
#if 0
	size_t textsz;
	char *text;
#endif
	char data[];
} wes_cfg_sec_t;

/* ---
 * Définition des structures utilisées pour les données de type
 * PULSE (impulsions), PLIERS (pinces) et TELEINFO (externe).
 * --- */

/* Même si présentes dans différents fichiers, ces informations sont
 * regroupées à la même enseigne sous ce démon. */

#define WDFTIEXST     1 /* Les données TELEINFO existent. */
#define WDFPLEXST     2 /* Les données PL existent. */
#define WDFPCEXST     4 /* Les données PC existent. */

#define WDFTIPLUG     8 /* TELEINFO est non branché */
#define WDFPLNAN0    16 /* PL1 est égal à NaN */
#define WDFPLNAN1    32 /* PL2 est égal à NaN */
#define WDFPLNAN2    64 /* PL3 est égal à NaN */
#define WDFPLNAN3   128 /* PL4 est égal à NaN */
#define WDFPCNAN0   256 /* PC1 est égal à NaN */
#define WDFPCNAN1   512 /* PC2 est égal à NaN */
#define WDFPCNAN2  1024 /* PC3 est égal à NaN */
#define WDFPCNAN3  2048 /* PC4 est égal à NaN */

typedef struct wes_data {
	struct wes_data *next;

	/* Minute correspondante dans la journée. */

	int hour, min;

	/* Options, concernant si les données sont valides, etc. */

	int flags;
	int wesdata__align;

	/* Valeurs concernant les pulsations. */

	double pl[4];

	/* Valeurs concernant les pinces. */

	double pc[4];

	/* Valeurs récupérées depuis les compteurs.
	 * `hp` est le cumul de l'énergie consommée lors des heures pleines,
	 * en Wh. `hc` est son équivalent pour les heures creuses.
	 * `ii` est l'intensité instantanée en A.
	 * `pa` est la puissance apparente en VA. */

	long hp, hc;
	long ii, pa;
} wes_data_t;

typedef struct wes_data_span {
	struct wes_data_span *next;

	/* Données correspondant à cette journée. */

	wes_data_t *data;

	/* Année, mois, jour du mois.
	 * Il s'agit de l'organisation des fichiers sur le WES. */

	int year, mon, dom;

	int wes_data_span__align;
} wes_data_span_t;

/* ---
 * Déclarations des fonctions.
 * --- */

/* Obtenir le message de l'erreur. */

extern char const *wes_error_string(int error);

/* Définir le niveau de log. */

extern void wes_set_log_level(char const *level);

/* Ouvrir et fermer un handle. */

extern int wes_open(WES **resource, wes_addr_t const *addr);
extern void wes_close(WES *resource);

/* Définition des identifiants HTTP et FTP. */

extern int wes_set_http_ident(WES *wes, const char *name, const char *pass);
extern int  wes_set_ftp_ident(WES *wes, const char *name, const char *pass);

/* Ces fonctions implémentent les interfaces CGI (génération et exécution
 * de scripts) et HTTP (utilisation d'arguments GET et POST pour réaliser
 * des actions).
 *
 * La gestion du tout se fait par la fonction la plus
 * basse : `wes_get_cgi_with_args()`. */

extern int wes_get_cgi_var(WES *wes, const char *var, const char *format,
	char *buffer, size_t *len);
extern int wes_get_cgi(WES *wes, int blkc, wes_cgi_t *blk);

extern int wes_get_form(WES *wes, int argc, wes_cgi_arg_t *args);
extern int wes_post_form(WES *wes, int argc, wes_cgi_arg_t *args);

extern int wes_get_cgi_with_args(WES *wes, wes_cgi_method_t method,
	int argc, wes_cgi_arg_t *args, int blkc, wes_cgi_t *blks);

/* Cette fonction implémentent l'interface M2M. */

extern int wes_init_m2m(WES *wes);
extern int wes_deinit_m2m(WES *wes);

extern int wes_send_command(WES *wes, char const *command,
	char *response, size_t *lenp);

/* Récupération des données pour une minute particulière,
 * et nettoyage des données locales de la configuration. */

extern int wes_get_data(WES *wes, wes_data_t *data,
	int year, int month, int mday, int hour, int min);
extern int wes_clear_data(WES *wes);

# ifdef __cplusplus
}
# endif
#endif /* LIBWES_H */