aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-06-11 10:12:35 +0200
committerThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-06-11 10:12:35 +0200
commit242ea55c5fe6c3bc13bd5db10f056b6001b12840 (patch)
tree064c1970726065a83aa513cbdffcd72efb12aae2
parent7f399eadf216fbb3290bdf882d78180b6140c364 (diff)
Reorganized WES hacking into libwes for demonstration purposesHEADmaster
-rw-r--r--.gitignore2
-rwxr-xr-xMakefile38
-rwxr-xr-xMakefile.vars50
-rw-r--r--daemon/base.c30
-rw-r--r--daemon/internals.h218
-rw-r--r--daemon/ip/internals.h344
-rw-r--r--daemon/server.c42
-rw-r--r--libwes/include/libwes.h314
-rw-r--r--libwes/src/cfg.c.draft (renamed from daemon/ip/cfg.c)14
-rw-r--r--libwes/src/cgi.c (renamed from daemon/ip/cgi.c)112
-rw-r--r--libwes/src/csv.c (renamed from daemon/ip/csv.c)22
-rw-r--r--libwes/src/data.c (renamed from daemon/ip/data.c)127
-rw-r--r--libwes/src/error.c54
-rw-r--r--libwes/src/internals.h235
-rw-r--r--libwes/src/log.c221
-rw-r--r--libwes/src/m2m.c (renamed from daemon/ip/m2m.c)111
-rw-r--r--libwes/src/open.c84
-rw-r--r--libwes/src/utils.c (renamed from daemon/ip/utils.c)66
-rw-r--r--libwesh/include/libwesh.hpp (renamed from include/libwesh.hpp)0
-rw-r--r--libwesh/src/helpers.cpp (renamed from lib/helpers.cpp)0
-rw-r--r--libwesh/src/interface.cpp (renamed from lib/interface.cpp)0
-rw-r--r--libwesh/src/internals.hpp (renamed from lib/internals.hpp)0
-rw-r--r--libwesh/src/meter.cpp (renamed from lib/meter.cpp)0
-rw-r--r--libwesh/src/sensor.cpp (renamed from lib/sensor.cpp)0
-rw-r--r--libwesh/src/wes.cpp (renamed from lib/wes.cpp)0
-rw-r--r--weshd.x286
26 files changed, 1573 insertions, 797 deletions
diff --git a/.gitignore b/.gitignore
index 0611830..22d7b61 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,5 +10,7 @@ vgcore.*
common/weshd.h
Makefile.cfg
testclient
+test.c
+test.sh
root
weshd-*.tar*
diff --git a/Makefile b/Makefile
index e0d3594..b85eaa1 100755
--- a/Makefile
+++ b/Makefile
@@ -85,7 +85,7 @@ install: install-daemon install-lib install-client
# Dossiers de construction.
# XXX: Temporaire, merci à moi du futur de refaire ça proprement un jour.
- ./build/ ./build/rpc/ ./build/daemon/ \
+ ./build/ ./build/rpc/ ./build/daemon/ ./build/libw/ \
./build/lib/ ./build/lib/wes/ ./build/lib/meter/ \
./build/daemon/ip/ ./build/daemon/dummy/ ./build/client/:
$(call bcmd,mkdir,$@,$(MD) "$@")
@@ -134,6 +134,42 @@ install: install-daemon install-lib install-client
$(call bcmd,cc,$@,$(CC) -c -o $@ $< $(S_CFLAGS))
# ---
+# Définition des targets pour la libwes.
+# ---
+# Création de la bibliothèque.
+
+ all-libw: $(CHECKCFG) $(W_DEST)
+
+ $(W_DEST): $(W_DEST).$(MAJOR) | $(dir $(W_DEST))
+ $(call bcmd,ln,$@,$(LN) $(notdir $(W_DEST).$(MAJOR)) $(W_DEST))
+ $(W_DEST).$(MAJOR): $(W_OBJ) | $(dir $(W_DEST))
+ $(call bcmd,ld,$@,$(LD) -o $@ $(W_OBJ) $(W_LDFLAGS))
+
+define make-lib-obj-rule
+ $(W_OBJDIR)/$1.c.o: $(W_SRCDIR)/$1.c $(W_INC) | $(dir $(W_OBJDIR)/$1)
+ $(call bcmd,cc,$$@,$(CC) -c -o $$@ $$< $(W_CFLAGS))
+endef
+$(foreach src,$(basename $(W_SRC)),\
+$(eval $(call make-lib-obj-rule,$(src))))
+
+# Installation de la bibliothèque.
+
+ install-libw: $(CHECKCFG) | $(ILIBDIR) $(IPKGDIR) $(sort \
+ $(foreach x,$(W_INCp),$(dir $(IINCDIR)/lib$(LIB)-$(VERSION)/$(x))))
+ $(call imsg,Installation de la bibliothèque.)
+ $(call qcmd,$(INST) -m 755 $(W_DEST) \
+ $(ILIBDIR)/$(notdir $(W_DEST).$(MAJOR)))
+ $(call qcmd,$(LN) $(notdir $(W_DEST).$(MAJOR)) \
+ $(ILIBDIR)/$(notdir $(W_DEST)))
+ $(call imsg,Installation du paquet pkg-config.)
+ $(call qcmd,tools/write-pkg.sh >$(IPKGDIR)/lib$(LIB).pc)
+ $(call imsg,Installation des headers.)
+ $(foreach i,$(W_INCp),$(call qcmd,$(INST) -m 644 $(W_INCDIR)/$(i) \
+ "$(IINCDIR)/lib$(LIB)-$(VERSION)/$(i)"$(\n)))
+
+.PHONY: all-libw install-libw
+
+# ---
# Définition des targets pour le démon.
# ---
# Création du démon.
diff --git a/Makefile.vars b/Makefile.vars
index e51d75e..7f0001d 100755
--- a/Makefile.vars
+++ b/Makefile.vars
@@ -28,6 +28,7 @@
DAEMON := weshd
LIB := wesh
+ LIBW := wes
CLIENT := weshclient
# ---
@@ -72,6 +73,11 @@
DEP_rpc_CFLAGS := $(shell pkg-config libtirpc --cflags)
DEP_rpc_LIBS := $(shell pkg-config libtirpc --libs)
+# libwes, soit la bibliothèque d'interaction avec le WES.
+
+ DEP_lw_CFLAGS := -I libwes/
+ DEP_lw_LIBS := -L build -l$(LIBW)
+
# libwesh, soit la bibliothèque client.
DEP_lib_CXXFLAGS := -I include/
@@ -97,17 +103,49 @@
S_CFLAGS := $(DEP_rpc_CFLAGS)
# ---
-# Informations concernant le démon.
+# Informations concernant la bibliothèque d'interaction avec les WES.
# ---
+# Dossiers la concernant.
+
+ W_DEST := ./build/lib$(LIBW).so
+
+ W_SRCDIR := ./libwes/src
+ W_INCDIR := ./libwes/include
+ W_OBJDIR := ./build/libw
+
+# Recherche de ses sources.
+
+ W_SRC := \
+ $(patsubst $(W_SRCDIR)/%,%,$(wildcard $(W_SRCDIR)/*.c \
+ $(W_SRCDIR)/**/*.c))
+ W_OBJ := $(W_SRC:%=$(W_OBJDIR)/%.o)
+ W_INCp := $(patsubst $(W_INCDIR)/%,%,$(wildcard \
+ $(W_INCDIR)/*.hpp $(W_INCDIR)/**/*.hpp))
+ W_INC := $(W_INCp:%=$(W_INCDIR)/%) \
+ $(wildcard $(W_SRCDIR)/*.h $(W_SRCDIR)/**/*.h)
+
# Dépendances et options.
- D_DEPS := libcurl rpc
+ W_DEPS := libcurl
- D_CFLAGS := $(CFLAGS) $(foreach x,$(D_DEPS),$(DEP_$(x)_CFLAGS)) \
- -I $(S_OBJDIR) -D NOLOGO=$(NO_LOGO) -D DEFAULT_LOGLEVEL=WL$(LOG_LEVEL) \
+ W_CFLAGS := $(CFLAGS) $(foreach x,$(W_DEPS),$(DEP_$(x)_CFLAGS)) \
+ -fPIC -I $(W_INCDIR) \
-D DELETE_SCRIPTS="$(if $(DELETE_SCRIPTS),$(DELETE_SCRIPTS),1)" \
-D CURLHTTPVERBOSE="$(if $(CURL_HTTP_VERBOSE),$(CURL_HTTP_VERBOSE),0)L" \
-D CURLFTPVERBOSE="$(if $(CURL_FTP_VERBOSE),$(CURL_FTP_VERBOSE),0)L"
+ W_LIBS := $(foreach x,$(W_DEPS),$(DEP_$(x)_LIBS))
+ W_LDFLAGS := $(W_LIBS) -shared -Wl,-z,relro -Wl,-z,combreloc -Wl,-z,defs \
+ -Wl,-soname,lib$(LIBW).so.$(MAJOR)
+
+# ---
+# Informations concernant le démon.
+# ---
+# Dépendances et options.
+
+ D_DEPS := rpc libw
+
+ D_CFLAGS := $(CFLAGS) $(foreach x,$(D_DEPS),$(DEP_$(x)_CFLAGS)) \
+ -I $(S_OBJDIR) -D NOLOGO=$(NO_LOGO) -D DEFAULT_LOGLEVEL=WL$(LOG_LEVEL)
D_LIBS := $(foreach x,$(D_DEPS),$(DEP_$(x)_LIBS))
# Dossiers le concernant.
@@ -132,8 +170,8 @@
L_DEST := ./build/lib$(LIB).so
- L_SRCDIR := ./lib
- L_INCDIR := ./include
+ L_SRCDIR := ./libwesh/src
+ L_INCDIR := ./libwesh/include
L_OBJDIR := ./build/lib
# Recherche de ses sources.
diff --git a/daemon/base.c b/daemon/base.c
index eb0275f..b2f6001 100644
--- a/daemon/base.c
+++ b/daemon/base.c
@@ -36,8 +36,7 @@
static char *empty_name = "";
-/* `init_wes_base()`: Initialiser les composants de base d'une ressource de
- * type serveur WES. */
+/* `init_obj_base()`: Initialiser les composants de base d'un objet. */
int init_wes_base(wes_t *wes, wesif_t const *iface)
{
@@ -46,38 +45,11 @@ int init_wes_base(wes_t *wes, wesif_t const *iface)
wes->next = NULL;
wes->prev = NULL;
wes->iface = iface;
- wes->lastobj = NULL;
wes->name = empty_name;
return (WROK);
}
-/* `deinit_wes_base()`: Supprimer les composants d'une ressource de
- * type serveur WES. */
-
-int deinit_wes_base(wes_t *wes)
-{
- set_name(wes, "");
- set_obj_to_free(wes, NULL);
-
- return (WROK);
-}
-
-/* `set_obj_to_free()`: faire en sorte qu'un objet soit libéré tantôt. */
-
-void set_obj_to_free(wes_t *wes, void *vobj)
-{
- wesfreemem_t **obj = (void*)vobj;
-
- if (wes->lastobj) {
- (**wes->lastobj)((void*)*wes->lastobj);
- wes->lastobj = NULL;
- }
-
- if (obj && *obj)
- wes->lastobj = (wesfreemem_t **)obj;
-}
-
/* ---
* Gestion d'un nom de serveur WES.
* --- */
diff --git a/daemon/internals.h b/daemon/internals.h
index 184efd1..5b75205 100644
--- a/daemon/internals.h
+++ b/daemon/internals.h
@@ -35,7 +35,6 @@
# include <string.h>
# include <ctype.h>
# include <errno.h>
-# include <curl/curl.h>
/* ---
* Codes de retour internes.
@@ -117,6 +116,107 @@ typedef int loglevel_t;
typedef int wesfreemem_t (void*);
/* ---
+ * Définition d'un objet du démon.
+ * --- */
+
+/* Les objets du démon sont organisés en un arbre, avec parents et enfants,
+ * en listes chaînées avec sentinelles.
+ * Le dernier identifiant (ID_MAX + 1) doit pouvoir être atteint puisqu'il
+ * s'agit de celui de la sentinelle. */
+
+# define ID_MAX 32766
+
+# define WESOBJTYPE_WES 1
+# define WESOBJTYPE_METER 2
+# define WESOBJTYPE_SENSOR 3
+
+# ifndef WESIF_DEFINITIONS
+# define WESIFBASENAME wesif
+# define WESIFBASENAMT wesif_t
+# else
+# define WESIFBASENAME wesifbase
+# define WESIFBASENAMT wesifbase_t
+# endif
+
+typedef int wesif_free_t (wes_t *);
+
+typedef struct wesifacebase {
+ wesif_free_t *free;
+} wesifacebase_t;
+
+typedef struct wesobjbase {
+ /* Identifiant utilisé dans le protocole d'interaction avec le démon,
+ * si l'objet est valide, suivi du type et d'alignement. */
+
+ int valid, id;
+ int type, _reserved;
+
+ /* Prochain WES dans la liste chaînée pour le même niveau.
+ * Aussi, pointeur vers le pointeur qui pointe sur cet élément dans
+ * l'élément précédent, pour pouvoir le mettre à jour en cas de
+ * changement. */
+
+ struct wesobj *next;
+ struct wesobj **prev;
+ struct wesobj *parent;
+ struct wesobj *children;
+
+ /* Interface. */
+
+ wesif_t const *iface;
+
+ /* Nom de la ressource (toutes les ressources en ont une). */
+
+ char *name;
+} wesobjbase_t;
+
+/* ---
+ * Définition des structures utilisées pour la liste.
+ * --- */
+
+/* Voici la structure de la liste.
+ * En plus du lien vers le début des deux chaînes, cette structure contient
+ * de quoi créer plus rapidement un élément avec un identifiant unique. */
+
+typedef struct {
+ /* Lien vers le premier élément. */
+
+ wesobjbase_t *first;
+
+ /* Dernier identifiant inséré.
+ * Ceci permet de ne pas réutiliser directement les identifiant
+ * supprimés avant d'avoir fait un tour. */
+
+ int last_id;
+
+ /* Nombre de nœuds actuellement gérés. */
+
+ int count;
+
+ /* Base */
+
+ WESBASENAMT sentinel;
+} weslist_t;
+
+/* On peut vouloir itérer sur le contenu de la liste, pour chercher un
+ * élément ou tout simplement lister les ressources disponibles. */
+
+# define WIVALID 18988
+
+typedef struct {
+ /* Le prochain élément à renvoyer. */
+
+ wes_t *current;
+
+ /* Histoire de vérifier qu'on ne tombe pas sur un itérateur
+ * pas initialisé. */
+
+ int status;
+
+ int wesiter__align;
+} wesiter_t;
+
+/* ---
* Utilitaires.
* --- */
@@ -628,8 +728,6 @@ typedef struct wes wes_t;
* à utiliser. Ces fonctions correspondent plus ou moins aux besoins du
* serveur. */
-typedef int wesif_free_t (wes_t *);
-
typedef int wesif_getcfg_t (wes_t *, wescfgflags_t, wescfg_t **);
typedef int wesif_setcfg_t (wes_t *, wescfgflags_t, wescfg_t const *);
@@ -711,98 +809,6 @@ typedef struct wescreatedata {
} wescreatedata_t;
/* ---
- * Définition du serveur WES en lui-même.
- * --- */
-
-/* Les ressources de type serveur WES telles que vues par le démon sont
- * gérées en liste chaînée avec sentinelle.
- * Le dernier identifiant (ID_MAX + 1) doit pouvoir être atteint puisqu'il
- * s'agit de celui de la sentinelle. */
-
-# define ID_MAX 32766
-
-# ifndef WESIF_DEFINITIONS
-# define WESBASENAME wes
-# define WESBASENAMT wes_t
-# else
-# define WESBASENAME wesbase
-# define WESBASENAMT wesbase_t
-# endif
-
-typedef struct WESBASENAME {
- /* Identifiant utilisé dans le protocole d'interaction avec le démon,
- * et options. */
-
- int id, valid;
-
- /* Prochain WES dans la liste chaînée.
- * Aussi, pointeur vers le pointeur qui pointe sur cet élément dans
- * l'élément précédent, pour pouvoir le mettre à jour en cas de
- * changement. */
-
- struct wes *next;
- struct wes **prev;
-
- /* Interface. */
-
- wesif_t const *iface;
-
- /* Dernier objet alloué (pour gestion par le serveur uniquement). */
-
- wesfreemem_t **lastobj;
-
- /* Nom du WES. */
-
- char *name;
-} WESBASENAMT;
-
-/* ---
- * Définition des structures utilisées pour la liste.
- * --- */
-
-/* Voici la structure de la liste.
- * En plus du lien vers le début des deux chaînes, cette structure contient
- * de quoi créer plus rapidement un élément avec un identifiant unique. */
-
-typedef struct {
- /* Lien vers le premier élément. */
-
- wes_t *first;
-
- /* Dernier identifiant inséré.
- * Ceci permet de ne pas réutiliser directement les identifiant
- * supprimés avant d'avoir fait un tour. */
-
- int last_id;
-
- /* Nombre de nœuds actuellement gérés. */
-
- int count;
-
- /* Base */
-
- WESBASENAMT sentinel;
-} weslist_t;
-
-/* On peut vouloir itérer sur le contenu de la liste, pour chercher un
- * élément ou tout simplement lister les ressources disponibles. */
-
-# define WIVALID 18988
-
-typedef struct {
- /* Le prochain élément à renvoyer. */
-
- wes_t *current;
-
- /* Histoire de vérifier qu'on ne tombe pas sur un itérateur
- * pas initialisé. */
-
- int status;
-
- int wesiter__align;
-} wesiter_t;
-
-/* ---
* Logging.
* --- */
@@ -846,10 +852,6 @@ extern int add_dummy_wes(weslist_t *list, wes_t **wesp);
extern int init_wes_base(wes_t *wes, wesif_t const *iface);
extern int deinit_wes_base(wes_t *wes);
-/* Définir un objet à libérer tantôt. */
-
-extern void set_obj_to_free(wes_t *wes, void *obj);
-
/* Définir le nom d'un serveur WES (dans sa base).
* - `prep_name()`: préparation d'un nom en sanitizant (sans validation,
* utilisé pour récupérer des données depuis les WES surtout ;
@@ -885,12 +887,18 @@ extern int correct_meter(wes_t *wes, wesmetercfg_t *meter,
extern int init_list(weslist_t *list);
extern int deinit_list(weslist_t *list);
+/* Initialiser une tête. */
+
+extern int init_obj_base(wesobjbase_t *obj, wesif_t const *iface);
+
/* Ces fonctions ajoutent et retirent un élément dans la liste chaînée.
- * `add_to_list()` crée un élément et l'ajoute dans la liste.
- * `remove_in_list()` retire un élément de la liste et le supprime. */
+ * `add_to_list()` ajoute un élément dans la liste.
+ * `remove_in_list()` retire un élément de la liste et le supprime
+ * ainsi que ses enfants s'il en a. */
-extern int add_to_list(weslist_t *list, wes_t *wes);
-extern int remove_in_list(weslist_t *list, wes_t *wes);
+extern int add_to_list(weslist_t *list, wesobjbase_t *parent,
+ wesobjbase_t *wes);
+extern int remove_in_list(weslist_t *list, wesobj_t *wes);
extern int remove_in_list_using_id(weslist_t *list, int id);
@@ -901,7 +909,7 @@ extern int empty_list(weslist_t *list);
/* Cette fonction permet d'obtenir un élément en utilisant son
* identifiant numérique. */
-extern int get_in_list(weslist_t *list, wes_t **resp, int id);
+extern int get_in_list(weslist_t *list, wesobj_t **resp, int id);
/* Ces fonctions permettent d'itérer sur le contenu de la liste.
* Il faut d'abord préparer l'itérateur avec `iterate_on_list()`,
@@ -909,7 +917,7 @@ extern int get_in_list(weslist_t *list, wes_t **resp, int id);
* ce qui veut dire qu'il n'y a plus d'éléments à dire. */
extern int iterate_on_list(wesiter_t *iter, weslist_t *list);
-extern int get_next_iteration(wesiter_t *iter, wes_t **element);
+extern int get_next_iteration(wesiter_t *iter, wesobj_t **element);
/* ---
* Gestion du démon en lui-même.
diff --git a/daemon/ip/internals.h b/daemon/ip/internals.h
index 0cdd6bb..c0d79c8 100644
--- a/daemon/ip/internals.h
+++ b/daemon/ip/internals.h
@@ -33,356 +33,16 @@
# define WESIF_DEFINITIONS 1
# include "../internals.h"
-
-/* POSIX-specific headers */
-
-# include <unistd.h>
-# include <arpa/inet.h>
-# include <netinet/in.h>
-# include <netinet/tcp.h>
-# include <sys/socket.h>
-# include <sys/ioctl.h>
-
-/* ---
- * Données utilisées pour les requêtes HTTP.
- * --- */
-
-typedef enum weshttpmethod {
- WESHTTPMETHOD_GET,
- WESHTTPMETHOD_POST
-} weshttpmethod_t;
-
-typedef struct weshttparg {
- const char *name;
- const char *value; /* peut être NULL ! */
-} weshttparg_t;
-
-# define WESHTTPARG(NAME, VALUE) {(NAME), (VALUE)}
-
-/* ---
- * Données utilisées pour le décodage de fichiers CSV.
- * --- */
-
-/* Cookie et type du callback.
- * Le callback est appelé pour chaque ligne qui a été lue.
- * Le `fdc` passé (field count) ne donne que le nombre de valeurs remplies,
- * pas le nombre total de champs qu'il y avait dans la ligne. */
-
-typedef int wescsventry_t (void *cookie, int line, int fdc,
- char * const fdv[]);
-
-typedef struct wescsv {
- int num, id, line, err;
- char * const *buffers;
- size_t const *lens;
- wescsventry_t *callback;
- void *cbcookie;
-
- size_t off;
- int separator;
-
- int wescsv__align;
-} wescsv_t;
-
-/* ---
- * Définition des structures utilisées pour la configuration.
- * --- */
-
-/* Élément de configuration. */
-
-typedef struct wescfgkey {
- struct wescfgkey *next;
-
- size_t keysz; /* Taille de la clé de configuration */
- size_t valsz; /* Taille de la valeur */
- char data[];
-} wescfgkey_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 wescfgsec {
- struct wescfgsec *next;
-
- wescfgkey_t *child;
- size_t keysz;
-#if 0
- size_t textsz;
- char *text;
-#endif
- char data[];
-} wescfgsec_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 wesdata {
- struct wesdata *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;
-} wesdata_t;
-
-typedef struct wesdataspan {
- struct wesdataspan *next;
-
- /* Données correspondant à cette journée. */
-
- wesdata_t *data;
-
- /* Année, mois, jour du mois.
- * Il s'agit de l'organisation des fichiers sur le WES. */
-
- int year, mon, dom;
-
- int wesdataspan__align;
-} wesdataspan_t;
-
-/* ---
- * Définition d'une requête 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 wescgi {
- /* 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;
-} wescgi_t;
-
-/* Les requêtes CGI sont également le moyen de faire des requêtes GET et POST
- * pour interagir en écriture avec le serveur WES. La méthode peut varier
- * selon la variable et le moyen de l'atteindre, mais l'idée derrière les
- * arguments reste la même. */
-
-typedef weshttpmethod_t wescgimethod_t;
-typedef weshttparg_t wescgiarg_t;
-
-# define WESCGIARG(NAME, VALUE) WESHTTPARG(NAME, VALUE)
-# define WESCGIMETHOD_GET WESHTTPMETHOD_GET
-# define WESCGIMETHOD_POST WESHTTPMETHOD_POST
-
-/* 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}
+# include <libwes.h>
/* ---
* Structure du WES propre à cette interface.
* --- */
-# define WSK_NONE 0
-# define WSK_TCP 1
-# define WSK_UDP 2
-
struct wes {
wesbase_t base;
- /* Identifiants pour les serveurs HTTP et FTP. */
-
- char *http_name;
- char *http_pass;
-
- char *ftp_name;
- char *ftp_pass;
-
- /* Canaux (handles de la libcurl) pour le HTTP et FTP. */
-
- CURL *http_handle;
- CURL *ftp_handle;
-
- /* Éléments pour la gestion de la configuration.
- * Il s'agit d'une liste chaînée de sections. */
-
- wescfgsec_t *sections;
-
- /* Éléments pour la gestion des données.
- * Il s'agit d'une liste chaînée de données regroupées par date. */
-
- wesdataspan_t *data;
-
- /* Adresse IP cross-platform pour joindre le serveur WES. */
-
- wesaddr_t addr;
-
- /* Éléments pour le protocole M2M.
- * `sock_type` représente le type de la socket parmi les constantes
- * en `WSK_*` précisées ci-dessus.
- * `sock_buf` est le buffer de réception, alloué dynamiquement à
- * `WSBUFSIZE` lorsque l'on se sert de la socket.
- * La socket et ses données, qui dépendent de la plateforme, sont
- * stockées dans l'union `platform`. */
-
- int sock_type;
- char *sock_buf;
- size_t sock_buflen;
-
- /* Éléments spécifiques à des platformes données. */
-
- union {
- struct {
- /* Sockets BSD.
- * On garde le file descriptor et l'adresse (pour l'UDP et
- * sa commande associée `sendto()`). */
-
- int sock;
-
- int wes_posix__align;
-
- struct sockaddr *sockaddr;
- socklen_t sockaddr_size;
-
- union {
- struct sockaddr_in ip;
- struct sockaddr_in6 ip6;
- } sock_addr;
- } posix;
- } platform;
+ WES *resource;
};
-/* ---
- * Décodages de fichiers CSV.
- * --- */
-
-/* `init_csv()` permet d'initialiser le cookie avec les buffers, quelques
- * tweaks de lecture et le callback à utiliser. */
-
-extern int init_csv(wescsv_t *cookie, int separator,
- int numfields, char * const buffers[], size_t const lens[],
- wescsventry_t *callback, void *cbcookie);
-
-/* `read_csv()` sert de callback à la libcurl par exemple (ressemble donc
- * à `fwrite()`), pour lire du contenu ;
- * `end_csv()` termine la lecture du fichier en appelant si besoin une
- * dernière fois le callback. */
-
-extern size_t read_csv(char *buf, size_t size, size_t nmemb, void *cookie);
-extern int end_csv(wescsv_t *cookie);
-
-/* ---
- * Gestions des protocoles cités ci-dessus.
- * --- */
-
-extern int set_http_ident(wes_t *wes, const char *name, const char *pass);
-extern int set_ftp_ident(wes_t *wes, const char *name, const char *pass);
-
-/* Ouvrir les canaux HTTP et FTP sur lesquels on fait les requêtes. */
-
-extern int open_http_handle(wes_t *wes, CURL **handlep, weshttpmethod_t method,
- const char *path, int argc, weshttparg_t *args);
-extern int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path);
-
-/* Récupérer et définir la valeur d'une option de configuration sur le
- * serveur WES. La « section » correspond au fichier dans le dossier `CFG/`
- * accessible sur le serveur FTP du serveur WES. */
-
-extern int get_config(wes_t *wes, const char *section, const char *key,
- char *buf, size_t len);
-extern int set_config(wes_t *wes, const char *section, const char *key,
- const char *value);
-
-/* Appliquer et retirer l'intégralité de la copie locale de
- * la configuration. */
-
-extern int apply_config(wes_t *wes);
-extern int clear_config(wes_t *wes);
-
-/* Récupération des données pour une minute particulière. */
-
-extern int get_data(wes_t *wes, wesdata_t *data, struct tm *dt);
-
-/* Nettoyage des données locales de la configuration. */
-
-extern int clear_data(wes_t *wes);
-
-/* Récupération d'un ou plusieurs éléments par script CGI
- * La gestion des arguments GET et POST via HTTP se fait via
- * la fonction la plus basse : `get_cgi_args()`. */
-
-extern int get_cgi_var(wes_t *wes, const char *var, const char *format,
- char *buffer, size_t *len);
-extern int get_cgi(wes_t *wes, int blkc, wescgi_t *blk);
-
-extern int get_form(wes_t *wes, int argc, wescgiarg_t *args);
-extern int post_form(wes_t *wes, int argc, wescgiarg_t *args);
-
-extern int get_cgi_with_args(wes_t *wes, wescgimethod_t method,
- int argc, wescgiarg_t *args, int blkc, wescgi_t *blks);
-
-/* Envoyer une commande et récupérer la réponse via le protocole M2M.
- * On propose aussi les commandes pour initialiser la couche réseau
- * utilisée par weshd : cela ne sera utilisé que par l'initialisation
- * et la déinitialisation/libération de la ressource de type WES, et non
- * pas par l'utilisateur. */
-
-extern int init_m2m(wes_t *wes);
-extern int deinit_m2m(wes_t *wes);
-
-extern int send_command(wes_t *wes, const char *command,
- char *response, size_t *lenp);
-
#endif
diff --git a/daemon/server.c b/daemon/server.c
index 169e8ed..46462f9 100644
--- a/daemon/server.c
+++ b/daemon/server.c
@@ -37,9 +37,12 @@
#include <weshd.h> /* définitions du protocole depuis `weshd.x` */
/* ---
- * Get the string for an address, for logging.
+ * Utilitaires.
* --- */
+/* `addrstr()`: récupérer la chaîne correspondant à une adresse, pour
+ * du logging. */
+
static const char *addrstr(struct in6_addr *src)
{
static char str[INET6_ADDRSTRLEN + 1] = {0};
@@ -49,13 +52,11 @@ static const char *addrstr(struct in6_addr *src)
#define REQADDR addrstr(&svc_getcaller(req->rq_xprt)->sin6_addr)
-/* ---
- * Macro to get the WES resource from the ID.
- * --- */
+/* Macro pour récupérer l'objet avec un ID. */
-#define GETWES(ID, RET, RESP) { \
+#define GETOBJ(ID, OBJ, RET, RESP) { \
int getwes_err; \
- switch ((getwes_err = get_in_list(list, &wes, ID))) { \
+ switch ((getwes_err = get_in_list(list, &OBJ, ID))) { \
case WROK: \
break; \
case WRNOTFOUND: \
@@ -69,6 +70,28 @@ static const char *addrstr(struct in6_addr *src)
return (RESP); \
}}
+/* `set_obj_to_free()`: Définition du prochain objet à détruire.
+ * Compense le fait que ce ne soient pas les callbacks ci-dessous qui
+ * envoient la réponse et du coup ne puissent pas détruire les objets avant
+ * de les envoyer au client.
+ *
+ * À ne surtout pas utiliser dans un contexte sur plusieurs fils d'exécution
+ * (threads), évidemment… */
+
+static void set_obj_to_free(void *vobj)
+{
+ static wesfreemem_t **lastobj = NULL;
+ wesfreemem_t **obj = (void *)vobj;
+
+ if (lastobj) {
+ (**lastobj)(*((void **)lastobj));
+ lastobj = NULL;
+ }
+
+ if (obj && *obj)
+ lastobj = obj;
+}
+
/* Ici, on stocke les ressources « globales » de sorte à ce que les
* appels de services (svc) puissent les utiliser. */
@@ -328,14 +351,14 @@ wespret_with_wes_t *get_1_svc(wespid_with_wes_flags_t *args,
default:
msg((wlerror, "invalid iftype: %d", wes->iface->type));
resp.ret = WESPRET_INT;
- set_obj_to_free(wes, cfgobj);
+ set_obj_to_free(cfgobj);
return (&resp);
}
/* Tout est bien qui finit bien ! */
resp.ret = WESPRET_OK;
- set_obj_to_free(wes, cfgobj);
+ set_obj_to_free(cfgobj);
return (&resp);
}
@@ -652,7 +675,7 @@ wespret_with_meter_t *get_meter_1_svc(wespid_with_meter_id_t *args,
/* Tout va bien ! */
resp.ret = WESPRET_OK;
- set_obj_to_free(wes, cfg);
+ set_obj_to_free(cfg);
return (&resp);
}
@@ -917,5 +940,6 @@ int run_server(weslist_t *llist)
msg((wlnotice, "Stopping the server."));
svc_destroy(tcp);
+ set_obj_to_free(NULL);
return (0);
}
diff --git a/libwes/include/libwes.h b/libwes/include/libwes.h
new file mode 100644
index 0000000..f3431d6
--- /dev/null
+++ b/libwes/include/libwes.h
@@ -0,0 +1,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 */
diff --git a/daemon/ip/cfg.c b/libwes/src/cfg.c.draft
index 7ea958b..189c9c6 100644
--- a/daemon/ip/cfg.c
+++ b/libwes/src/cfg.c.draft
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * ip/cfg.c -- gestion de la configuration par FTP des serveurs WES.
+ * cfg.c -- gestion de la configuration par FTP des serveurs WES.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -628,12 +628,12 @@ static int delsectionkey(wes_t *wes, const char *section, const char *key)
* Fonctions pour l'utilisateur concernant la configuration.
* --- */
-/* `get_config()`: Récupération d'un élément de configuration. */
+/* `wes_get_config()`: Récupération d'un élément de configuration. */
-int get_config(wes_t *wes, const char *section_src, const char *key_src,
+int wes_get_config(WES *wes, const char *section_src, const char *key_src,
char *buf, size_t len)
{
- int err; wescfgkey_t *cfg;
+ int err; wes_cfg_key_t *cfg;
char section[SECSIZE + 1];
char key[KEYSIZE + 1];
@@ -655,7 +655,7 @@ int get_config(wes_t *wes, const char *section_src, const char *key_src,
/* `set_config()`: Définition d'un élément de configuration. */
-int set_config(wes_t *wes, const char *section_src, const char *key_src,
+int set_config(WES *wes, const char *section_src, const char *key_src,
const char *value_src)
{
int err;
@@ -678,7 +678,7 @@ int set_config(wes_t *wes, const char *section_src, const char *key_src,
/* `apply_config()`: Application de la configuration. */
-int apply_config(wes_t *wes)
+int apply_config(WES *wes)
{
wescfgsec_t *sec;
int err;
@@ -693,7 +693,7 @@ int apply_config(wes_t *wes)
/* `clear_config()`: Vidage de la configuration. */
-int clear_config(wes_t *wes)
+int clear_config(WES *wes)
{
wescfgsec_t *sec;
diff --git a/daemon/ip/cgi.c b/libwes/src/cgi.c
index 3103630..e4d1164 100644
--- a/daemon/ip/cgi.c
+++ b/libwes/src/cgi.c
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * ip/cgi.c -- téléversement et exécution de scripts CGI sur le serveur WES.
+ * cgi.c -- téléversement et exécution de scripts CGI sur le serveur WES.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -61,7 +61,7 @@ struct ucookie {
int ucookie__align;
- const wescgi_t *blocks;
+ const wes_cgi_t *blocks;
size_t off, current_fmt_len;
char command[VARLEN];
@@ -72,7 +72,7 @@ struct ucookie {
* initialisation du bloc s'il y a lieu. */
static inline void init_cookie_block(struct ucookie *cookie,
- const wescgi_t *block)
+ const wes_cgi_t *block)
{
char *var = cookie->command;
size_t len;
@@ -94,7 +94,7 @@ static size_t sendscript_read(char *buffer, size_t blksize, size_t nmemb,
size_t left = blksize * nmemb;
const char *buf; size_t len, elen, off;
- if (cookie->err != WROK || cookie->id >= cookie->num)
+ if (cookie->err != wes_error_ok || cookie->id >= cookie->num)
return (0);
while (left) {
@@ -193,7 +193,7 @@ static size_t sendscript_read(char *buffer, size_t blksize, size_t nmemb,
/* `estimatescriptsize()`: Estimation de la taille du fichier qu'on va
* créer. */
-static curl_off_t estimatescriptsize(int num, const wescgi_t *blocks)
+static curl_off_t estimatescriptsize(int num, const wes_cgi_t *blocks)
{
curl_off_t filesize = 0;
size_t fmtsize;
@@ -212,7 +212,7 @@ static curl_off_t estimatescriptsize(int num, const wescgi_t *blocks)
/* `sendscript()`: Envoi d'un script CGI. */
-static int sendscript(wes_t *wes, int num, const wescgi_t *blocks)
+static int sendscript(WES *wes, int num, const wes_cgi_t *blocks)
{
CURL *curl; CURLcode cres;
char path[50];
@@ -221,8 +221,8 @@ static int sendscript(wes_t *wes, int num, const wescgi_t *blocks)
/* Initialisation du handle de la libcurl. */
- sprintf(path, "/wh%d.cgi", wes->base.id);
- if ((err = open_ftp_handle(wes, &curl, path)))
+ sprintf(path, "/whscript.cgi");
+ if ((err = wes_open_ftp_handle(wes, &curl, path)))
return (err);
/* Initialisation du cookie. */
@@ -230,7 +230,7 @@ static int sendscript(wes_t *wes, int num, const wescgi_t *blocks)
cookie.state = 0;
cookie.step = UST_REQ;
cookie.id = 0;
- cookie.err = WROK;
+ cookie.err = wes_error_ok;
cookie.off = 0;
cookie.num = num;
cookie.blocks = blocks;
@@ -267,7 +267,7 @@ static int sendscript(wes_t *wes, int num, const wescgi_t *blocks)
case CURLE_OUT_OF_MEMORY:
/* Une allocation a échoué. */
- return (WRALLOC);
+ return (wes_error_alloc);
case CURLE_COULDNT_RESOLVE_HOST: /* FALLTHRU */
case CURLE_COULDNT_CONNECT: /* FALLTHRU */
@@ -276,17 +276,17 @@ static int sendscript(wes_t *wes, int num, const wescgi_t *blocks)
case CURLE_RECV_ERROR:
/* Quelque chose s'est mal passé sur la transmission. */
- return (WRNOHOST);
+ return (wes_error_nohost);
case CURLE_LOGIN_DENIED:
- return (WRAUTH);
+ return (wes_error_auth);
default:
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
}
- return (WROK);
+ return (wes_error_ok);
}
/* ---
@@ -309,7 +309,7 @@ static size_t delscript_write(char *buffer, size_t blksize, size_t nmemb,
/* `delscript()`: Suppression d'un script CGI. */
-static int delscript(wes_t *wes)
+static int delscript(WES *wes)
{
char hdr[20];
CURL *curl; CURLcode cres;
@@ -318,12 +318,12 @@ static int delscript(wes_t *wes)
/* Initialisation du handle de la libcurl. */
- if ((err = open_ftp_handle(wes, &curl, "/")))
+ if ((err = wes_open_ftp_handle(wes, &curl, "/")))
return (err);
/* Préparation des méta-informations. */
- sprintf(hdr, "DELE wh%d.cgi", wes->base.id);
+ sprintf(hdr, "DELE whscript.cgi");
headerlist = curl_slist_append(headerlist, hdr);
@@ -343,7 +343,7 @@ static int delscript(wes_t *wes)
case CURLE_OUT_OF_MEMORY:
/* Une allocation a échoué. */
- return (WRALLOC);
+ return (wes_error_alloc);
case CURLE_COULDNT_RESOLVE_HOST: /* FALLTHRU */
case CURLE_COULDNT_CONNECT: /* FALLTHRU */
@@ -352,17 +352,17 @@ static int delscript(wes_t *wes)
case CURLE_RECV_ERROR:
/* Quelque chose s'est mal passé sur la transmission. */
- return (WRNOHOST);
+ return (wes_error_nohost);
case CURLE_LOGIN_DENIED:
- return (WRAUTH);
+ return (wes_error_auth);
default:
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
}
- return (WROK);
+ return (wes_error_ok);
}
#endif
@@ -374,13 +374,13 @@ static int delscript(wes_t *wes)
/* `open_http_exec_handle()`: ouverture d'un handle de récupération de
* script CGI, avec arguments */
-static int open_http_exec_handle(wes_t *wes, CURL **curlp,
- wescgimethod_t method, int argc, wescgiarg_t *args)
+static int open_http_exec_handle(WES *wes, CURL **curlp,
+ wes_cgi_method_t method, int argc, wes_cgi_arg_t *args)
{
char path[20];
- sprintf(path, "/wh%d.cgi", wes->base.id);
- return (open_http_handle(wes, curlp, method, path, argc, args));
+ sprintf(path, "/whscript.cgi");
+ return (wes_open_http_handle(wes, curlp, method, path, argc, args));
}
/* Cookie d'écriture (`ecookie` comme `execution cookie`).
@@ -400,7 +400,7 @@ static int open_http_exec_handle(wes_t *wes, CURL **curlp,
* je cherche juste à ce que ça marche. */
struct ecookie {
- wescgi_t *blocks;
+ wes_cgi_t *blocks;
char *sepbuf;
int id, num, err, bufid;
@@ -415,7 +415,7 @@ struct ecookie {
static size_t execscript_write(char *buffer, size_t blksize, size_t nmemb,
struct ecookie *cookie)
{
- wescgi_t *block;
+ wes_cgi_t *block;
int car;
size_t left, len;
@@ -582,8 +582,8 @@ static size_t execscript_write(char *buffer, size_t blksize, size_t nmemb,
/* `execscript()`: Exécution d'un script CGI via HTTP. */
-static int execscript(wes_t *wes, wescgimethod_t method,
- int argc, wescgiarg_t *args, int blkc, wescgi_t *blocks)
+static int execscript(WES *wes, wes_cgi_method_t method,
+ int argc, wes_cgi_arg_t *args, int blkc, wes_cgi_t *blocks)
{
CURL *curl; CURLcode cres;
char sepbuf[sizeof(REQSEP) + 1];
@@ -600,7 +600,7 @@ static int execscript(wes_t *wes, wescgimethod_t method,
cookie.id = 0;
cookie.num = blkc;
cookie.blocks = blocks;
- cookie.err = 0;
+ cookie.err = wes_error_ok;
cookie.sepbuf = sepbuf;
cookie.buffers[1] = sepbuf;
memcpy(cookie.buffers[1], REQSEP, sizeof(REQSEP));
@@ -642,7 +642,7 @@ static int execscript(wes_t *wes, wescgimethod_t method,
case CURLE_OUT_OF_MEMORY:
/* Une allocation a échoué. */
- return (WRALLOC);
+ return (wes_error_alloc);
case CURLE_COULDNT_RESOLVE_HOST: /* FALLTHRU */
case CURLE_COULDNT_CONNECT: /* FALLTHRU */
@@ -651,29 +651,29 @@ static int execscript(wes_t *wes, wescgimethod_t method,
case CURLE_RECV_ERROR:
/* Quelque chose s'est mal passé sur la transmission. */
- return (WRNOHOST);
+ return (wes_error_nohost);
case CURLE_LOGIN_DENIED:
- return (WRAUTH);
+ return (wes_error_auth);
default:
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
}
- return (WROK);
+ return (wes_error_ok);
}
/* ---
* Interface utilisateur.
* --- */
-/* `get_cgi_with_args()`: Téléversement et exécution de scripts CGI sur le
+/* `wes_get_cgi_with_args()`: Téléversement et exécution de scripts CGI sur le
* serveur WES, avec gestion d'arguments GET et POST. */
-int get_cgi_with_args(wes_t *wes, wescgimethod_t method,
- int argc, wescgiarg_t *args,
- int blkc, wescgi_t *blocks)
+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 *blocks)
{
int err, nerr = 0;
#if DELETE_SCRIPTS
@@ -684,7 +684,7 @@ int get_cgi_with_args(wes_t *wes, wescgimethod_t method,
* pour rien. */
if (!argc && !blkc)
- return (WROK);
+ return (wes_error_ok);
/* Génération et téléversement du script. */
@@ -715,37 +715,37 @@ int get_cgi_with_args(wes_t *wes, wescgimethod_t method,
return (err ? err : nerr);
}
-/* `get_form()`: Exécution d'une requête avec arguments via GET. */
+/* `wes_get_form()`: Exécution d'une requête avec arguments via GET. */
-int get_form(wes_t *wes, int argc, wescgiarg_t *args)
+int wes_get_form(WES *wes, int argc, wes_cgi_arg_t *args)
{
- return (get_cgi_with_args(wes, WESCGIMETHOD_GET, argc, args,
+ return (wes_get_cgi_with_args(wes, WESCGIMETHOD_GET, argc, args,
0, NULL));
}
-/* `post_form()`: Exécution d'une requête avec arguments via POST. */
+/* `wes_post_form()`: Exécution d'une requête avec arguments via POST. */
-int post_form(wes_t *wes, int argc, wescgiarg_t *args)
+int wes_post_form(WES *wes, int argc, wes_cgi_arg_t *args)
{
- return (get_cgi_with_args(wes, WESCGIMETHOD_POST, argc, args,
+ return (wes_get_cgi_with_args(wes, WESCGIMETHOD_POST, argc, args,
0, NULL));
}
-/* `get_cgi()`: Téléversement et exécution de scripts CGI sur le
+/* `wes_get_cgi()`: Téléversement et exécution de scripts CGI sur le
* serveur WES. */
-int get_cgi(wes_t *wes, int blkc, wescgi_t *blocks)
+int wes_get_cgi(WES *wes, int blkc, wes_cgi_t *blocks)
{
- return (get_cgi_with_args(wes, WESCGIMETHOD_GET, 0, NULL,
+ return (wes_get_cgi_with_args(wes, WESCGIMETHOD_GET, 0, NULL,
blkc, blocks));
}
-/* `get_cgi_var()`: Récupération de valeurs par CGI. */
+/* `wes_get_cgi_var()`: Récupération de valeurs par CGI. */
-int get_cgi_var(wes_t *wes, const char *var, const char *format,
+int wes_get_cgi_var(WES *wes, const char *var, const char *format,
char *buffer, size_t *len)
{
- wescgi_t cgi;
+ wes_cgi_t cgi;
int err;
cgi.var = var;
@@ -753,11 +753,11 @@ int get_cgi_var(wes_t *wes, const char *var, const char *format,
cgi.buffer = buffer;
cgi.len = *len;
- if ((err = get_cgi(wes, 1, &cgi)))
+ if ((err = wes_get_cgi(wes, 1, &cgi)))
return (err);
*len = cgi.full;
if (cgi.full > cgi.len)
- return (WRSPACE);
- return (WROK);
+ return (wes_error_space);
+ return (wes_error_ok);
}
diff --git a/daemon/ip/csv.c b/libwes/src/csv.c
index 83e858f..5056748 100644
--- a/daemon/ip/csv.c
+++ b/libwes/src/csv.c
@@ -30,15 +30,15 @@
#include "internals.h"
#define validfieldcar(CAR) (isascii(CAR) && (CAR) != '\r')
-/* `init_csv()`: Initialise le cookie de récupération de fichiers CSV.
+/* `wes_init_csv()`: Initialise le cookie de récupération de fichiers CSV.
* Prend le nombre de champs à remplir, les buffers et leur longueur (qui
* _DOIT_ faire au moins un caractère pour contenir celui de terminaison '\0'),
* ainsi que le callback à appeler en cas d'entrée lue (y compris la
* première qui donne le nom des champs, au callback de détecter ça). */
-int init_csv(wescsv_t *cookie, int separator,
+int wes_init_csv(wes_csv_t *cookie, int separator,
int numfields, char * const buffers[], size_t const lens[],
- wescsventry_t *callback, void *cbcookie)
+ wes_csv_entry_t *callback, void *cbcookie)
{
cookie->num = numfields;
cookie->buffers = buffers;
@@ -52,14 +52,14 @@ int init_csv(wescsv_t *cookie, int separator,
cookie->off = 0;
cookie->err = 0;
- return (WROK);
+ return (wes_error_ok);
}
-/* `read_csv()`: Callback de contribution à la lecture de CSV. */
+/* `wes_read_csv()`: Callback de contribution à la lecture de CSV. */
-size_t read_csv(char *buf, size_t size, size_t nmemb, void *rawcookie)
+size_t wes_read_csv(char *buf, size_t size, size_t nmemb, void *rawcookie)
{
- wescsv_t *cookie = (void*)rawcookie;
+ wes_csv_t *cookie = (void*)rawcookie;
size_t left = size * nmemb, inisz = left;
int car, err;
@@ -109,14 +109,14 @@ size_t read_csv(char *buf, size_t size, size_t nmemb, void *rawcookie)
return (nmemb);
}
-/* `end_csv()`: Termine le traitement d'un CSV. */
+/* `wes_end_csv()`: Termine le traitement d'un CSV. */
-int end_csv(wescsv_t *cookie)
+int wes_end_csv(wes_csv_t *cookie)
{
int err;
if (!cookie->id && !cookie->off)
- return (WROK);
+ return (wes_error_ok);
if (cookie->id < cookie->num)
cookie->buffers[cookie->id][cookie->off] = '\0';
@@ -135,5 +135,5 @@ int end_csv(wescsv_t *cookie)
cookie->id = 0;
cookie->off = 0;
- return (WROK);
+ return (wes_error_ok);
}
diff --git a/daemon/ip/data.c b/libwes/src/data.c
index 997031c..f473e10 100644
--- a/daemon/ip/data.c
+++ b/libwes/src/data.c
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * ip/data.c -- gestion des données par FTP des serveurs WES.
+ * data.c -- gestion des données par FTP des serveurs WES.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -47,7 +47,7 @@
* `alt` est une valeur d'URL alternative, 0 s'il s'agit de l'ancien format,
* 1 s'il s'agit du nouveau. */
-static int get_request(wes_t *wes, CURL **handlep, int kind, int alt,
+static int get_request(WES *wes, CURL **handlep, int kind, int alt,
int year, int mon, int dom)
{
const char *alts[3][4] = {{
@@ -69,10 +69,10 @@ static int get_request(wes_t *wes, CURL **handlep, int kind, int alt,
/* Création de l'URL. */
if (!alts[kind][alt])
- return (WRNOITER);
+ return (wes_error_iter);
sprintf(path, alts[kind][alt], year, mon, dom);
- return (open_ftp_handle(wes, handlep, path));
+ return (wes_open_ftp_handle(wes, handlep, path));
}
/* `gethourmin()`: récupérer l'heure et la minute à partir d'un champ
@@ -84,26 +84,26 @@ static int gethourmin(const char *from, int *hourp, int *minp)
if (!isdigit(from[0]) || !isdigit(from[1]) || from[2] != ':'
|| !isdigit(from[3]) || !isdigit(from[4]) || from[5] != '\0')
- return (WRUNKNOWN);
+ return (wes_error_unknown);
hour = (from[0] - '0') * 10 + (from[1] - '0');
min = (from[3] - '0') * 10 + (from[4] - '0');
if (hour >= 24 || min >= 60)
- return (WRUNKNOWN);
+ return (wes_error_unknown);
*hourp = hour;
*minp = min;
- return (WROK);
+ return (wes_error_ok);
}
/* `getentry()`: Récupération d'une entrée de donnée correspondant à
* un couple (heures, minutes) de la journée. Si l'entrée n'existe pas,
* elle est créée et initialisée. */
-static int getentry(wesdataspan_t *span, wesdata_t **dataresp,
+static int getentry(wes_data_span_t *span, wes_data_t **dataresp,
int hour, int min)
{
- wesdata_t **datap, *data;
+ wes_data_t **datap, *data;
for (datap = &span->data; (data = *datap); datap = &data->next) {
if (data->hour > hour || (data->hour == hour && data->min >= min))
@@ -111,12 +111,12 @@ static int getentry(wesdataspan_t *span, wesdata_t **dataresp,
}
if (data && data->hour == hour && data->min == min) {
*dataresp = data;
- return (WROK);
+ return (wes_error_ok);
}
- data = malloc(sizeof(wesdata_t));
+ data = malloc(sizeof(wes_data_t));
if (!data)
- return (WRALLOC);
+ return (wes_error_alloc);
data->next = *datap;
data->hour = hour;
@@ -125,7 +125,7 @@ static int getentry(wesdataspan_t *span, wesdata_t **dataresp,
*datap = data;
*dataresp = data;
- return (WROK);
+ return (wes_error_ok);
}
/* ---
@@ -136,23 +136,24 @@ static int getentry(wesdataspan_t *span, wesdata_t **dataresp,
* appliqué aux données d'impulsions. Récupère les buffers et la section
* et ajoute l'entrée à la section. */
-static int gatherspanpl_add(wesdataspan_t *span, int line,
+static int gatherspanpl_add(wes_data_span_t *span, int line,
int fdc, char **fdv)
{
- int err, i; wesdata_t *ent;
+ int err, i;
+ wes_data_t *ent;
int hour, min;
/* On ignore la première ligne, qui ne contient que les noms des champs. */
if (line == 0)
- return (WROK);
+ return (wes_error_ok);
/* On obtient la date et l'heure, et on obtient l'entrée correspondante
* dans la liste de données. Si la date et l'heure sont invalides,
* on se contente d'ignorer l'entrée courante. */
if (!fdc || (err = gethourmin(fdv[0], &hour, &min)))
- return (WROK);
+ return (wes_error_ok);
/* On récupère un pointeur sur l'entrée. */
@@ -172,30 +173,31 @@ static int gatherspanpl_add(wesdataspan_t *span, int line,
}
}
- return (WROK);
+ return (wes_error_ok);
}
/* `gatherspanpc_add()`: Callback de `getcsv()` pour `gatherspandata()`
* appliqué aux données des pinces ampèremétriques. Récupère les buffers
* et la section et ajoute l'entrée à la section. */
-static int gatherspanpc_add(wesdataspan_t *span, int line,
+static int gatherspanpc_add(wes_data_span_t *span, int line,
int fdc, char **fdv)
{
- int err, i; wesdata_t *ent;
+ int err, i;
+ wes_data_t *ent;
int hour, min;
/* On ignore la première ligne, qui ne contient que les noms des champs. */
if (line == 0)
- return (WROK);
+ return (wes_error_ok);
/* On obtient la date et l'heure, et on obtient l'entrée correspondante
* dans la liste de données. Si la date et l'heure sont invalides,
* on se contente d'ignorer l'entrée courante. */
if (!fdc || (err = gethourmin(fdv[0], &hour, &min)))
- return (WROK);
+ return (wes_error_ok);
/* On récupère un pointeur sur l'entrée. */
@@ -215,30 +217,31 @@ static int gatherspanpc_add(wesdataspan_t *span, int line,
}
}
- return (WROK);
+ return (wes_error_ok);
}
/* `gatherspanti_add()`: Callback de `getcsv()` pour `gatherspandata()`
* appliqué aux données de téléinfo. Récupère les buffers et la section
* et ajoute l'entrée à la section. */
-static int gatherspanti_add(wesdataspan_t *span, int line,
+static int gatherspanti_add(wes_data_span_t *span, int line,
int fdc, char **fdv)
{
- int err; wesdata_t *ent;
+ int err;
+ wes_data_t *ent;
int hour, min;
/* On ignore la première ligne, qui ne contient que les noms des champs. */
if (line == 0)
- return (WROK);
+ return (wes_error_ok);
/* On obtient la date et l'heure, et on obtient l'entrée correspondante
* dans la liste de données. Si la date et l'heure sont invalides,
* on se contente d'ignorer l'entrée courante. */
if (!fdc || (err = gethourmin(fdv[0], &hour, &min)))
- return (WROK);
+ return (wes_error_ok);
/* On récupère un pointeur sur l'entrée. */
@@ -251,7 +254,7 @@ static int gatherspanti_add(wesdataspan_t *span, int line,
if (fdc <= 2 || !strcmp(fdv[1], "PAS de teleinfo")) {
ent->flags &= ~WDFTIPLUG;
- return (WROK);
+ return (wes_error_ok);
}
ent->flags |= WDFTIPLUG;
@@ -283,7 +286,7 @@ static int gatherspanti_add(wesdataspan_t *span, int line,
else
ent->pa = 0;
- return (WROK);
+ return (wes_error_ok);
}
/* ---
@@ -292,9 +295,9 @@ static int gatherspanti_add(wesdataspan_t *span, int line,
/* `emptyspan()`: Vidage d'une journée de données en local. */
-static int emptyspan(wesdataspan_t *span)
+static int emptyspan(wes_data_span_t *span)
{
- wesdata_t *data;
+ wes_data_t *data;
while ((data = span->data)) {
span->data = data->next;
@@ -302,18 +305,18 @@ static int emptyspan(wesdataspan_t *span)
free(data);
}
- return (WROK);
+ return (wes_error_ok);
}
/* `gatherspandata()`: Récupération des données concernant une section
* pour une période. */
-static int gatherspandata(wes_t *wes, wesdataspan_t *span,
- int kind, wescsventry_t *cb, int numfields,
+static int gatherspandata(WES *wes, wes_data_span_t *span,
+ int kind, wes_csv_entry_t *cb, int numfields,
char * const buffers[], size_t const lens[])
{
CURL *curl; CURLcode cres;
- wescsv_t csv;
+ wes_csv_t csv;
int alt, err;
for (alt = 0;; alt++) {
@@ -321,14 +324,14 @@ static int gatherspandata(wes_t *wes, wesdataspan_t *span,
if ((err = get_request(wes, &curl, kind, alt, span->year,
span->mon, span->dom))) {
- if (err == WRNOITER)
+ if (err == wes_error_iter)
break;
return (err);
}
- init_csv(&csv, ',', numfields, buffers, lens, cb, span);
+ wes_init_csv(&csv, ',', numfields, buffers, lens, cb, span);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &read_csv);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &wes_read_csv);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &csv);
cres = curl_easy_perform(curl);
@@ -348,7 +351,7 @@ static int gatherspandata(wes_t *wes, wesdataspan_t *span,
return (csv.err);
default:
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
}
@@ -358,7 +361,7 @@ static int gatherspandata(wes_t *wes, wesdataspan_t *span,
* puisque la période peut ne pas avoir été prise.
* On se contente donc de renvoyer OK. */
- return (WROK);
+ return (wes_error_ok);
}
/* `gatherspan()`: Récupération de ce qu'il faut pour une période.
@@ -366,7 +369,7 @@ static int gatherspandata(wes_t *wes, wesdataspan_t *span,
* format moderne, soit dans l'ancien format (ou format « alternatif ») si
* le premier n'existe pas. */
-static int gatherspan(wes_t *wes, wesdataspan_t *span)
+static int gatherspan(WES *wes, wes_data_span_t *span)
{
char timebuf[6], fl[4][10], ti[4][20];
char * const pl_buffers[5] = {timebuf, fl[0], fl[1], fl[2], fl[3]};
@@ -383,33 +386,34 @@ static int gatherspan(wes_t *wes, wesdataspan_t *span)
return (err);
/* Ensuite, on récupère les données concernant les impulsions. */
+
if ((err = gatherspandata(wes, span, KIND_PLS,
- (wescsventry_t*)&gatherspanpl_add, 5, pl_buffers, pl_lens)))
+ (wes_csv_entry_t*)&gatherspanpl_add, 5, pl_buffers, pl_lens)))
return (err);
/* On enchaîne avec les données concernant les pinces ampèremétriques. */
if ((err = gatherspandata(wes, span, KIND_PCE,
- (wescsventry_t*)&gatherspanpc_add, 5, pc_buffers, pc_lens)))
+ (wes_csv_entry_t*)&gatherspanpc_add, 5, pc_buffers, pc_lens)))
return (err);
/* Puis on récupère les données concernant les compteurs via Téléinfo. */
if ((err = gatherspandata(wes, span, KIND_TLI,
- (wescsventry_t*)&gatherspanti_add, 5, ti_buffers, ti_lens)))
+ (wes_csv_entry_t*)&gatherspanti_add, 5, ti_buffers, ti_lens)))
return (err);
/* On est bons ! */
- return (WROK);
+ return (wes_error_ok);
}
/* `getspan()`: Récupération du set de données pour un jour donné. */
-static int getspan(wes_t *wes, wesdataspan_t **spanresp, int year,
+static int getspan(WES *wes, wes_data_span_t **spanresp, int year,
int mon, int dom)
{
- wesdataspan_t **spanp, *span;
+ wes_data_span_t **spanp, *span;
int err;
/* Partons à la recherche de l'entrée. */
@@ -423,14 +427,14 @@ static int getspan(wes_t *wes, wesdataspan_t **spanresp, int year,
if (span && span->year == year && span->mon == mon && span->dom == dom) {
/* TODO: si c'est à la date d'aujourd'hui, l'actualiser ? */
*spanresp = span;
- return (WROK);
+ return (wes_error_ok);
}
/* L'entrée n'existe pas, mais on sait où la créer, alors créons-la. */
- span = malloc(sizeof(wesdataspan_t));
+ span = malloc(sizeof(*span));
if (!span)
- return (WRALLOC);
+ return (wes_error_alloc);
span->next = *spanp;
span->data = NULL;
@@ -449,29 +453,20 @@ static int getspan(wes_t *wes, wesdataspan_t **spanresp, int year,
*spanp = span;
*spanresp = span;
- return (WROK);
+ return (wes_error_ok);
}
/* ---
* Fonction de l'interface utilisateur.
* --- */
-int get_data(wes_t *wes, wesdata_t *data, struct tm *dt)
+int wes_get_data(WES *wes, wes_data_t *data, int year, int mon, int dom,
+ int hour, int min)
{
- wesdataspan_t *span;
- wesdata_t *resp;
- int year, mon, dom, hour, min;
+ wes_data_span_t *span;
+ wes_data_t *resp;
int err;
- /* Normalisation de la date, puis récupération des données. */
-
- mktime(dt);
- year = dt->tm_year + 1900;
- mon = dt->tm_mon + 1;
- dom = dt->tm_mday;
- hour = dt->tm_hour;
- min = dt->tm_min;
-
/* Récupération des données pour la date. */
if ((err = getspan(wes, &span, year, mon, dom)))
@@ -485,6 +480,6 @@ int get_data(wes_t *wes, wesdata_t *data, struct tm *dt)
}
/* TODO: do this properly */
- memcpy(data, resp, sizeof(wesdata_t));
- return (WROK);
+ memcpy(data, resp, sizeof(wes_data_t));
+ return (wes_error_ok);
}
diff --git a/libwes/src/error.c b/libwes/src/error.c
new file mode 100644
index 0000000..5e6c8ec
--- /dev/null
+++ b/libwes/src/error.c
@@ -0,0 +1,54 @@
+/* ****************************************************************************
+ * error.c -- utilitaires pour les erreurs.
+ * 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.
+ * ************************************************************************* */
+#include "internals.h"
+
+static char const *error_descriptions[16] = {
+ "no error",
+ "unknown error",
+ "unauthorized operation",
+ "a memory allocation has failed",
+ "one of the arguments was found invalid",
+ "no more elements in iterator",
+ NULL, NULL, NULL, NULL,
+
+ "the host could not be joined",
+ "the connexion was reset",
+ "a resource could not be found",
+ "a delay has expired",
+ "an authentication event has failed",
+ "not enough space was available"
+};
+
+char const *wes_error_string(int error)
+{
+ if (error >= 16 || !error_descriptions[error])
+ return ("unrecognized error");
+ return (error_descriptions[error]);
+}
diff --git a/libwes/src/internals.h b/libwes/src/internals.h
new file mode 100644
index 0000000..10ded3c
--- /dev/null
+++ b/libwes/src/internals.h
@@ -0,0 +1,235 @@
+/* ****************************************************************************
+ * internals.h -- mécanismes internes de la libwes.
+ * 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 LOCAL_INTERNALS_H
+# define LOCAL_INTERNALS_H 20180611
+# include <stdlib.h>
+# include <string.h>
+# include <errno.h>
+# include <libwes.h>
+# include <curl/curl.h>
+
+/* En-têtes spécifiques POSIX. */
+
+# include <unistd.h>
+# include <arpa/inet.h>
+# include <netinet/in.h>
+# include <netinet/tcp.h>
+# include <sys/socket.h>
+# include <sys/ioctl.h>
+
+/* ---
+ * Logging.
+ * --- */
+
+/* Obtention du nom d'une fonction. */
+
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+# define LOGFUNC __func__
+# elif !defined(__STRICT_ANSI__) && GNUC_PREREQ(2, 0)
+# define LOGFUNC __FUNCTION__
+# else
+# define LOGFUNC NULL
+# endif
+
+/* Non seulement les versions en minuscules sont plus faciles à taper, mais
+ * elles sont faites pour être utilisées avec les macros `msg` et `mem`.
+ *
+ * (et parce que les majuscules c'est un peu lourd à taper, je fais aussi
+ * la version en minuscules. en fait depuis ça a pris un rôle différent,
+ * mais bon) */
+
+# define wldebug 0, LOGFUNC
+# define wlinfo 0, LOGFUNC
+# define wlwarn 10, LOGFUNC
+# define wlerror 20, LOGFUNC
+# define wlfatal 30, LOGFUNC
+# define wlnotice 40, LOGFUNC
+
+/* Fonctions principales.
+ * Elles sont cachées derrière les macros en-dessous. */
+
+extern void wes_log_msg(wes_loglevel_t loglevel, const char *func,
+ const char *format, ...);
+extern void wes_log_mem(wes_loglevel_t loglevel, const char *func,
+ const void *m, size_t n);
+
+/* Macros principales, qui redirigent vers les fonctions de log.
+ * Utilisez les doubles parenthèses de la façon suivante :
+ *
+ * msg((wldebug, "ma %schaîne de formattage %d", "merveilleuse ", 1));
+ * mem((wlwarn, ma_zone_de_memoire, la_taille_de_ma_zone_de_memoire));
+ *
+ * Il s'agit de macros variadiques, mais compatibles K&R/ANSI C. */
+
+# define msg(ARGS) wes_log_msg ARGS
+# define mem(ARGS) wes_log_mem ARGS
+
+/* ---
+ * Déclaration de la structure WES.
+ * --- */
+
+# define WSK_NONE 0
+# define WSK_TCP 1
+# define WSK_UDP 2
+
+struct WES {
+ /* Identifiants pour les serveurs HTTP et FTP. */
+
+ char *http_name;
+ char *http_pass;
+
+ char *ftp_name;
+ char *ftp_pass;
+
+ /* Canaux (handles de la libcurl) pour le HTTP et FTP. */
+
+ CURL *http_handle;
+ CURL *ftp_handle;
+
+#if 0
+ /* Éléments pour la gestion de la configuration.
+ * Il s'agit d'une liste chaînée de sections. */
+
+ wes_cfg_sec_t *sections;
+#endif
+
+ /* Éléments pour la gestion des données.
+ * Il s'agit d'une liste chaînée de données regroupées par date. */
+
+ wes_data_span_t *data;
+
+ /* Adresse IP cross-platform pour joindre le serveur WES. */
+
+ wes_addr_t addr;
+
+ /* Éléments pour le protocole M2M.
+ * `sock_type` représente le type de la socket parmi les constantes
+ * en `WSK_*` précisées ci-dessus.
+ * `sock_buf` est le buffer de réception, alloué dynamiquement à
+ * `WSBUFSIZE` lorsque l'on se sert de la socket.
+ * La socket et ses données, qui dépendent de la plateforme, sont
+ * stockées dans l'union `platform`. */
+
+ int sock_type;
+ char *sock_buf;
+ size_t sock_buflen;
+
+ /* Éléments spécifiques à des platformes données. */
+
+ union {
+ struct {
+ /* Sockets BSD.
+ * On garde le file descriptor et l'adresse (pour l'UDP et
+ * sa commande associée `sendto()`). */
+
+ int sock;
+
+ int wes_posix__align;
+
+ struct sockaddr *sockaddr;
+ socklen_t sockaddr_size;
+
+ union {
+ struct sockaddr_in ip;
+ struct sockaddr_in6 ip6;
+ } sock_addr;
+ } posix;
+ } platform;
+};
+
+/* ---
+ * Décodage de fichiers CSV.
+ * --- */
+
+/* Cookie et type du callback.
+ * Le callback est appelé pour chaque ligne qui a été lue.
+ * Le `fdc` passé (field count) ne donne que le nombre de valeurs remplies,
+ * pas le nombre total de champs qu'il y avait dans la ligne. */
+
+typedef int wes_csv_entry_t (void *cookie, int line, int fdc,
+ char * const fdv[]);
+
+typedef struct wes_csv {
+ int num, id, line, err;
+ char * const *buffers;
+ size_t const *lens;
+ wes_csv_entry_t *callback;
+ void *cbcookie;
+
+ size_t off;
+ int separator;
+
+ int wes_csv__align;
+} wes_csv_t;
+
+/* `wes_init_csv()` permet d'initialiser le cookie avec les buffers, quelques
+ * tweaks de lecture et le callback à utiliser. */
+
+extern int wes_init_csv(wes_csv_t *cookie, int separator,
+ int numfields, char * const buffers[], size_t const lens[],
+ wes_csv_entry_t *callback, void *cbcookie);
+
+/* `wes_read_csv()` sert de callback à la libcurl par exemple (ressemble donc
+ * à `fwrite()`), pour lire du contenu ;
+ * `wes_end_csv()` termine la lecture du fichier en appelant si besoin une
+ * dernière fois le callback. */
+
+extern size_t wes_read_csv(char *buf, size_t size, size_t nmemb, void *cookie);
+extern int wes_end_csv(wes_csv_t *cookie);
+
+/* ---
+ * Autres utilitaires.
+ * --- */
+
+/* Ouverture des canaux sur lesquels les requêtes sont faites. */
+
+extern int wes_open_http_handle(WES *wes, CURL **handlep,
+ wes_http_method_t method, char const *path, int argc,
+ wes_http_arg_t *args);
+extern int wes_open_ftp_handle(WES *wes, CURL **handlep, char const *path);
+
+#if 0 /* INDEV */
+/* Récupérer et définir la valeur d'une option de configuration sur le
+ * serveur WES. La « section » correspond au fichier dans le dossier `CFG/`
+ * accessible sur le serveur FTP du serveur WES. */
+
+extern int wes_get_config(WES *wes, const char *section, const char *key,
+ char *buf, size_t len);
+extern int wes_set_config(WES *wes, const char *section, const char *key,
+ const char *value);
+
+/* Appliquer et retirer l'intégralité de la copie locale de
+ * la configuration. */
+
+extern int wes_apply_config(WES *wes);
+extern int wes_clear_config(WES *wes);
+#endif
+
+#endif /* LOCAL_INTERNALS_H */
diff --git a/libwes/src/log.c b/libwes/src/log.c
new file mode 100644
index 0000000..931cc94
--- /dev/null
+++ b/libwes/src/log.c
@@ -0,0 +1,221 @@
+/* ****************************************************************************
+ * log.c -- système de logging pour le démon de gestion de serveurs WES.
+ * 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.
+ * ************************************************************************* */
+#include "internals.h"
+#ifndef DEFAULT_LOGLEVEL
+# define DEFAULT_LOGLEVEL wes_log_info
+#endif
+
+static wes_loglevel_t current_log_level = DEFAULT_LOGLEVEL;
+
+/* `decode_log_level()`: décoder une chaîne. */
+
+static wes_loglevel_t decode_log_level(char const *text)
+{
+ if (!strcmp(text, "debug") || !strcmp(text, "info"))
+ return (wes_log_debug);
+ if (!strcmp(text, "warn"))
+ return (wes_log_warn);
+ if (!strcmp(text, "error"))
+ return (wes_log_error);
+ if (!strcmp(text, "fatal"))
+ return (wes_log_fatal);
+ return (wes_log_notice);
+}
+
+/* `wes_set_log_level()`: définir le niveau de logging minimum. */
+
+void wes_set_log_level(char const *level)
+{
+ current_log_level = decode_log_level(level);
+}
+
+/* `islog()`: vérifier si l'on doit logger un message ou non. */
+
+static int islog(wes_loglevel_t loglevel)
+{
+ return (loglevel >= current_log_level);
+}
+
+/* ---
+ * Affichage simple.
+ * --- */
+
+/* `loglevel_tostring()`: Récupération de la chaîne correspondant à un
+ * niveau de log. */
+
+static const char *loglevel_tostring(wes_loglevel_t loglevel)
+{
+ if (loglevel <= wes_log_debug)
+ return ("debug");
+ else if (loglevel <= wes_log_warn)
+ return ("warn");
+ else if (loglevel <= wes_log_error)
+ return ("error");
+ else if (loglevel <= wes_log_fatal)
+ return ("fatal");
+ else
+ return ("notice");
+}
+
+/* `log_prefix()`: Affichage du préfixe pour une ligne. */
+
+static void log_prefix(wes_loglevel_t loglevel, char const *func)
+{
+ if (func && loglevel <= wes_log_fatal)
+ fprintf(stderr, "\r[weshd %5s] %s: ",
+ loglevel_tostring(loglevel), func);
+ else
+ fprintf(stderr, "\r[weshd %5s] ",
+ loglevel_tostring(loglevel));
+}
+
+/* `wes_log_msg()`: Affichage d'un message. */
+
+void wes_log_msg(wes_loglevel_t loglevel, const char *func,
+ const char *format, ...)
+{
+ va_list args;
+ int shouldlog = islog(loglevel);
+
+ /* put the prefix */
+ if (shouldlog)
+ log_prefix(loglevel, func);
+
+ /* put the main part */
+ va_start(args, format);
+ if (shouldlog) {
+ vfprintf(stderr, format, args);
+ fputc('\n', stderr);
+ }
+ va_end(args);
+}
+
+/* ---
+ * Affichage d'une zone de mémoire.
+ * --- */
+
+/* `log_putascii()`: mettre un nombre en ASCII-hex, dans un champ de
+ * n caractères. */
+
+static void log_putascii(unsigned char *p, unsigned long i, int n)
+{
+ p += (n - 1);
+ while (n--) {
+ int j = i % 16;
+ *p-- = (unsigned char)(j >= 10 ? j - 10 + 'A' : j + '0');
+ i /= 16;
+ }
+}
+
+/* `log_mem_hex()`: affiche la représentation en hexadécimal de deux octets
+ * maximum. */
+
+static void log_mem_hex(char *s, const unsigned char *m, size_t n)
+{
+ size_t l = 0;
+ while (l < 8) {
+ /* Mise du nombre sous forme hexadécimale. */
+ if (n) {
+ log_putascii((unsigned char*)s, *m++, 2);
+ s += 2;
+ } else {
+ *s++ = ' ';
+ *s++ = ' ';
+ }
+
+ /* Décrémentation de la taille de la zone de mémoire à traiter. */
+ n -= !!n;
+
+ /* On va au prochain caractère si s est à la fin d'un groupe. */
+ if (l++ % 2)
+ s++;
+ }
+}
+
+/* `log_mem_asc()`: afficher l'interprétation ASCII d'un maximum de
+ * deux octets. */
+
+static void log_mem_asc(char *s, const unsigned char *m, size_t n)
+{
+ size_t l = 0;
+
+ while (n-- && l++ < 8) {
+ /* Pour chaque octet, on met le caractère (ou un point si
+ * celui-ci n'est pas imprimable. */
+
+ if (isprint(*m++))
+ *s++ = *((const char*)m - 1);
+ else
+ *s++ = '.';
+ }
+
+ /* Et on n'oublie pas la fin de la ligne. */
+
+ *s++ = '\n';
+ *s = '\0';
+}
+
+/* `wes_log_mem()`: afficher une zone de mémoire. */
+
+void wes_log_mem(wes_loglevel_t loglevel, const char *func,
+ const void *m, size_t n)
+{
+ char linebuf[58];
+ const unsigned char *p;
+
+ /* On voit si on affiche bien la zone de mémoire par rapport au
+ * niveau de log actuel. */
+
+ if (!islog(loglevel))
+ return ;
+
+ /* S'il n'y a rien, on affiche ça. */
+
+ if (!n) {
+ log_prefix(loglevel, func);
+ fprintf(stderr, "(nothing)\n");
+ return ;
+ }
+
+ /* Pour chaque groupe de huit octets maximum, on remplit la zone
+ * ASCII-hex et la zone ASCII, puis on affiche la ligne. */
+
+ memcpy(linebuf, "0000 0000 0000 0000 ", 20);
+ for (p = m; n > 0;) {
+ log_mem_hex(&linebuf[0], p, n);
+ log_mem_asc(&linebuf[20], p, n);
+
+ log_prefix(loglevel, func);
+ fputs(linebuf, stderr);
+
+ p += 8;
+ n -= n > 8 ? 8 : n;
+ }
+}
diff --git a/daemon/ip/m2m.c b/libwes/src/m2m.c
index 96c6328..19a2a02 100644
--- a/daemon/ip/m2m.c
+++ b/libwes/src/m2m.c
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * ip/m2m.c -- gestion du protocole M2M over TCP des serveurs WES.
+ * m2m.c -- gestion du protocole M2M over TCP des serveurs WES.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -36,12 +36,12 @@
/* `get_proto_port()`: Récupérer le protocole et le port à utiliser. */
-static int get_proto_port(wes_t *wes, int *proto, int *port)
+static int get_proto_port(WES *wes, int *proto, int *port)
{
int err;
char tcp_act[5], udp_act[5];
char tcp_port[10], udp_port[10];
- wescgi_t blocks[] = {
+ wes_cgi_t blocks[] = {
/* Selon si l'interface M2M via TCP est activée ou non.
* Vaut "c" (pour "checked") si c'est le cas, "" sinon. */
WESCGI("Mta", "%.1s", tcp_act, 5),
@@ -57,7 +57,7 @@ static int get_proto_port(wes_t *wes, int *proto, int *port)
WESCGI("Mup", "%d", udp_port, 10)
};
- if ((err = get_cgi(wes, 4, blocks)))
+ if ((err = wes_get_cgi(wes, 4, blocks)))
return (err);
if (blocks[0].buffer[0] == 'c' && blocks[1].lines) {
@@ -67,9 +67,9 @@ static int get_proto_port(wes_t *wes, int *proto, int *port)
*proto = WSK_UDP;
*port = (int)(atoi(blocks[3].buffer) & 0x7fff);
} else
- return (WRUNAVAIL);
+ return (wes_error_op);
- return (WROK);
+ return (wes_error_ok);
}
/* ---
@@ -80,12 +80,12 @@ static int get_proto_port(wes_t *wes, int *proto, int *port)
* Définie à part car utilisée dans l'initialisation *et* dans l'envoi
* de commande en cas de problème. */
-static int connect_tcp(wes_t *wes)
+static int connect_tcp(WES *wes)
{
int ret;
if (wes->sock_type != WSK_TCP)
- return (WROK);
+ return (wes_error_ok);
/* Il s'agit d'une connexion TCP, on s'occupe donc de la
* connecter au serveur. */
@@ -97,23 +97,23 @@ static int connect_tcp(wes_t *wes)
case ENETUNREACH:
case EADDRINUSE:
case ETIMEDOUT:
- return (WRNOHOST);
+ return (wes_error_nohost);
default:
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
/* Si on a besoin de définir `TCP_NODELAY` pour une raison ou pour
* une autre, c'est ici. */
- return (WROK);
+ return (wes_error_ok);
}
/* `connect_wes()`: Se connecter via TCP ou UDP (selon ce qui est ouvert ou
* ce qu'on doit ouvrir) au WES sur le port utilisé pour le protocole M2M,
* ou réutiliser le socket déjà ouvert. */
-static int connect_wes(wes_t *wes)
+static int connect_wes(WES *wes)
{
char ip_as_string[50];
const unsigned char *ip;
@@ -126,7 +126,7 @@ static int connect_wes(wes_t *wes)
* renvoie cette socket. */
if (wes->sock_type != WSK_NONE)
- return (WROK);
+ return (wes_error_ok);
/* On vérifie si l'interface est allumée via TCP ou UDP et on récupère
* le port associé, le tout via l'interface CGI. */
@@ -137,18 +137,18 @@ static int connect_wes(wes_t *wes)
/* On prépare l'adresse de la socket. */
- if (wes->addr.data.inet.has & HASIPv4) {
+ if (wes->addr.data.inet.has & WESHASIPv4) {
ip = wes->addr.data.inet.ipv4;
sprintf(ip_as_string, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
sockaddr4 = &wes->platform.posix.sock_addr.ip;
- wes->platform.posix.sockaddr = (struct sockaddr*)sockaddr4;
+ wes->platform.posix.sockaddr = (struct sockaddr *)sockaddr4;
wes->platform.posix.sockaddr_size = sizeof(*sockaddr4);
sockaddr4->sin_family = AF_INET;
inet_pton(AF_INET, ip_as_string, &sockaddr4->sin_addr);
sockaddr4->sin_port = htons(port);
- } else if (wes->addr.data.inet.has & HASIPv6) {
+ } else if (wes->addr.data.inet.has & WESHASIPv6) {
ip = wes->addr.data.inet.ipv6;
sprintf(ip_as_string, "%02X%02X:%02X%02X:%02X%02X:%02X%02X"
":%02X%02X:%02X%02X:%02X%02X:%02X%02X",
@@ -156,14 +156,14 @@ static int connect_wes(wes_t *wes)
ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]);
sockaddr6 = &wes->platform.posix.sock_addr.ip6;
- wes->platform.posix.sockaddr = (struct sockaddr*)sockaddr6;
+ wes->platform.posix.sockaddr = (struct sockaddr *)sockaddr6;
wes->platform.posix.sockaddr_size = sizeof(*sockaddr6);
sockaddr6->sin6_family = AF_INET6;
inet_pton(AF_INET6, ip_as_string, &sockaddr6->sin6_addr);
sockaddr6->sin6_port = htons(port);
} else
- return (WRUNKNOWN);
+ return (wes_error_unknown);
/* On prépare le buffer avant la création du socket et la connexion
* (opérations les plus lourdes) pour que tout soit lu correctement.
@@ -172,7 +172,7 @@ static int connect_wes(wes_t *wes)
* des données dans une frame TCP ou un paquet UDP. */
if (!(wes->sock_buf = malloc(4096)))
- return (WRALLOC);
+ return (wes_error_alloc);
wes->sock_buflen = 4096;
/* On crée la socket avec la bonne famille. */
@@ -191,10 +191,10 @@ static int connect_wes(wes_t *wes)
case EMFILE: /* FALLTHRU */
case ENFILE: /* FALLTHRU */
case ENOMEM:
- return (WRALLOC);
+ return (wes_error_alloc);
default:
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
}
@@ -235,14 +235,14 @@ static int connect_wes(wes_t *wes)
free(wes->sock_buf);
wes->sock_buf = NULL;
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
}
/* Notre socket est prête à être utilisée par les fonctions
* `send_*_command()` ! */
- return (WROK);
+ return (wes_error_ok);
}
/* `receive_buffer()`: Recevoir un buffer. */
@@ -264,12 +264,12 @@ static int receive_buffer(int sock, char *buf, size_t size, size_t *received)
if ((ret = select(sock + 1, &rfds, NULL, NULL, &tv)) < 0) switch (errno) {
case ECONNRESET:
- return (WRCONN);
+ return (wes_error_conn);
default:
- return (WRUNKNOWN);
+ return (wes_error_unknown);
} else if (!ret)
- return (WRTIMEOUT);
+ return (wes_error_timeout);
/* On sait qu'on a une réponse, maintenant, on veut savoir
* de combien d'octets est composée cette réponse. */
@@ -277,7 +277,7 @@ static int receive_buffer(int sock, char *buf, size_t size, size_t *received)
if (ioctl(sock, FIONREAD, &intcount) < 0) {
/* FIXME: si cet `ioctl()` échoue, que fait-on ? */
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
count = (ssize_t)intcount;
@@ -295,16 +295,16 @@ static int receive_buffer(int sock, char *buf, size_t size, size_t *received)
if (recv(sock, buf, (size_t)count, 0) < count) {
/* FIXME: check ERRNO? */
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
- return (WROK);
+ return (wes_error_ok);
}
/* `send_tcp_command()`: Envoi d'une commande via TCP, et réception de la
* commande par le même moyen. */
-static int send_tcp_command(wes_t *wes, const char *command, size_t clen,
+static int send_tcp_command(WES *wes, const char *command, size_t clen,
char *response, size_t rlen, size_t *fullp)
{
int sock, err, tries;
@@ -327,14 +327,14 @@ static int send_tcp_command(wes_t *wes, const char *command, size_t clen,
err = receive_buffer(sock, wes->sock_buf,
wes->sock_buflen, &count);
- if (err == WRCONN) {
+ if (err == wes_error_conn) {
if ((err = connect_tcp(wes)))
return (err);
break;
}
- if (err == WROK)
+ if (err == wes_error_ok)
continue;
- if (err != WRTIMEOUT)
+ if (err != wes_error_timeout)
return (err);
}
@@ -374,7 +374,7 @@ static int send_tcp_command(wes_t *wes, const char *command, size_t clen,
default:
/* On ne connaît pas l'erreur ici. */
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
}
@@ -387,18 +387,18 @@ static int send_tcp_command(wes_t *wes, const char *command, size_t clen,
err = receive_buffer(sock, wes->sock_buf,
wes->sock_buflen, &count);
- if (err == WRCONN) {
+ if (err == wes_error_conn) {
if ((err = connect_tcp(wes)))
return (err);
break;
}
switch (err) {
- case WROK:
+ case wes_error_ok:
break;
default:
/* TODO: traiter l'erreur correctement */
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
/* On traite le buffer. */
@@ -444,13 +444,13 @@ static int send_tcp_command(wes_t *wes, const char *command, size_t clen,
}
*fullp = full;
- return (WROK);
+ return (wes_error_ok);
}
/* `send_udp_command()`: Envoi d'une commande via UDP, et réception de
* la commande par le même moyen. */
-static int send_udp_command(wes_t *wes, const char *command, size_t clen,
+static int send_udp_command(WES *wes, const char *command, size_t clen,
char *response, size_t rlen, size_t *fullp)
{
int sock, err, newline = 0, car;
@@ -472,14 +472,14 @@ static int send_udp_command(wes_t *wes, const char *command, size_t clen,
err = receive_buffer(sock, wes->sock_buf,
wes->sock_buflen, &count);
- if (err == WRCONN) {
+ if (err == wes_error_conn) {
if ((err = connect_tcp(wes)))
return (err);
break;
}
- if (err == WROK)
+ if (err == wes_error_ok)
continue;
- if (err != WRTIMEOUT)
+ if (err != wes_error_timeout)
return (err);
}
@@ -494,7 +494,7 @@ static int send_udp_command(wes_t *wes, const char *command, size_t clen,
default:
/* On ne connaît pas l'erreur ici. */
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
/* Ensuite, on cherche à récupérer la réponse.
@@ -507,11 +507,11 @@ static int send_udp_command(wes_t *wes, const char *command, size_t clen,
err = receive_buffer(sock, wes->sock_buf,
wes->sock_buflen, &count);
switch (err) {
- case WROK:
+ case wes_error_ok:
break;
default:
/* TODO: traiter l'erreur correctement */
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
/* On traite le buffer. */
@@ -546,28 +546,28 @@ static int send_udp_command(wes_t *wes, const char *command, size_t clen,
}
*fullp = full;
- return (WROK);
+ return (wes_error_ok);
}
/* ---
* Interface utilisateur.
* --- */
-/* `init_m2m()`: Initialiser l'aspect M2M d'un serveur. */
+/* `wes_init_m2m()`: Initialiser l'aspect M2M d'un serveur. */
-int init_m2m(wes_t *wes)
+int wes_init_m2m(WES *wes)
{
wes->sock_type = WSK_NONE;
wes->platform.posix.sock = -1;
wes->sock_buf = NULL;
- return (WROK);
+ return (wes_error_ok);
}
-/* `deinit_m2m()`: Déinitialiser l'aspect M2M d'un serveur. */
+/* `wes_deinit_m2m()`: Déinitialiser l'aspect M2M d'un serveur. */
-int deinit_m2m(wes_t *wes)
+int wes_deinit_m2m(WES *wes)
{
if (wes->platform.posix.sock >= 0) {
close(wes->platform.posix.sock);
@@ -581,13 +581,14 @@ int deinit_m2m(wes_t *wes)
}
wes->sock_type = WSK_NONE;
- return (WROK);
+ return (wes_error_ok);
}
-/* `send_command()`: Envoyer une commande via le protocole M2M, et
+/* `wes_send_command()`: Envoyer une commande via le protocole M2M, et
* recevoir la réponse. */
-int send_command(wes_t *wes, const char *command, char *response, size_t *lenp)
+int wes_send_command(WES *wes, const char *command, char *response,
+ size_t *lenp)
{
size_t commandlen;
char shortcommand[256], *p;
@@ -619,5 +620,5 @@ int send_command(wes_t *wes, const char *command, char *response, size_t *lenp)
response, *lenp, lenp));
}
- return (WRUNKNOWN);
+ return (wes_error_unknown);
}
diff --git a/libwes/src/open.c b/libwes/src/open.c
new file mode 100644
index 0000000..de42156
--- /dev/null
+++ b/libwes/src/open.c
@@ -0,0 +1,84 @@
+/* ****************************************************************************
+ * open.c -- ouvrir et fermer un handle de WES.
+ * 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.
+ * ************************************************************************* */
+#include "internals.h"
+
+/* `wes_open()`: créer une ressource. */
+
+int wes_open(WES **resourcep, wes_addr_t const *addr)
+{
+ WES *res;
+
+ if (!addr || addr->type != WESINET || ~addr->data.inet.has & WESHASIPv4)
+ return (wes_error_val);
+ if (!(res = (*resourcep = malloc(sizeof(*res)))))
+ return (wes_error_alloc);
+
+ res->http_name = NULL;
+ res->http_pass = NULL;
+ res->ftp_name = NULL;
+ res->ftp_pass = NULL;
+ res->http_handle = NULL;
+ res->ftp_handle = NULL;
+ res->data = NULL;
+ res->addr.type = WESINET;
+ res->addr.data.inet.has = WESHASIPv4;
+ memcpy(&res->addr.data.inet.ipv4, &addr->data.inet.ipv4, 4);
+ wes_init_m2m(res);
+
+ return (wes_error_ok);
+}
+
+/* `wes_close()`: fermer une ressource. */
+
+void wes_close(WES *res)
+{
+ if (!res)
+ return ;
+
+ if (res->http_handle) {
+ curl_easy_cleanup(res->http_handle);
+ res->http_handle = NULL;
+ }
+ if (res->ftp_handle) {
+ curl_easy_cleanup(res->ftp_handle);
+ res->ftp_handle = NULL;
+ }
+
+ wes_deinit_m2m(res);
+
+#if 0
+ clear_config(res);
+#endif
+ /* FIXME: clear_data(res); */
+
+ wes_set_http_ident(res, NULL, NULL);
+ wes_set_ftp_ident(res, NULL, NULL);
+ free(res);
+}
diff --git a/daemon/ip/utils.c b/libwes/src/utils.c
index 439467e..a0fd557 100644
--- a/daemon/ip/utils.c
+++ b/libwes/src/utils.c
@@ -1,5 +1,5 @@
/* ****************************************************************************
- * ip/utils.c -- utilitaires.
+ * utils.c -- utilitaires.
* Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
*
* This project is governed by the CeCILL license under French law and
@@ -40,7 +40,7 @@ static char *default_ftp_pass = "wesftp";
/* `set_http_ident()`: Définir les identifiants HTTP du serveur WES. */
-int set_http_ident(wes_t *wes, const char *namep, const char *passp)
+int wes_set_http_ident(WES *wes, const char *namep, const char *passp)
{
char *name = NULL, *pass = NULL;
size_t sz;
@@ -54,7 +54,7 @@ int set_http_ident(wes_t *wes, const char *namep, const char *passp)
else {
sz = strlen(namep) + 1;
if (!(name = malloc(sz)))
- return (WRALLOC);
+ return (wes_error_alloc);
memcpy(name, namep, sz);
}
@@ -69,7 +69,7 @@ int set_http_ident(wes_t *wes, const char *namep, const char *passp)
sz = strlen(passp) + 1;
if (!(pass = malloc(sz))) {
free(name);
- return (WRALLOC);
+ return (wes_error_alloc);
}
memcpy(pass, passp, sz);
@@ -85,12 +85,12 @@ int set_http_ident(wes_t *wes, const char *namep, const char *passp)
wes->http_name = name;
wes->http_pass = pass;
- return (WROK);
+ return (wes_error_ok);
}
-/* `set_ftp_ident()`: Définir les identifiants FTP du serveur WES. */
+/* `wes_set_ftp_ident()`: Définir les identifiants FTP du serveur WES. */
-int set_ftp_ident(wes_t *wes, const char *namep, const char *passp)
+int wes_set_ftp_ident(WES *wes, const char *namep, const char *passp)
{
char *name = NULL, *pass = NULL;
size_t sz;
@@ -104,7 +104,7 @@ int set_ftp_ident(wes_t *wes, const char *namep, const char *passp)
else {
sz = strlen(namep) + 1;
if (!(name = malloc(sz)))
- return (WRALLOC);
+ return (wes_error_alloc);
memcpy(name, namep, sz);
}
@@ -119,7 +119,7 @@ int set_ftp_ident(wes_t *wes, const char *namep, const char *passp)
sz = strlen(passp) + 1;
if (!(pass = malloc(sz))) {
free(name);
- return (WRALLOC);
+ return (wes_error_alloc);
}
memcpy(pass, passp, sz);
@@ -135,7 +135,7 @@ int set_ftp_ident(wes_t *wes, const char *namep, const char *passp)
wes->ftp_name = name;
wes->ftp_pass = pass;
- return (WROK);
+ return (wes_error_ok);
}
/* ---
@@ -146,7 +146,7 @@ int set_ftp_ident(wes_t *wes, const char *namep, const char *passp)
* Gère les caractères spéciaux type `&`, `?`, `=`, …
* Doit _impérativement_ évoluer en même temps que `strcpy_encoded()`. */
-static size_t strlen_encoded(const char *src)
+static size_t strlen_encoded(char const *src)
{
int car;
size_t len = 0;
@@ -195,12 +195,12 @@ static void strcpy_encoded(char *dest, const char *src)
* La fonction renvoie la taille qu'elle aurait dû avoir pour pouvoir
* tout stocker. */
-static size_t make_qs(int argc, wescgiarg_t *args, char *buf, size_t size)
+static size_t make_qs(int argc, wes_cgi_arg_t *args, char *buf, size_t size)
{
int i;
size_t notfirst = 0;
size_t lenkey, lenval, lenarg, full = 1; /* caractère NUL */
- wescgiarg_t *arg;
+ wes_cgi_arg_t *arg;
if (size)
size--; /* caractère NUL à la fin du buffer. */
@@ -241,11 +241,11 @@ static size_t make_qs(int argc, wescgiarg_t *args, char *buf, size_t size)
return (full);
}
-/* `open_http_handle()`: Ouverture d'un canal HTTP pour un chemin HTTP.
+/* `wes_open_http_handle()`: Ouverture d'un canal HTTP pour un chemin HTTP.
* Ce canal n'a point besoin d'être fermé. */
-int open_http_handle(wes_t *wes, CURL **handlep, weshttpmethod_t method,
- const char *path, int argc, weshttparg_t *args)
+int wes_open_http_handle(WES *wes, CURL **handlep, wes_http_method_t method,
+ const char *path, int argc, wes_http_arg_t *args)
{
CURL *handle;
const unsigned char *ip;
@@ -253,21 +253,21 @@ int open_http_handle(wes_t *wes, CURL **handlep, weshttpmethod_t method,
size_t left, sz;
if (method != WESHTTPMETHOD_GET && method != WESHTTPMETHOD_POST)
- return (WROP);
+ return (wes_error_op);
/* On prépare l'URL complète, avec protocole et interface du WES. */
- if (wes->addr.data.inet.has & HASIPv4) {
+ if (wes->addr.data.inet.has & WESHASIPv4) {
ip = wes->addr.data.inet.ipv4;
sprintf(url, "http://%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
- } else if (wes->addr.data.inet.has & HASIPv6) {
+ } else if (wes->addr.data.inet.has & WESHASIPv6) {
ip = wes->addr.data.inet.ipv4;
sprintf(url, "http://[%02X%02X:%02X%02X:%02X%02X:%02X%02X"
":%02X%02X:%02X%02X:%02X%02X:%02X%02X]",
ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7],
ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]);
} else
- return (WROP);
+ return (wes_error_op);
sz = strlen(url);
p = &url[sz];
@@ -275,7 +275,7 @@ int open_http_handle(wes_t *wes, CURL **handlep, weshttpmethod_t method,
sz = strlen(path);
if (sz > left)
- return (WROP);
+ return (wes_error_op);
memcpy(p, path, sz);
p += sz;
left -= sz;
@@ -283,20 +283,20 @@ int open_http_handle(wes_t *wes, CURL **handlep, weshttpmethod_t method,
if (method == WESHTTPMETHOD_GET && argc) {
if (left <= 1)
- return (WROP);
+ return (wes_error_op);
*p++ = '?';
*p = '\0';
left--;
if (make_qs(argc, args, p, left) > left)
- return (WROP);
+ return (wes_error_op);
}
/* On prépare le postdata si nécessaire. */
if (method == WESHTTPMETHOD_POST
&& (sz = make_qs(argc, args, postdata, 201)) > 201)
- return (WROP);
+ return (wes_error_op);
/* On ouvre le handle si nécessaire. */
@@ -305,7 +305,7 @@ int open_http_handle(wes_t *wes, CURL **handlep, weshttpmethod_t method,
else {
handle = curl_easy_init();
if (!handle)
- return (WRUNKNOWN);
+ return (wes_error_unknown);
wes->http_handle = handle;
}
@@ -334,17 +334,17 @@ int open_http_handle(wes_t *wes, CURL **handlep, weshttpmethod_t method,
curl_easy_setopt(handle, CURLOPT_USERAGENT, "weshd/" WESHD_VERSION);
*handlep = handle;
- return (WROK);
+ return (wes_error_ok);
}
/* ---
* Ouverture d'un canal FTP.
* --- */
-/* `open_ftp_handle()`: Ouverture d'un canal FTP pour un chemin FTP.
+/* `wes_open_ftp_handle()`: Ouverture d'un canal FTP pour un chemin FTP.
* Ce canal n'a point besoin d'être fermé. */
-int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path)
+int wes_open_ftp_handle(WES *wes, CURL **handlep, char const *path)
{
CURL *handle;
const unsigned char *ip;
@@ -352,11 +352,11 @@ int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path)
/* On prépare l'URL complète, avec protocole et interface du WES. */
- if (wes->addr.data.inet.has & HASIPv4) {
+ if (wes->addr.data.inet.has & WESHASIPv4) {
ip = wes->addr.data.inet.ipv4;
sprintf(url, "ftp://%d.%d.%d.%d%.200s", ip[0], ip[1], ip[2], ip[3],
path);
- } else if (wes->addr.data.inet.has & HASIPv6) {
+ } else if (wes->addr.data.inet.has & WESHASIPv6) {
ip = wes->addr.data.inet.ipv4;
sprintf(url, "ftp://[%02X%02X:%02X%02X:%02X%02X:%02X%02X"
":%02X%02X:%02X%02X:%02X%02X:%02X%02X]%.200s",
@@ -364,7 +364,7 @@ int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path)
ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15],
path);
} else
- return (WRUNKNOWN);
+ return (wes_error_unknown);
/* On ouvre le handle si nécessaire. */
@@ -373,7 +373,7 @@ int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path)
else {
handle = curl_easy_init();
if (!handle)
- return (WRUNKNOWN);
+ return (wes_error_unknown);
wes->ftp_handle = handle;
}
@@ -392,5 +392,5 @@ int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path)
curl_easy_setopt(handle, CURLOPT_READDATA, NULL);
*handlep = handle;
- return (WROK);
+ return (wes_error_ok);
}
diff --git a/include/libwesh.hpp b/libwesh/include/libwesh.hpp
index c59cd01..c59cd01 100644
--- a/include/libwesh.hpp
+++ b/libwesh/include/libwesh.hpp
diff --git a/lib/helpers.cpp b/libwesh/src/helpers.cpp
index 62847fc..62847fc 100644
--- a/lib/helpers.cpp
+++ b/libwesh/src/helpers.cpp
diff --git a/lib/interface.cpp b/libwesh/src/interface.cpp
index 2cb670c..2cb670c 100644
--- a/lib/interface.cpp
+++ b/libwesh/src/interface.cpp
diff --git a/lib/internals.hpp b/libwesh/src/internals.hpp
index 044e2a0..044e2a0 100644
--- a/lib/internals.hpp
+++ b/libwesh/src/internals.hpp
diff --git a/lib/meter.cpp b/libwesh/src/meter.cpp
index d8d1d0a..d8d1d0a 100644
--- a/lib/meter.cpp
+++ b/libwesh/src/meter.cpp
diff --git a/lib/sensor.cpp b/libwesh/src/sensor.cpp
index db66e6a..db66e6a 100644
--- a/lib/sensor.cpp
+++ b/libwesh/src/sensor.cpp
diff --git a/lib/wes.cpp b/libwesh/src/wes.cpp
index d313a65..d313a65 100644
--- a/lib/wes.cpp
+++ b/libwesh/src/wes.cpp
diff --git a/weshd.x b/weshd.x
index 99ef4ca..4294a00 100644
--- a/weshd.x
+++ b/weshd.x
@@ -47,38 +47,7 @@
* même espace de noms. */
/* ---
- * Codes relatifs au protocole.
- * --- */
-
-/* Les codes de retour (ou d'erreur) sont les suivants :
- *
- * - `OK`: aucune erreur ;
- * - `INT`: une erreur interne s'est produite ;
- * - `IMP`: cette fonctionnalité n'est pas (encore) implémentée.
- * - `VAL`: arguments invalides pour cette fonctionnalité.
- * - `MIS`: mismatch entre ce qu'on a et ce qui est attendu par le client,
- * utilisé pour les compteurs.
- *
- * - `NOW`: la ressource n'existe pas.
- * - `CON`: le serveur n'a pas pu être joint.
- * - `LRG`: la période pour la récupération de données est trop large,
- * le statut de la (sous-)ressource a changé entretemps. */
-
-enum wespret_t {
- WESPRET_OK = 0,
- WESPRET_INT = 1,
- WESPRET_IMP = 2,
- WESPRET_VAL = 3,
- WESPRET_MIS = 4,
-
- WESPRET_NOW = 10,
- WESPRET_CON = 11,
- WESPRET_LRG = 12
-};
-
-/* ---
- * Sous-types définis pour les ressources de type serveur WES, ainsi que
- * les autres.
+ * Utilitaires.
* --- */
/* Horodate, la plus complète possible pour tout couvrir.
@@ -131,26 +100,91 @@ case WESPIPTYPE_6:
unsigned char addr6[16];
};
-/* Identifiant d'un serveur WES.
- * Cet identifiant peut aller de 1 à 32766 inclus. */
+/* ---
+ * Codes relatifs au protocole.
+ * --- */
+
+/* Les codes de retour (ou d'erreur) sont les suivants :
+ *
+ * - `OK`: aucune erreur ;
+ * - `INT`: une erreur interne s'est produite ;
+ * - `IMP`: cette fonctionnalité n'est pas (encore) implémentée.
+ * - `VAL`: arguments invalides pour cette fonctionnalité.
+ * - `MIS`: mismatch entre ce qu'on a et ce qui est attendu par le client,
+ * utilisé pour les compteurs.
+ *
+ * - `NOW`: la ressource n'existe pas.
+ * - `CON`: le serveur n'a pas pu être joint.
+ * - `LRG`: la période pour la récupération de données est trop large,
+ * le statut de la (sous-)ressource a changé entretemps. */
+
+enum wespret_t {
+ WESPRET_OK = 0,
+ WESPRET_INT = 1,
+ WESPRET_IMP = 2,
+ WESPRET_VAL = 3,
+ WESPRET_MIS = 4,
+
+ WESPRET_NOW = 10,
+ WESPRET_CON = 11,
+ WESPRET_LRG = 12
+};
+
+/* ---
+ * Gestion des objets.
+ * --- */
+
+/* Identifiant d'un objet (serveur WES, compteur, …).
+ * Tous les objets sont dans un même espace d'identifiants, où chacun
+ * peut aller de 1 à 32766 inclus. */
typedef int wespid_t;
-/* Identifiant d'un compteur pour un serveur WES.
- * Cet identifiant peut aller de 1 à 32766 inclus. */
+/* Type de l'objet. */
-typedef int wespmeterid_t;
+enum wesptype_t {
+ WESPTYPE_WES = 0,
+ WESPTYPE_METER = 1,
+ WESPTYPE_SENSOR = 2
+};
-/* Type du WES.
- * `DUMMY`: serveur WES factice / paramètres généraux uniquement.
+/* Sous-type de l'objet pour un objet de type `WESTYPE_WES`.
+ * `NONE` : type générique.
+ * `DUMMY`: serveur WES factice.
* `IP`: serveur WES connecté par IP. */
-enum wesptype_t {
- WESPTYPE_DUMMY = 0,
- WESPTYPE_NONE = 0,
- WESPTYPE_IP = 1
+enum wesptype_wes_t {
+ WESPTYPE_WES_NONE = 0,
+ WESPTYPE_WES_DUMMY = 1,
+ WESPTYPE_WES_IP = 2
};
+/* Sous-type de l'objet pour un objet de type `WESTYPE_METER`.
+ * `NONE`: type générique.
+ * `TELEINFO`: compteur branché via le protocole télé-information d'Enedis.
+ * `AMPER`: pinces ampèremétriques.
+ * `PULSE`: compteur d'impulsions. */
+
+enum wesptype_meter_t {
+ WESPTYPE_METER_NONE = 0,
+ WESPTYPE_METER_AMPER = 1,
+ WESPTYPE_METER_PULSE = 2,
+ WESPTYPE_METER_TELEINFO = 3
+};
+
+/* Sous-type de l'objet pour un objet de type `WESTYPE_SENSOR`.
+ * `NONE`: type générique.
+ * `ONEWIRE`: capteur branché via le bus 1-Wire. */
+
+enum wesptype_sensor_t {
+ WESPTYPE_SENSOR_NONE = 0,
+ WESPTYPE_SENSOR_ONEWIRE = 1
+};
+
+/* ---
+ * Objets de type WES (regroupement de compteurs et capteurs).
+ * --- */
+
/* Propriétés d'enregistrement spécifiques au serveur WES connecté par IP. */
struct wespoptions_ip_t {
@@ -240,19 +274,6 @@ struct wesp_t {
* Énumérations et sous-types divers concernant les compteurs.
* --- */
-/* De quel type de compteur s'agit-il ?
- * `NONE`: informations génériques uniquement.
- * `TELEINFO`: compteur branché via le protocole télé-informatique d'Enedis.
- * `AMPER`: pinces ampèremétriques.
- * `PULSE`: compteur d'impulsions. */
-
-enum wespmetertype_t {
- WESPMETERTYPE_NONE = 0,
- WESPMETERTYPE_AMPER = 1,
- WESPMETERTYPE_PULSE = 2,
- WESPMETERTYPE_TELEINFO = 3
-};
-
/* Mode de consommation/production de chaque compteur.
* `CONSO`: consommation.
* `PROD`: production (panneaux solaires, …). */
@@ -561,9 +582,130 @@ struct wespmetervalues_t {
};
/* ---
+ * Configuration d'un objet.
+ * --- */
+
+/* Objet de type ressource WES. */
+
+union wespcfg_wesmore_t switch (wesptype_wes_t type) {
+case WESPTYPE_WES_NONE:
+case WESPTYPE_WES_DUMMY:
+case WESPTYPE_WES_IP:
+ wespcfg_wes_ip_t ip;
+};
+
+struct wespcfg_wes_t {
+ wespcfg_wesmore_t more;
+};
+
+/* Objet de type compteur. */
+
+union wespcfg_metermore_t switch (wesptype_meter_t type) {
+case WESPTYPE_METER_NONE:
+case WESPTYPE_METER_TELEINFO:
+case WESPTYPE_METER_AMPER:
+case WESPTYPE_METER_PULSE:
+};
+
+struct wespcfg_meter_t {
+ /* Propriétés de base de tout compteur.
+ * `rd`: le compteur est-il lu ou ignoré par le système ?
+ * `mode`: mode de consommation/production du compteur.
+ * `what`: grandeur mesurée. */
+
+ bool rd;
+ wespmetermode_t mode;
+ wespmeterwhat_t what;
+
+ /* Informations concernant le coût.
+ * `fixed_cost`: coût fixe de l'abonnement, à l'année.
+ * `prorata`: l'abonnement est-il au prorata du prix de l'unité ? */
+
+ double fixed_cost;
+ bool prorata;
+
+ wespcfg_metermore_t more;
+};
+
+/* Objet de type capteur. */
+
+union wespcfg_sensormore_t switch (wesptype_sensor_t type) {
+case WESPTYPE_SENSOR_NONE:
+case WESPTYPE_SENSOR_ONEWIRE:
+};
+
+struct wespcfg_sensor_t {
+ wespcfg_sensormore_t more;
+};
+
+/* Objet général de configuration.
+ * Les types sont donnés en plus dans `type` et `subtype` puisque ce n'est pas
+ * parce qu'on informe le client de ceux-ci que les données suivent
+ * derrière. */
+
+union wespcfgmore_t switch (wesptype_t type) {
+case WESPTYPE_WES:
+ wespcfg_wes_t wes;
+case WESPTYPE_METER:
+ wespcfg_meter_t meter;
+case WESPTYPE_SENSOR:
+ wespcfg_sensor_t sensor;
+};
+
+struct wespcfg_t {
+ int type;
+ int subtype;
+
+ string name<>;
+ wespcfgmore_t more;
+};
+
+/* ---
* Structures pour utilisation par le programme.
* --- */
+struct wespid_with_flags_t {
+ wespid_t id;
+ wespflags_t flags;
+};
+
+struct wespid_with_flags_and_cfg_t {
+ wespid_t id;
+ wespflags_t flags;
+ wespcfg_t cfg;
+};
+
+struct wespquery_t {
+ wespid_t parent;
+ int offset;
+ int count;
+};
+
+struct wespid_and_span_t {
+ wespid_t id;
+ wespdt_t begin;
+ wespdt_t end;
+};
+
+struct wespret_with_cfg_t {
+ wespret_t ret;
+ wespcfg_t cfg;
+};
+
+struct wes
+
+struct wespret_with_list_t {
+
+};
+
+struct wespret_with_id_t {
+
+};
+
+struct wespret_with_data_t {
+
+};
+
/* Gestion des serveurs WES. */
struct wespid_with_wes_t {
@@ -705,33 +847,23 @@ program WESHD_PROG {
void WESHD_NULL(void) = 0;
- /* Gérer les serveur WES. */
+ /* Récupération, suppression d'un ou plusieurs éléments. */
- wespret_with_id_t GATHER(wespoptions_t args) = 1;
- wespret_t UNREGISTER(wespid_t id) = 2;
+ wespret_with_cfg_t GET(wespid_with_flags_t args) = 1;
+ wespret_t SET(wespid_with_flags_and_cfg_t args) = 2;
- wespret_with_wes_t GET(wespid_with_wes_flags_t id) = 3;
- wespret_t SET(wespid_with_wes_t id) = 4;
- wespret_with_wes_list_t
- QUERY_WES(wespquery_t args) = 5;
+ wespret_with_list_t QUERY(wespquery_t args) = 3;
+ wespret_t REMOVE(wespid_t id) = 4;
- /* Gérer les compteurs. */
+ /* Opérations spécifiques aux serveurs WES.
+ * `GATHER_WES()`: récupération (voire initialisation) d'un WES. */
- wespret_with_meter_t GET_METER(wespid_with_meter_id_t id) = 6;
- wespret_t SET_METER(wespid_with_meter_t id) = 7;
- wespret_with_meter_data_t
- GET_METER_DATA(wespid_with_meter_id_and_span_t args) = 8;
- wespret_with_meter_list_t
- QUERY_METERS(wespid_with_meter_query_t args) = 9;
+ wespret_with_id_t GATHER_WES(wespoptions_t args) = 5;
- /* Gérer les capteurs. */
+ /* Opérations spécifiques aux compteurs et capteurs.
+ * `GET_DATA()`: récupération de données. */
- wespret_with_sensor_t GET_SENSOR(wespid_with_sensor_id_t id) = 10;
- wespret_t SET_SENSOR(wespid_with_sensor_t id) = 11;
- wespret_with_sensor_data_t
- GET_SENSOR_DATA(wespid_with_sensor_id_and_span_t args) = 12;
- wespret_with_sensor_list_t
- QUERY_SENSORS(wespid_with_sensor_query_t args) = 13;
+ wespret_with_data_t GET_DATA(wespid_and_span_t args) = 6;
/* TODO: interactions avec le LCD */
} = 1;