Les API d’Eris Linux

Publié par cpb
Sep 22 2026

Nous avons vu dans les articles précédents de cette série :

Les applications que l’on embarque sous forme de code « métier » ne sont que très rarement auto-suffisantes. Elles ont souvent besoin de communiquer avec le système sous-jacent pour consulter ou configurer des éléments du système (par exemple le paramétrage réseau, la configuration du watchdog, celle des LEDs etc.)

Pour cela Eris Linux offre une interface de programmation qui permet, depuis l’intérieur d’un container, de communiquer avec le système hôte. En réalité cette API (Application Programming Interface) est déclinée en deux implémentations. Une bibliothèque (liberis) qui peut être employée par les applications compilées (en C ou C++ par exemple) et un service REST accessible pour les langages interprétés (javascript, Python, etc.). Nous avons déjà aperçu des usages de liberis et du service REST pour l’API d’Eris Linux dans l’article précédent.

Nous allons ici examiner les fonctionnalités proposées par ces API. Cet article (très long) n’est pas prévu pour être lu d’un bout à l’autre. J’imagine plutôt le lecteur survolant la table des matières pour voir les différents domaines d’utilisation de l’API, puis examinant plus en détail certaines fonctions et requêtes proposées ainsi que les exemples d’invocation.

Il faut savoir qu’Eris Linux est un projet en évolution et des fonctionnalités sont régulièrement ajoutées. Pensez donc à vous référer à la documentation officielle en cas de doute. Cet article sera probablement mis à jour lors des prochains ajouts dans l’API d’Eris.

Table des matières

1 – Appels des requêtes

Pour tester l’emploi des requêtes décrites ci-dessous, deux possibilités :

  • appel depuis un programme C/C++ en utilisant la bibliothèque liberis à la compilation,
  • utilisation d’un outil ligne de commande pour appeler les requêtes de l’API REST.

1.1 – Utilisation de la bibliothèque liberis

Nous allons commencer par appeler une requête simple qui remplit le buffer qu’on lui passe avec la version d’Eris Linux en cours d’utilisation :

int eris_get_system_version(char *buffer, size_t size)

Cette fonction, comme la plupart de l’API liberis renvoie 0 si elle réussit et -1 en cas d’erreur (en remplissant la variable errno avec un code d’erreur).

Pour cela je pars de l’exemple 06-api-test-tcp des containers de démonstration. Je le simplifie pour ne plus avoir que le fichier source suivant :

// liberis-test.c:

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#include <liberis.h>


// ---------------------- Private macros.

#define CONNECTION_PORT   20000


// ---------------------- Private method declarations.

// ---------------------- Private variables.

// ---------------------- Public variable definitions.

// ---------------------- Public methods

int main(void)
{
	int server_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (server_sock == -1) {
		perror("socket");
		exit(EXIT_FAILURE);
	}

	int option = 1;
	(void) setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));

	struct sockaddr_in server_addr;
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = INADDR_ANY;
	server_addr.sin_port = htons(CONNECTION_PORT);
	if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
		perror("bind");
		exit(EXIT_FAILURE);
	}
	listen(server_sock, 3);

	int client_sock;
	while ((client_sock = accept(server_sock, NULL, 0)) != -1) {
		FILE *fp = fdopen(client_sock, "w");
		if (fp != NULL) {

			char buffer[1024];
			if (eris_get_system_version(buffer, sizeof(buffer)) == 0) {
				buffer[sizeof(buffer) - 1] = '\0';
				fprintf(fp, "Answer: %s\n", buffer);
			} else {
				fprintf(fp, "Error: %d\n", errno);
			}
			fclose(fp);
		} else {
			close(client_sock);
		}
	}
	close(server_sock);
	return EXIT_SUCCESS;
}

Beaucoup de code pour une seule ligne nous concernant vraiment ! Mais comme ce code s’exécute dans un container sur un système embarqué potentiellement distant, on ne peut pas se contenter d’un simple :

int main(void)
{
    char buffer[1024];
    if (eris_get_system_version(buffer, sizeof(buffer)) == 0) {
        buffer[sizeof(buffer) - 1] = '\0';
        printf("Answer: %s\n", buffer);
    } else {
        printf("Error: %d\n", errno);
    }
    return 0;
}

(Ou plutôt si, on peut s’en contenter mais il faudra rediriger les sorties stdout et stderr vers un système distant, comme nous le verrons dans le prochain article dédié au débogage applicatif).

Nous avons donc mis en place un exemple qui crée un serveur TCP/IP sur le port 20000, et qui à chaque connexion appelle la fonction d’API qu’on veut tester et renvoie le résultat.

Après compilation (en utilisant le script create-container livré avec les containers de démonstration), téléchargement sur le serveur Eris Linux et déploiement vers un groupe de test, on peut vérifier le comportement en se connectant en utilisant un outil comme telnet, putty ou nc :

$ nc  192.168.3.36  20000
Answer: 1.0.0

1.2 – Appel de l’API REST

On peut obtenir la même information en interrogeant la méthode GET de l’URI /api/system/version sur le port 8080.

Pour tester cette URI, le plus simple est de l’appeler de l’intérieur d’un container, en utilisant l’outil curl en ligne de commande. Pour cela, nous commençons par créer une image spécifique de container en copiant le Dockerfile de l’exemple 01-ssh-server (voir cet article) et en le modifiant légèrement pour ajouter curl après openssh sur la ligne apk add --no-cache :

$ cp  -R  01-ssh-server/  ssh-with-curl

$ nano  ssh-with-curl/Dockerfile

FROM alpine:latest
RUN apk update                             \
 && apk add --no-cache openssh curl        \
 && ssh-keygen -A                          \
 [...]

On produit le container de test :

$ ./create-container arm64 ssh-with-curl ssh-with-curl

Après copie sur le serveur Eris Linux et déploiement sur un groupe d’équipements de test, on peut se connecter sur l’adresse IP de notre carte en utilisant SSH et essayer :

# curl  -X GET   -w '\n'  "http://host.docker.internal:8080/api/system/version"
1.0.0

L’option -w '\n' de curl permet d’ajouter un retour-chariot après la chaîne pour éviter que le prompt du shell ne soit collé à la suite de la réponse.

Lorsqu’une requête nécessitera des paramètres, comme /api/container/name qui renvoie le nom du container dont le numéro est précisé dans le paramètre index, on l’ajoutera à l’URI ainsi :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/name?index=2"
SSH with Curl

J’utiliserai pour la plupart des exemples ci-dessous cette méthode car elle est plus simple et plus rapide à mettre en oeuvre que la recompilation et le redéploiement du programme d’exemple.

2 – Informations système

Il est souvent important pour une application embarquée d’obtenir des informations sur le système sous-jacent (environnement matériel et logiciel) afin de s’adapter au mieux aux ressources disponibles. Les fonctions décrites dans ce paragraphe renvoient des informations sur l’image Eris Linux installée et sa configuration.

2.1 – Version d’Eris Linux en cours d’utilisation

Cette requête a déjà été vue ci-dessus. Dans la bibliothèque liberis, elle est fournie par la fonction suivante :

int eris_get_system_version(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/system/version

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/system/version"
1.0.0

2.2 – Modèle de carte matérielle

Eris Linux est disponible pour différentes cartes embarquées. Les cartes du commerce sont disponibles directement, le support pour des cartes dédiées à un projet est développé spécifiquement. On obtient avec la fonction suivante le nom du matériel supportant Eris Linux.

int eris_get_system_model(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/system/model

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/system/model"
Raspberry-Pi-5

2.3 – Type d’image Eris Linux

Les images Eris Linux sont disponibles aujourd’hui suivant deux types : Headless (sans interface graphique) ou Graphical (avec support d’écran). Il se peut que dans l’avenir d’autres types d’images apparaissent.

int eris_get_system_type(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/system/type

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/system/type"
Graphical

2.4 – Version du noyau Linux

Connaître le numéro de version du noyau Linux qui fait fonctionner tout le système permet de s’assurer de la disponibilité de certaines fonctionnalités. Cela présente également un intérêt en termes de sécurité pour identifier la branche utilisée et constitue une information utile pour déterminer le niveau de correctifs de sécurité.

int eris_get_system_kernel(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/system/kernel

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/system/kernel"
6.6.63-v8-16k

2.5 – Identification de l’équipement

Lors du premier boot, chaque équipement se voit doté d’un numéro unique, servant à l’identifier ensuite vers le Device Manager.

int eris_get_system_uuid(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/system/uuid

Exemple :

# curl -X GET -w '\n'  "http://host.docker.internal:8080/api/system/uuid"
bf2ec75d-d304-47bb-b89a-95b6e11343fd

2.6 – État du système

Eris Linux assure la mise à jour automatique du système d’exploitation lorsque des nouvelles versions apparaissent, essentiellement suite à des corrections de vulnérabilités. L’état du système et de ses mises à jour est consultable par la fonction ci-dessous. Elle renvoie directement l’un des codes suivants :

1Système Ok, pas de mise à jour en cours.
2Installation en cours d’une mise à jour du système.
3Installation de mise à jour terminée, en attente de redémarrage.
4Installation de mise à jour échouée.
5Redémarrage en cours.
-1Erreur, consulter la variable errno.
int eris_get_system_update_status(void);

Point d’accès Rest sur le port 8080  : GET /api/system/status

La chaîne renvoyée contient le code suivi du libellé de l’état du système. Exemple :

# curl -X GET -w '\n'  "http://host.docker.internal:8080/api/system/status"
1 System OK.



3 – Contact entre l’équipement et le Device Manager

Les cartes embarquées contactent régulièrement le Device Manager en utilisant son adresse Internet pour lui remonter leur état de fonctionnement et recevoir en retour les informations de mise à jour et les liens des containers à installer (nous détaillerons cela dans le prochain article). Pour les équipements n’ayant pas d’accès à Internet, nous pouvons proposer diverses variantes du Device Manager (contactez-moi par mail pour en savoir plus).

3.1 – Lecture de la période de contact

La période entre deux contacts de l’équipement vers le Device Manager est consultable avec la fonction suivante. La période renvoyée est en secondes. Une période nulle signifie que l’équipement ne contacte le Device Manager que sur requête explicite (cf eris_contact_server() ci-dessous).

int eris_get_server_contact_period(void);

Point d’accès Rest sur le port 8080 : GET /api/contact/period

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/contact/period"
240

Note : il est possible de modifier la période de contact depuis le Device Manager ; cette valeur s’applique à tout le groupe d’équipements. La valeur que l’on consulte avec la requête ci-dessus (ou que l’on modifie avec la requête ci-dessous) est celle qui concerne uniquement l’équipement où elle a lieu et est prioritaire sur la valeur du groupe. Pour demander au device d’utiliser à nouveau la période du groupe d’équipements, on lui donnera la valeur -1.

3.2 – Écriture de la période de contact

Il est possible de modifier la période de contact vers le Device Manager. Elle est initialement fixée à 240 secondes (4 minutes). On la réduira par exemple à 60 secondes pour un groupe de devices sur lesquels on est en train de développer et tester un nouveau container applicatif. On pourra ensuite l’augmenter par exemple à 7200 secondes (2 heures) pour les équipements déployés et validés sur lesquels on n’a pas besoin d’un retour fréquent.

int eris_set_server_contact_period(int period_seconds);

La valeur transmise est :

  • -1 pour dire que l’équipement doit prendre en compte la période fixée au niveau du groupe,
  • 0 pour un équipement qui ne contactera le Device Manager que sur demande explicite,
  • [60, 86400] (de 1 minute à 24 heures) pour indiquer une période donnée.

Point d’accès Rest sur le port 8080 : PUT /api/contact/period?period=<value>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/contact/period"
240
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/contact/period?period=60"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/contact/period"
60
#

3.3 – Contact du Device Manager dès que possible

Pour les équipements qui ne contactent le Device Manager que sur requête explicite (par exemple un système embarqué dans un dispositif avec un accès réseau intermittent) on utilisera :

int eris_contact_server(void);

qui renvoie 0 en cas de réussite et -1 en cas d’échec.

Point d’accès Rest sur le port 8080 : POST /api/contact/now

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/contact/period?period=0"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/contact/period"
0
# curl  -X POST  -w '\n' "http://host.docker.internal:8080/api/contact/now"
Ok

4 – Les containers

Il peut être important d’obtenir certaines informations sur les containers installés sur le système. Cela permet par exemple de s’assurer qu’un service complémentaire à l’application principale est disponible dans un slot voisin.

4.1 – Nombre de slots

Le nombre de slots dans lesquels on peut installer des containers est aujourd’hui fixé à 4. Toutefois cette valeur pourra évoluer (augmenter) si le besoin s’en fait sentir. Pour consulter le nombre de slots total, on peut appeler :

int eris_get_number_of_slots(void);

Point d’accès Rest sur le port 8080 : GET /api/container/count

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/count"
4

4.2 – Occupation d’un slot

Pour savoir si un slot est occupé par un container, on peut utiliser la fonction :

int eris_get_container_presence(int slot);

L’argument slot est compris entre 0 et le nombre maximal de slots moins 1 (actuellement [0, 3]). La valeur renvoyée est 0 (slot vide) ou 1 (slot occupé). En cas d’erreur (argument invalide), la valeur renvoyée est -1.

Point d’accès Rest sur le port 8080 : GET /api/container/presence?index=<slot>
La valeur renvoyée est une chaîne : absent ou present.

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/presence?index=0"
present
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/presence?index=1"
present
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/presence?index=3"
absent
# 

4.3 – Nom du container installé dans un slot

Le nom du container est enregistré lors de sa création dans l’onglet « My Containers » du Device Manager. Une fois installé dans un slot, il peut être consulté (mais pas modifié) avec la fonction suivante :

int eris_get_container_name(int slot, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/container/name?index=<slot>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/name?index=0"
Test 1
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/name?index=1"
Liberis test
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/name?index=2"
SSH with Curl
# 

4.4 – Version du container installé dans un slot

Le numéro de version d’un container est, comme son nom, enregistré lors de sa création dans l’onglet « My Containers » du Device Manager. Une fois installé dans un slot, il peut être consulté avec la fonction suivante :

int eris_get_container_version(int slot, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/container/version?index=<slot>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/version?index=1"
1.4
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/version?index=2"
1.0

4.5 – État du container installé dans un slot

Il est possible de consulter l’état d’un container pour vérifier s’il fonctionne correctement.

int eris_get_container_status(int slot, char *buffer, size_t size);

L’état du container se trouvant dans le slot est représenté par la valeur numérique renvoyée, qui peut prendre l’une des 14 valeurs suivantes :

CodeSignification
-1Le slot est vide, il n’y a pas de container.
0Le container fonctionne correctement.
1Erreur lors du téléchargement de l’image du container.
2Erreur lors du décodage de l’image du container.
3Erreur durant l’extraction de l’image du container.
4Erreur à la vérification de la checksum de l’image du container.
5Erreur d’importation de l’image dans Docker.
6Erreur de lancement du container.
7Impossible de faire démarrer l’application.
8Application absente.
9Erreur durant l’exécution.
10Application terminée.
11Impossible de démarrer le débogage.
12Erreur interne du système de container d’Eris Linux.

Point d’accès Rest sur le port 8080 : GET /api/container/status?index=<slot>

La chaîne en réponse à la requête Rest commence par le numéro de status ci-dessus, suivi d’un libellé succinct.

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/status?index=0"
-1 empty

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/status?index=1"
0 running

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/status?index=2"
0 running

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/status?index=3"
0 running

4.6 – Lecture de la politique de mise à jour des containers

Eris propose deux politiques différentes pour les mises à jour des containers embarquant le code applicatif :

  • téléchargement, installation et redémarrage du container aussitôt que possible lors de la notification d’une nouvelle version (politique « immediate » ),
  • téléchargement immédiat de la nouvelle version d’un container, mais installation et démarrage au reboot du système (politique « atreboot » ).

La fonction suivante renvoie 0 si la politique en cours est atreboot et 1 si c’est immediate.

int eris_get_container_update_policy(void);

Point d’accès Rest sur le port 8080 : GET /api/container/policy

La requête renvoie la chaîne atreboot ou immediate.

Exemple:

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/policy"
immediate

4.7 – Écriture de la politique de mise à jour des containers

Pour fixer la politique de mise à jour décrite ci-dessus, on passe 0 en argument de la fonction suivante pour une mise à jour atreboot et 1 pour une politique immediate.

int eris_set_container_update_policy(int policy);

Point d’accès Rest sur le port 8080 : PUT /api/container/policy?policy=atreboot

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/container/policy?policy=atreboot"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/policy"
atreboot
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/container/policy?policy=immediate"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/container/policy"
immediate

5 – Nomenclature logicielle (SBOM)

Le terme de Bill of Materials (BOM) est très répandu dans les industries mécaniques et électroniques et recouvre l’ensemble des composants nécessaires pour un processus de fabrication. En informatique, principalement dans les systèmes embarqués, la Software BOM ou « nomenclature logicielle » est un descriptif de tous les éléments logiciels (applications, bibliothèque, collection d’utilitaires, etc.) nécessaires pour le bon fonctionnement d’un système.

Dans l’univers des logiciels libres, la SBOM prend une dimension légale, puisque la plupart des licences de type Open Source réclament que l’utilisateur final puisse connaître la liste des packages libres intégrés dans un équipement et, suivant le type de licence, leur numéro de version, leur provenance, les modifications logicielles éventuellement apportées et le texte complet de la licence.

La SBOM devient d’autant plus importante de nos jours que l’entrée en application du Cyber Resilience Act (C.R.A) la rend indispensable. La mise en conformité avec le C.R.A. d’un système basé sur Eris Linux sera discutée en détail dans un prochain article.

5.1 – Liste des packages installés

La première information importante à obtenir est la liste des packages sous licences libres installés sur le système. Il n’est pas nécessaire que cette liste contienne les applications sous licences propriétaires que l’on trouve dans les containers applicatifs. La fonction suivante remplit le buffer fourni avec la liste des packages installés sans jamais dépasser la limite indiquée.

int eris_get_list_of_packages(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/sbom/package/list

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/list"
base-files base-passwd bluez-firmware-rpidistro-bcm4345c0-hcd bluez-firmware-rpidistro-bcm4345c5-hcd bluez-firmware-rpidistro-cypress-license bluez5 bridge-utils build-timestamp busybox busybox-syslog busybox-udhcpc ca-certificates cgroup-lite containerd-opencontainers cryptsetup dbus dbus-common dbus-lib dbus-tools docker-compose docker-moby docker-moby-cli dosfstools dtc e2fsprogs e2fsprogs-badblocks e2fsprogs-dumpe2fs e2fsprogs-e2fsck e2fsprogs-mke2fs early-init encodings eris-api-server-dbg eris-configuration-files eris-containers eris-containers-early eris-containers-network eris-dashboard eris-first-boot eris-ntp eris-rest-api eris-update-service eris-update-service-notifier eris-update-service-updater eris-wifi-monitor eudev eudev-hwdb expat f2fs-tools fast-reboot file font-adobe-100dpi font-adobe-utopia-100dpi font-bh-100dpi font-bh-lucidatypewriter-100dpi font-bitstream-100dpi font-util fontconfig fontconfig-utils formfactor freetype gdb gdbserver gdk-pixbuf gdk-pixbuf-locale-en-gb get-dmk glib-2.0 glib-2.0-locale-en-gb gmp gnutls hdparm init-ifupdown init-system-helpers-service initscripts initscripts-functions iptables iptables-module-ip6t-ah iptables-module-ip6t-dnpt iptables-module-ip6t-dst iptables-module-ip6t-eui64 iptables-module-ip6t-frag iptables-module-ip6t-hbh iptables-module-ip6t-hl
[...]
util-linux-mcookie util-linux-mesg util-linux-mkfs util-linux-mkfs.cramfs util-linux-mkswap util-linux-more util-linux-mount util-linux-mountpoint util-linux-namei util-linux-nologin util-linux-nsenter util-linux-partx util-linux-pipesz util-linux-pivot-root util-linux-prlimit util-linux-readprofile util-linux-rename util-linux-renice util-linux-resizepart util-linux-rev util-linux-rfkill util-linux-rtcwake util-linux-script util-linux-scriptlive util-linux-scriptreplay util-linux-setarch util-linux-setpriv util-linux-setsid util-linux-setterm util-linux-sfdisk util-linux-sulogin util-linux-swaplabel util-linux-swapoff util-linux-swapon util-linux-switch-root util-linux-taskset util-linux-uclampset util-linux-ul util-linux-umount util-linux-unshare util-linux-utmpdump util-linux-uuidd util-linux-uuidgen util-linux-uuidparse util-linux-waitpid util-linux-wall util-linux-wdctl util-linux-whereis util-linux-wipefs util-linux-write util-linux-zramctl wireless-regdb-static wpa-supplicant wpa-supplicant-cli wpa-supplicant-passphrase wpa-supplicant-plugins xauth xdpyinfo xf86-input-libinput xf86-video-modesetting xhost xinit xinput xinput-calibrator xkbcomp xkeyboard-config xkeyboard-config-locale-en-gb xmodmap xorg-fonts-100dpi xrandr xserver-nodm-init xserver-xf86-config xserver-xorg xserver-xorg-extension-glx xset xsetroot zlib 

Il y a de très nombreux petits packages (modules du noyau par exemple) qui forment des packages indépendants. Cette liste est donc plutôt longue.

5.2 – Version d’un package installé

Le numéro de version d’un package fait partie des informations légales à fournir à l’utilisateur final s’il en fait la demande. On l’obtiendra avec la fonction suivante, qui remplit le buffer avec la version du package dont le nom est passé en argument (et qui doit appartenir à la liste précédemment renvoyée), sans dépasser la taille maximale indiquée en dernier paramètre :

int eris_get_package_version(const char *package_name, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/sbom/package/version?name=<package_name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/version?name=base-files"
3.0.14
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/version?name=busybox"
1.36.1
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/version?name=musl"
1.2.4+git

5.3 – Nom de recette d’un package

Eris Linux est construit en utilisant l’environnement Yocto Project, qui s’appuie sur des fichiers « recettes » pour produire les différents composants du système. La plupart du temps un composant donné est obtenu à partir de la recette de même nom. Parfois une même recette peut produire plusieurs packages. Il peut être important d’identifier la recette ayant généré un élément, grâce à la fonction suivante :

int eris_get_package_recipe(const char *package_name, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/sbom/package/recipe?name=<package_name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/recipe?name=busybox-syslog"
busybox
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/recipe?name=kernel-module-ath9k-htc-6.6.63-v8-16k"
linux-raspberrypi

5.4 – Licences d’un package

La distribution d’un composant peut être soumise, selon le choix de son auteur, aux termes d’une ou plusieurs licences logicielles. La fonction ci-dessous permet de retrouver les différentes licences concernant un package :

int eris_get_package_licenses(const char *package_name, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/sbom/package/licenses?name=<package_name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/licenses?name=busybox"
GPL-2.0-only & bzip2-1.0.4
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/licenses?name=f2fs-tools"
GPL-2.0-only
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/package/licenses?name=eris-rest-api"
LGPL-2.0-only
# 

5.5 – Liste des licences présentes

La fonction suivante remplit le buffer fourni avec la liste de toutes les licences utilisées par au moins un package installé sur le système.

int eris_get_list_of_licenses(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/sbom/license/list

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/license/list"
AFL-2.1 Apache-2.0 binary-redist-Cypress-rpidistro BSD-1-Clause BSD-2-Clause BSD-3-Clause BSD-4-Clause bzip2-1.0.4 bzip2-1.0.6 CC-BY-SA-4.0 CLOSED Firmware-cypress-rpidistro FTL GPL-1.0-or-later GPL-2.0-only GPL-2.0-or-later GPL-2.0-with-OpenSSL-exception GPL-3.0-only GPL-3.0-or-later GPL-3.0-with-GCC-exception hdparm HPND HPND-sell-variant IJG ISC LGPL-2.0-only LGPL-2.0-or-later LGPL-2.1-only LGPL-2.1-or-later LGPL-3.0-only LGPL-3.0-or-later Libpng MIT MPL-2.0 OFL-1.1 PD PSF-2.0 Synaptics-rpidistro Unicode-DFS-2016 Unicode-TOU Zlib

5.6 – Texte d’une licence

On peut obtenir le texte complet d’une licence utilisée par un package, en appelant la fonction suivante en lui passant le nom de la licence désirée en premier argument. Le buffer sera rempli avec le texte de la licence sans jamais dépasser la taille maximale indiquée.

int eris_get_license_text(const char *license_name, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/sbom/license/text?name=<license_name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/sbom/license/text?name=GPL-2.0-only"

GNU GENERAL PUBLIC LICENSE

Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble

[...]

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.

6 – Redémarrage du système

La plupart des systèmes embarqués sont amenés à redémarrer abruptement suite à des coupures d’alimentation brutales. Eris Linux ne fait pas exception et est prévu pour redémarrer correctement quelles que soient les circonstances de l’arrêt du système.

Il peut néanmoins être nécessaire de redémarrer intentionnellement le système, par exemple pour activer une nouvelle version d’Eris Linux préalablement installée.

6.1 – Redémarrage immédiat

Le fonction suivante demande un redémarrage immédiat du système. Elle doit être évidemment employée avec la plus grande prudence pour éviter d’interrompre un traitement important. Si une application est en train d’enregistrer des données dans un fichier, ces données seront perdues, et dans de très rares cas la partition de données peut être corrompue et nécessiter une réparation automatique, voire dans le pire des cas un reformatage complet.

int eris_reboot_now(void);

Point d’accès Rest sur le port 8080 : POST /api/reboot/now

Exemple :

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/reboot/now"
Read from remote host 192.168.3.6: Connection reset by peer
Connection to 192.168.3.6 closed.
client_loop: send disconnect: Broken pipe

6.2 – État d’attente de redémarrage

Après une mise à jour, le système reste en attente de reboot pendant trente secondes environ. On peut vérifier avec la fonction suivante si un redémarrage a été demandé (par exemple avant de lancer une tâche prenant du temps). Elle renvoie 1 si un reboot est programmé et 0 sinon.

int eris_get_pending_reboot_flag(void);

Point d’accès Rest sur le port 8080 : GET /api/reboot/pending

Exemple :

 # curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/reboot/pending"
no

6.3 – Demande de redémarrage

On peut avec la fonction suivante demander au système de redémarrer lors du prochain cycle de trente secondes, ou annuler une demande déjà programmée. L’argument doit être 1 pour programmer un redémarrage et 0 pour l’annuler.

int eris_set_reboot_pending_flag(int reboot);

Point d’accès Rest sur le port 8080 : POST /api/reboot/pending?reboot={y|n}

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/reboot/pending"
no
# curl  -X POST  -w '\n' "http://host.docker.internal:8080/api/reboot/pending?reboot=y"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/reboot/pending"
yes
# curl  -X POST  -w '\n' "http://host.docker.internal:8080/api/reboot/pending?reboot=n"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/reboot/pending"
no
# curl  -X POST  -w '\n' "http://host.docker.internal:8080/api/reboot/pending?reboot=y"
Ok

(Attente environ 45 secondes)
# Read from remote host 192.168.3.6: Connection reset by peer
Connection to 192.168.3.6 closed.
client_loop: send disconnect: Broken pipe

6.4 – Lecture du redémarrage automatique après mise à jour

Après l’installation d’une nouvelle version du système Eris Linux, deux comportements sont possibles :

  • redémarrage automatique au bout de trente secondes pour basculer sur la nouvelle version,
  • attendre un redémarrage explicitement demandé par le code applicatif via la fonction vue ci-dessus.

La fonction suivante permet de vérifier le comportement actuel. Elle renvoie 1 si le redémarrage se fait automatiquement, et 0 sinon.

int eris_get_automatic_reboot_flag(void);

Point d’accès Rest sur le port 8080 : GET /api/reboot/automatic

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/reboot/automatic"
yes

6.5 – Écriture du redémarrage automatique après mise à jour

On peut modifier avec la fonction suivante le comportement après mise à jour décrit ci-dessus, en passant un 1 en argument si l’on souhaite que désormais le système redémarre automatiquement quand une mise à jour est installée, ou un 0 si on préfère gérer les redémarrages depuis le code applicatif.

int eris_set_automatic_reboot_flag(int auto);

Point d’accès Rest sur le port 8080 : PUT /api/reboot/automatic

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/reboot/automatic?auto=n"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/reboot/automatic"
no
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/reboot/automatic?auto=y"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/reboot/automatic"
yes
# 

6.6 – Demande de rollback

Le système Eris Linux utilise un mécanisme de mise à jour dit « A/B » (et même A/B/Recovery pour être exact) : si après une mise à jour le système échoue à plusieurs reprises à redémarrer correctement, il revient automatiquement à la version précédente.

Ceci s’appuie sur la détection du fonctionnement correct des étapes de boot et le démarrage réussi des containers. Il peut néanmoins subsister des problèmes non détectés par le système Eris Linux et qui ne pourront être observés que par le code applicatif. Dans ce cas, il peut être nécessaire de demander explicitement un rollback (retour sur la version précédente) qui s’appliquera au prochain redémarrage.

int eris_rollback(void);

Point d’accès Rest sur le port 8080 : POST /api/reboot/rollback

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/system/version"
1.0.0-dev-30
# curl  -X POST  -w '\n' "http://host.docker.internal:8080/api/reboot/rollback"
Ok
# curl  -X POST  -w '\n' "http://host.docker.internal:8080/api/reboot/pending?reboot=y"
Ok
[...]
Après reboot...
[...]
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/system/version"
1.0.0-dev-29

6.7 – Demande de réinitialisation du système

Dans le cas où le système est totalement incapable de redémarrer, même après un rollback, Eris Linux tente un démarrage en réinitialisant la partition contenant toutes les données. Ceci remet le système dans un état proche de sa sortie d’usine. (Toutefois on reste sur la dernière version du code système, on ne revient pas sur le code en sortie d’usine qui contenait peut être des vulnérabilités corrigées depuis).

Au niveau applicatif, on peut demander à réinitialiser totalement la partition contenant les données par exemple avant de revendre l’équipement sur le marché de l’occasion. Ceci peut être effectué avec la fonction suivante :

int eris_restore_factory_preset(void);

En réalité cette fonction n’est pas encore implémentée et renvoie toujours la valeur -1, avec la variable globale errno positionnée à ENOSYS (fonction système non implémentée).

Point d’accès Rest sur le port 8080 : POST /api/reboot/factory

Exemple :

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/reboot/factory"
Feature not implemented yet.

7 – Watchdog

Sur un système embarqué, un watchdog (chien de garde) est un composant électronique qu’il faut notifier régulièrement. Au bout d’un temps donné sans notification il force le redémarrage du système. Pour les équipements sans watchdog matériel, le noyau Linux peut émuler cette fonctionnalité (avec l’inconvénient qu’il ne pourra pas détecter un kernel panic).

7.1 – Alimentation du watchdog

On peut appeler la fonction suivante régulièrement pour notifier le watchdog. Cela remet le compteur au délai maximal (configurable avec eris_set_watchdog_delay() ) et déclenche le décompte. Si le timer atteint zéro, le système redémarre.

int eris_feed_watchdog(void);

Point d’accès Rest sur le port 8080 : POST /api/watchdog

Exemple :

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/watchdog"
Ok

7.2 – Arrêt du watchdog

Pour arrêter le watchdog (par exemple le temps de faire une opération très coûteuse en charge processeur qui risque de retarder les notifications) on utilisera la fonction suivante. Il faut être conscient qu’une fois le watchdog arrêté, le système ne sera plus protégé contre les blocages du système.

int eris_disable_watchdog(void)

Point d’accès Rest sur le port 8080 : DELETE /api/watchdog

Exemple :

# curl  -X DELETE  -w '\n'  http://host.docker.internal:8080/api/watchdog
Ok

7.3 – Lecture du délai de redémarrage

Le délai (en secondes) entre la dernière notification et le redémarrage du système par le watchdog, est consultable avec la fonction :

int eris_get_watchdog_delay(void);

Point d’accès Rest sur le port 8080 : GET /api/watchdog/delay

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/watchdog/delay"
15

7.4 – Écriture du délai de redémarrage

On peut fixer le délai entre notification et redémarrage entre 1 et 48 secondes (pour être compatible avec l’essentiel des watchdogs) avec la fonction :

int eris_set_watchdog_delay(int seconds);

Point d’accès Rest sur le port 8080 : PUT /api/watchdog/delay?delay=<seconds>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/watchdog/delay"
15
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/watchdog/delay?delay=30"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/watchdog/delay"
30

7.5 – Démarrage d’un thread d’alimentation

Si on ne souhaite pas développer d’application qui alimente régulièrement le watchdog, il est possible de laisser travailler un thread spécifique du serveur REST dédié à cette tâche. Ce thread n’est pas lancé par défaut et nécessite d’être explicitement déclenché au démarrage du système.

int eris_start_watchdog_feeder(void);

Point d’accès Rest sur le port 8080 : POST /api/watchdog/feeder

Exemple :

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/watchdog/feeder"
Ok

7.6 – Arrêt du thread d’alimentation

On peut arrêter le thread d’alimentation automatique du watchdog avec :

int eris_stop_watchdog_feeder(void)

Point d’accès Rest sur le port 8080 : DELETE /api/watchdog/feeder

Exemple :

# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/watchdog/feeder"
Ok

7.7 – État du thread d’alimentation

On peut observer l’état du thread d’alimentation automatique. La fonction suivante écrit la chaîne running ou stopped dans le buffer passé en argument sans jamais dépasser la taille indiquée.

int eris_watchdog_feeder_status(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/watchdog/feeder

Exemple :

# curl  -X GET  -w '\n'   "http://host.docker.internal:8080/api/watchdog/feeder"
stopped
# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/watchdog/feeder"
Ok
# curl  -X GET  -w '\n'   "http://host.docker.internal:8080/api/watchdog/feeder"
running
# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/watchdog/feeder"
Already running
# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/watchdog/feeder"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/watchdog/feeder"
stopped
# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/watchdog/feeder"
Already stopped


8 – Horloge

Les systèmes embarqués ont souvent besoin d’interroger un serveur externe pour synchroniser l’heure du système sur celle d’une horloge officielle. Pour cela on peut activer ou non le protocole NTP (Network Time Protocol) servant à cette synchronisation, et le cas échéant configurer le nom ou l’adresse du serveur NTP.

Eris Linux propose également de configurer et consulter une horloge système. Il est également possible de choisir un fuseau horaire et de consulter l’heure locale.

8.1 – Lecture de l’utilisation de NTP

Le protocole NTP (Network Time Protocol) permet de synchroniser un équipement avec un serveur. On peut attendre la plupart du temps une précision de quelques dizaines de millisecondes lors d’un accès au serveur via Internet et quelques centaines de microsecondes lorsque le serveur et le client sont sur un réseau local.

La fonction suivante permet de vérifier si le protocole NTP est utilisé ou non sur l’équipement.

int eris_get_ntp_enable(void);

Point d’accès Rest sur le port 8080 : GET /api/time/ntp

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/ntp"
yes

8.2 – Écriture de l’utilisation de NTP

Avec la fonction suivante, on peut activer ou désactiver l’utilisation de NTP sur l’équipement.

int eris_set_ntp_enable(int enable);

Point d’accès Rest sur le port 8080 : PUT /api/time/ntp?status={yes|no}

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/ntp?status=no"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/ntp"
no
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/ntp?status=yes"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/ntp"
yes

8.3 – Lecture du serveur NTP

Si le protocole NTP est utilisé, on peut employer la fonction suivante pour connaître l’adresse du serveur NTP actif. L’adresse (ou le nom d’hôte) est écrite dans le buffer transmis en argument sans dépasser la taille indiquée.

int eris_get_ntp_server(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/time/ntp/server

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/ntp/server"
pool.ntp.org

8.4 – Écriture du serveur NTP

La fonction suivante permet d’indiquer l’adresse, ou le nom d’hôte, du serveur NTP à utiliser.

int eris_set_ntp_server(const char *server);

Point d’accès Rest sur le port 8080 : PUT /api/time/ntp/server?server=<address>

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/ntp/server?server=192.168.1.45"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/ntp/server"
192.168.1.45
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/ntp/server?server=pool.ntp.org"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/ntp/server"
pool.ntp.org

8.5 – Liste des fuseaux horaires

Pour configurer l’heure locale du système, on précise le fuseau horaire dans lequel il se trouve. On peut obtenir la liste des fuseaux horaires connus avec la fonction :

int eris_list_time_zones(char *buffer, size_t size)

Point d’accès Rest sur le port 8080 : GET /api/time/zone/list

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/zone/list"
Africa/Abidjan Africa/Accra Africa/Addis_Ababa Africa/Algiers Africa/Asmara Africa/Asmera Africa/Bamako
Africa/Bangui Africa/Banjul Africa/Bissau Africa/Blantyre Africa/Brazzaville Africa/Bujumbura Africa/Cairo
Africa/Casablanca Africa/Ceuta Africa/Conakry Africa/Dakar Africa/Dar_es_Salaam Africa/Djibouti Africa/Douala
Africa/El_Aaiun Africa/Freetown Africa/Gaborone Africa/Harare Africa/Johannesburg Africa/Juba Africa/Kampala
Africa/Khartoum Africa/Kigali Africa/Kinshasa Africa/Lagos Africa/Libreville Africa/Lome Africa/Luanda
Africa/Lubumbashi Africa/Lusaka Africa/Malabo Africa/Maputo Africa/Maseru Africa/Mbabane Africa/Mogadishu
Africa/Monrovia Africa/Nairobi Africa/Ndjamena Africa/Niamey Africa/Nouakchott Africa/Ouagadougou
Africa/Porto-Novo Africa/Sao_Tome Africa/Timbuktu Africa/Tripoli Africa/Tunis Africa/Windhoek America/Adak
America/Anchorage America/Anguilla America/Antigua America/Araguaina America/Aruba America/Asuncion
America/Atikokan America/Atka America/Bahia America/Bahia_Banderas America/Barbados America/Belem
America/Belize America/Blanc-Sablon America/Boa_Vista America/Bogota America/Boise America/Buenos_Aires
America/Cambridge_Bay America/Campo_Grande America/Cancun America/Caracas America/Catamarca America/Cayenne
America/Cayman America/Chicago America/Chihuahua America/Ciudad_Juarez America/Coral_Harbour America/Cordoba
America/Costa_Rica America/Coyhaique America/Creston America/Cuiaba America/Curacao America/Danmarkshavn
America/Dawson America/Dawson_Creek America/Denver America/Detroit America/Dominica America/Edmonton
America/Eirunepe America/El_Salvador America/Ensenada America/Fort_Nelson America/Fort_Wayne America/Fortaleza
America/Glace_Bay America/Godthab America/Goose_Bay America/Grand_Turk America/Grenada America/Guadeloupe
America/Guatemala America/Guayaquil America/Guyana America/Halifax America/Havana America/Hermosillo
America/Indianapolis America/Inuvik America/Iqaluit America/Jamaica America/Jujuy America/Juneau
America/Knox_IN America/Kralendijk America/La_Paz America/Lima America/Los_Angeles America/Louisville
America/Lower_Princes America/Maceio America/Managua America/Manaus America/Marigot America/Martinique
America/Matamoros America/Mazatlan America/Mendoza America/Menominee America/Merida America/Metlakatla
America/Mexico_City America/Miquelon America/Moncton America/Monterrey America/Montevideo America/Montreal
America/Montserrat America/Nassau America/New_York America/Nipigon America/Nome America/Noronha America/Nuuk
America/Ojinaga America/Panama America/Pangnirtung America/Paramaribo America/Phoenix America/Port-au-Prince
America/Port_of_Spain America/Porto_Acre America/Porto_Velho America/Puerto_Rico America/Punta_Arenas
America/Rainy_River America/Rankin_Inlet America/Recife America/Regina America/Resolute America/Rio_Branco
America/Rosario America/Santa_Isabel America/Santarem America/Santiago America/Santo_Domingo America/Sao_Paulo
America/Scoresbysund America/Shiprock America/Sitka America/St_Barthelemy America/St_Johns America/St_Kitts
America/St_Lucia America/St_Thomas America/St_Vincent America/Swift_Current America/Tegucigalpa America/Thule
America/Thunder_Bay America/Tijuana America/Toronto America/Tortola America/Vancouver America/Virgin
America/Whitehorse America/Winnipeg America/Yakutat America/Yellowknife Antarctica/Casey Antarctica/Davis
Antarctica/DumontDUrville Antarctica/Macquarie Antarctica/Mawson Antarctica/McMurdo Antarctica/Palmer
Antarctica/Rothera Antarctica/South_Pole Antarctica/Syowa Antarctica/Troll Antarctica/Vostok Arctic/Longyearbyen
Asia/Aden Asia/Almaty Asia/Amman Asia/Anadyr Asia/Aqtau Asia/Aqtobe Asia/Ashgabat Asia/Ashkhabad Asia/Atyrau
Asia/Baghdad Asia/Bahrain Asia/Baku Asia/Bangkok Asia/Barnaul Asia/Beirut Asia/Bishkek Asia/Brunei Asia/Calcutta
Asia/Chita Asia/Choibalsan Asia/Chongqing Asia/Chungking Asia/Colombo Asia/Dacca Asia/Damascus Asia/Dhaka
Asia/Dili Asia/Dubai Asia/Dushanbe Asia/Famagusta Asia/Gaza Asia/Harbin Asia/Hebron Asia/Ho_Chi_Minh
Asia/Hong_Kong Asia/Hovd Asia/Irkutsk Asia/Istanbul Asia/Jakarta Asia/Jayapura Asia/Jerusalem Asia/Kabul
Asia/Kamchatka Asia/Karachi Asia/Kashgar Asia/Kathmandu Asia/Katmandu Asia/Khandyga Asia/Kolkata
Asia/Krasnoyarsk Asia/Kuala_Lumpur Asia/Kuching Asia/Kuwait Asia/Macao Asia/Macau Asia/Magadan Asia/Makassar
Asia/Manila Asia/Muscat Asia/Nicosia Asia/Novokuznetsk Asia/Novosibirsk Asia/Omsk Asia/Oral Asia/Phnom_Penh
Asia/Pontianak Asia/Pyongyang Asia/Qatar Asia/Qostanay Asia/Qyzylorda Asia/Rangoon Asia/Riyadh Asia/Saigon
Asia/Sakhalin Asia/Samarkand Asia/Seoul Asia/Shanghai Asia/Singapore Asia/Srednekolymsk Asia/Taipei
Asia/Tashkent Asia/Tbilisi Asia/Tehran Asia/Tel_Aviv Asia/Thimbu Asia/Thimphu Asia/Tokyo Asia/Tomsk
Asia/Ujung_Pandang Asia/Ulaanbaatar Asia/Ulan_Bator Asia/Urumqi Asia/Ust-Nera Asia/Vientiane Asia/Vladivostok
Asia/Yakutsk Asia/Yangon Asia/Yekaterinburg Asia/Yerevan Atlantic/Azores Atlantic/Bermuda Atlantic/Canary
Atlantic/Cape_Verde Atlantic/Faeroe Atlantic/Faroe Atlantic/Jan_Mayen Atlantic/Madeira Atlantic/Reykjavik
Atlantic/South_Georgia Atlantic/St_Helena Atlantic/Stanley Australia/ACT Australia/Adelaide Australia/Brisbane
Australia/Broken_Hill Australia/Canberra Australia/Currie Australia/Darwin Australia/Eucla Australia/Hobart
Australia/LHI Australia/Lindeman Australia/Lord_Howe Australia/Melbourne Australia/NSW Australia/North
Australia/Perth Australia/Queensland Australia/South Australia/Sydney Australia/Tasmania Australia/Victoria
Australia/West Australia/Yancowinna Brazil/Acre Brazil/DeNoronha Brazil/East Brazil/West CET CST6CDT
Canada/Atlantic Canada/Central Canada/Eastern Canada/Mountain Canada/Newfoundland Canada/Pacific
Canada/Saskatchewan Canada/Yukon Chile/Continental Chile/EasterIsland Cuba EET EST EST5EDT Egypt Eire Etc/GMT
Etc/GMT+0 Etc/GMT+1 Etc/GMT+10 Etc/GMT+11 Etc/GMT+12 Etc/GMT+2 Etc/GMT+3 Etc/GMT+4 Etc/GMT+5 Etc/GMT+6
Etc/GMT+7 Etc/GMT+8 Etc/GMT+9 Etc/GMT-0 Etc/GMT-1 Etc/GMT-10 Etc/GMT-11 Etc/GMT-12 Etc/GMT-13 Etc/GMT-14
Etc/GMT-2 Etc/GMT-3 Etc/GMT-4 Etc/GMT-5 Etc/GMT-6 Etc/GMT-7 Etc/GMT-8 Etc/GMT-9 Etc/GMT0 Etc/Greenwich Etc/UCT
Etc/UTC Etc/Universal Etc/Zulu Europe/Amsterdam Europe/Andorra Europe/Astrakhan Europe/Athens Europe/Belfast
Europe/Belgrade Europe/Berlin Europe/Bratislava Europe/Brussels Europe/Bucharest Europe/Budapest Europe/Busingen
Europe/Chisinau Europe/Copenhagen Europe/Dublin Europe/Gibraltar Europe/Guernsey Europe/Helsinki
Europe/Isle_of_Man Europe/Istanbul Europe/Jersey Europe/Kaliningrad Europe/Kiev Europe/Kirov Europe/Kyiv
Europe/Lisbon Europe/Ljubljana Europe/London Europe/Luxembourg Europe/Madrid Europe/Malta Europe/Mariehamn
Europe/Minsk Europe/Monaco Europe/Moscow Europe/Nicosia Europe/Oslo Europe/Paris Europe/Podgorica Europe/Prague
Europe/Riga Europe/Rome Europe/Samara Europe/San_Marino Europe/Sarajevo Europe/Saratov Europe/Simferopol
Europe/Skopje Europe/Sofia Europe/Stockholm Europe/Tallinn Europe/Tirane Europe/Tiraspol Europe/Ulyanovsk
Europe/Uzhgorod Europe/Vaduz Europe/Vatican Europe/Vienna Europe/Vilnius Europe/Volgograd Europe/Warsaw
Europe/Zagreb Europe/Zaporozhye Europe/Zurich Factory GB GB-Eire GMT GMT+0 GMT-0 GMT0 Greenwich HST Hongkong
Iceland Indian/Antananarivo Indian/Chagos Indian/Christmas Indian/Cocos Indian/Comoro Indian/Kerguelen Indian/Mahe
Indian/Maldives Indian/Mauritius Indian/Mayotte Indian/Reunion Iran Israel Jamaica Japan Kwajalein Libya MET MST
MST7MDT Mexico/BajaNorte Mexico/BajaSur Mexico/General NZ NZ-CHAT Navajo PRC PST8PDT Pacific/Apia Pacific/Auckland
Pacific/Bougainville Pacific/Chatham Pacific/Chuuk Pacific/Easter Pacific/Efate Pacific/Enderbury Pacific/Fakaofo
Pacific/Fiji Pacific/Funafuti Pacific/Galapagos Pacific/Gambier Pacific/Guadalcanal Pacific/Guam Pacific/Honolulu
Pacific/Johnston Pacific/Kanton Pacific/Kiritimati Pacific/Kosrae Pacific/Kwajalein Pacific/Majuro
Pacific/Marquesas Pacific/Midway Pacific/Nauru Pacific/Niue Pacific/Norfolk Pacific/Noumea Pacific/Pago_Pago
Pacific/Palau Pacific/Pitcairn Pacific/Pohnpei Pacific/Ponape Pacific/Port_Moresby Pacific/Rarotonga
Pacific/Saipan Pacific/Samoa Pacific/Tahiti Pacific/Tarawa Pacific/Tongatapu Pacific/Truk Pacific/Wake
Pacific/Wallis Pacific/Yap Poland Portugal ROC ROK Singapore Turkey UCT US/Alaska US/Aleutian US/Arizona
US/Central US/East-Indiana US/Eastern US/Hawaii US/Indiana-Starke US/Michigan US/Mountain US/Pacific US/Samoa UTC
Universal W-SU WET Zulu

8.6 – Lecture du fuseau horaire du système

On peut consulter le fuseau horaire actuellement configuré avec la fonction :

int eris_get_time_zone(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/time/zone

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/zone"
UTC

8.7 – Écriture du fuseau horaire du système

Pour fixer le fuseau horaire, on utilisera la fonction suivante, en passant un argument un des noms de zones renvoyés dans la liste précédemment vue.

int eris_set_time_zone(const char *timezone);

Point d’accès Rest sur le port 8080 : PUT /api/time/zone?zone=<zone-name>

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/zone?zone=Europe/Paris"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/zone"
Europe/Paris

8.8 – Lecture de l’heure locale

L’heure locale du système est déterminée en se basant sur son fuseau horaire. Elle est inscrite dans le buffer sans dépasser la taille indiquée. Le format contient :

  • l’année sur 4 chiffres,
  • le mois sur 2 chiffres,
  • le jour sur 2 chiffres,
  • l’heure sur deux chiffres,
  • les minutes sur deux chiffres,
  • les secondes sur deux chiffres,
  • les microsecondes sur 6 chiffres.
int eris_get_local_time(char *buffer, size_t size)

Point d’accès Rest sur le port 8080 : GET /api/time/local

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/zone"
UTC
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/local"
2026-09-07 18:48:41:554132
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/zone?zone=Europe/Paris"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/local"
2026-09-07 20:48:47:615302
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/zone?zone=America/New_York"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/local"
2026-09-07 14:48:52:373670

8.9 – Lecture de l’heure système

L’heure système ne dépend pas du fuseau horaire. Elle est normalement alignée sur l’heure UTC, récupérée au démarrage depuis un composant nommé « RTC » (Real Time Clock) et ajustée régulièrement depuis un serveur NTP. On peut lire sa valeur avec la fonction suivante, le format est le même que l’heure locale :

int eris_get_system_time(char *buffer, size_t size)

Point d’accès Rest sur le port 8080 : GET /api/time/system

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/zone?zone=UTC"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/system"
2026-09-07 18:58:14:578329
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/local"
2026-09-07 18:58:16:194981
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/zone?zone=Europe/Paris"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/system"
2026-09-07 18:58:19:412932
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/local"
2026-09-07 20:58:21:126631

8.10 – Écriture de l’heure système

Bien qu’il soit préférable d’utiliser un protocole comme NTP, il est possible de modifier l’heure système depuis une application avec la fonction suivante. La chaîne time_string attendue est <year>-<month>-<day>T<hour>:<minute>:<second>.

int eris_set_system_time(const char *time_string);

Point d’accès Rest sur le port 8080 : PUT /api/time/system?time=<time-string>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/system"
2026-09-07 19:08:13:098130
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/time/system?time=2025-08-07T18:06:17"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/time/system"
2025-08-07 18:06:20:480723

9 – Réseau

Les exemples que nous utiliserons dans cette section sont exécutés sur un Raspberry Pi 5 disposant de deux interfaces réseau (Ethernet et Wifi), avec deux adresses sur le même sous-réseau, comme il l’indique au Device Manager :

Fig. 1 – Adresses IP du Raspberry Pi d’exemple.

9.1 – Liste des interfaces disponibles

La première étape de configuration du réseau consiste souvent à déterminer la liste des interfaces disponibles. La fonction suivante remplit le buffer en argument avec cette liste, sans dépasser la taille maximale indiquée. Les interfaces listées sont celles reposant sur des composants matériels physiques, pas d’interface virtuelle, de communication avec un container ou de loopback.

int eris_get_list_of_network_interfaces(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/network/interface/list

Exemple :

# curl  -X GET  -w '\n'  http://host.docker.internal:8080/api/network/interface/list
wlan0 eth0

9.2 – Lecture de l’état d’une interface

On peut consulter l’état d’une interface pour savoir si elle est active (up) ou non (down). Si l’interface est up, le résultat contient également son adresse IP et le masque du sous-réseau.

int eris_get_network_interface_status(const char *interface_name, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/network/interface/status?name=<interface-name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/status?name=eth0"
up 192.168.3.6 255.255.255.0 
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/status?name=wlan0"
up 192.168.3.36 255.255.255.0 

9.3 – Écriture de l’état d’une interface

On peut activer ou désactiver une interface avec la fonction suivante en lui passant up ou down en second argument.

int eris_set_network_interface_status(const char *interface, const char *status);

Point d’accès Rest sur le port 8080 : PUT /api/network/interface/status?name=<interface-name>&status={up|down}

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/network/interface/status?name=eth0&status=down"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/status?name=eth0"
down 
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/network/interface/status?name=eth0&status=up"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/status?name=eth0"
up 192.168.3.6 255.255.255.0 

9.4 – Lecture de la configuration d’une interface

La configuration d’une interface réseau est une suite de champs séparés par des espaces :

  • nom de l’interface (par exemple eth0),
  • atboot si l’interface doit être automatiquement activée au démarrage du système ou ondemand si l’activation doit se faire par la méthode vue ci-dessus,
  • dhcp si l’interface doit interroger un serveur pour obtenir sa configuration IP, ou static si la configuration est fournie à la suite,
  • (si configuration static) ipv4 ou ipv6 selon le type d’adresse acceptée,
  • (si configuration static) adresse IP de l’équipement sur l’interface,
  • (si configuration static) masque de sous-réseau de l’interface,
  • (si configuration static) adresse IP d’une passerelle pour sortir du sous-réseau.
int eris_get_network_interface_config(const char *interface, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/network/interface/config?name=<interface-name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/config?name=eth0"
eth0 atboot dhcp
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/config?name=wlan0"
wlan0 ondemand dhcp

9.5 – Écriture de la configuration d’une interface

La configuration d’une interface peut se faire en précisant les arguments suivants :

  • activation de l’interface dès le démarrage (atboot) ou sur requête explicite (ondemand),
  • mode d’initialisation de l’adresse IP (dhcp ou static),
  • (si mode static) choix entre adresses ipv4 ou ipv6,
  • (si mode static) adresse IP de l’équipement,
  • (si mode static) masque du sous-réseau,
  • (si mode static) adresse de la passerelle de sortie du sous-réseau.
int eris_set_network_interface_config(const char *interface, const char *activate, const char *mode, const char *ip, const char *address, const char *netmask, const char *gateway);

Point d’accès Rest sur le port 8080 : PUT /api/network/interface/config?name=<interface-name>&activate={atboot|ondemand}&mode={dhcp|static}&ip={ipv4|ipv6}&address=<ip-address>&netmask=<ip-mask>&gateway=<gw-address>

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/network/interface/config?name=eth0&activate=ondemand&mode=static&ip=ipv4&address=192.168.3.100&netmask=255.255.255.0&gateway=192.168.3.254"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/config?name=eth0"
eth0 ondemand static ipv4 192.168.3.100 255.255.255.0 192.168.3.254
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/network/interface/config?name=eth0&activate=atboot&mode=dhcp"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/config?name=eth0"
eth0 atboot dhcp
# 

9.6 – Lecture de la connectivité d’une interface

On peut vérifier avec la fonction suivante si une interface est filaire (valeur renvoyée 0) ou sans fil (valeur renvoyée 1) ;

int eris_is_network_interface_wireless(const char *interface);

Point d’accès Rest sur le port 8080 : GET /api/network/interface/wireless&name=<interface-name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/wireless?name=eth0"
no
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/interface/wireless?name=wlan0"
yes

9.7 – Lecture de l’adresse du DNS

Le serveur de nom ou DNS (Domain Name Server) fait la résolution des noms d’hôtes pour obtenir des adresses IP. La fonction suivante permet de récupérer l’adresse du serveur DNS actuellement utilisé dans la variable buffer sans dépasser la taille maximale indiquée :

int eris_get_nameserver_address(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/network/dns

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/dns"
192.168.3.254

9.8 – Écriture de l’adresse du DNS

Pour fixer l’adresse du serveur DNS on utilisera la fonction :

int eris_set_nameserver_address(const char *address);

Point d’accès Rest sur le port 8080 : PUT /api/network/dns?address=<ip-address>

Exemple :

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/network/dns?address=8.8.8.8"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/dns"
8.8.8.8
# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/network/dns?address=192.168.3.254"
Ok
# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/dns"
192.168.3.254
# 

9.9 – Scan des réseaux Wifi accessibles

Si une interface est wireless, on peut récupérer la liste des réseaux wifi détectés.

Le même nom de réseau peut être présent à plusieurs reprises, si plusieurs fréquences (exemple 2.4 GHz et 5 GHz).

int eris_scan_wifi(const char *interface, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/network/wifi?name=<interface-name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/wifi?name=wlan0"
LogilinLab
Guest
LogilinLab

# 

9.10 – Connexion sur un réseau Wifi

La connexion sur un réseau Wifi peut se faire avec la fonction suivante en passant le nom de l’interface wireless concernée, l’identifiant SSID du réseau (comprise dans la liste renvoyée par la fonction précédente), et le mot de passe d’accès au réseau. La commande REST est susceptible d’évoluer dans l’avenir pour que le SSID et le mot de passe soient transmis dans le corps de la requête.

int eris_connect_wifi(const char *interface, const char *ssid, const char *password);

Point d’accès Rest sur le port 8080 : POST /api/network/wifi/connection?name=<interface-name>&ssid=<ssid-string>&pass=<password>

Exemple :

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/network/wifi/connection?name=wlan0&ssid=Guest&pass=Welcome"
ok

9.11 – Déconnexion d’un réseau Wifi

La déconnexion du réseau wifi sur lequel l’équipement est connecté peut s’obtenir avec :

int eris_disconnect_wifi(void);

Point d’accès Rest sur le port 8080 : DELETE /api/network/wifi/connection

Exemple :

# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/network/wifi/connection"
Ok

9.12 – Lecture de la qualité de la connexion Wifi

La qualité de la connexion Wifi est renvoyée sous forme de trois valeurs :

  • link : (qualité du lien) valeur calculée pour estimer la qualité du lien. L’échelle peut dépendre du driver et est généralement entre 0 et 70. Plus la valeur est élevée, meilleure est la connexion.
  • level: valeur mesurée en dBm de force du signal. Plus elle est élevée, mieux c’est. Un niveau de -30dBm à -50dBm est très bon. En dessous de -80 dBm, le lien est trop faible pour une connexion fiable.
  • noise : mesure physique du niveau de bruit entourant le signal utile. En dessous de -90dBm on considère le niveau de bruit très faible (liaison très bonne). Au dessus de -70dBm le signal est très bruité.

Ces valeurs sont très dépendantes du driver. Je suppose que le niveau de bruit de -256dB que l’on voit ci-dessous signifie plutôt que la mesure n’est pas disponible.

int eris_get_wifi_quality(const char *interface, char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/network/wifi/quality&name=<interface-name>

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/network/wifi/quality?name=wlan0"
link=64 level=-46 noise=-256

10 – GPIO

10.1 – Liste des GPIO

La liste des GPIO est disponible sous forme d’un tableau au format JSON avec une entrée pour chaque GPIO. Chaque entrée contient deux champs :

  • id est la référence de la ligne GPIO. Elle est construite en associant le nom du contrôleur GPIO, un caractère deux-points et l’offset de la ligne vis-à-vis du contrôleur. Par exemple gpiochip0:23. Ce champ identifie la GPIO de manière unique.
  • name est le nom indiqué pour la ligne GPIO dans le device tree (description du matériel). Ce champ peut être significatif, par exemple GPIO23, mais peut également être vide ou ne contenir que des caractères underscore _.
int eris_get_list_of_gpio(char *buffer, size_t size);

Point d’accès Rest sur le port 8080 : GET /api/gpio/list

Exemple :

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/gpio/list"
[{"id":"gpiochip10:0","name":"_"},{"id":"gpiochip10:1","name":"2712_BOOT_CS_N"},{"id":"gpiochip10:2","name":"2712_BOOT_MISO"},{"id":"gpiochip10:3","name":"2712_BOOT_MOSI"},
 {"id":"gpiochip10:4","name":"2712_BOOT_SCLK"},{"id":"gpiochip10:5","name":"_"},{"id":"gpiochip10:6","name":"_"},{"id":"gpiochip10:7","name":"_"},
 {"id":"gpiochip10:8","name":"_"},{"id":"gpiochip10:9","name":"_"},{"id":"gpiochip10:10","name":"_"},{"id":"gpiochip10:11","name":"_"},
 {"id":"gpiochip10:12","name":"_"},{"id":"gpiochip10:13","name":"_"},{"id":"gpiochip10:14","name":"PCIE_SDA"},{"id":"gpiochip10:15","name":"PCIE_SCL"},
 [...]
 {"id":"gpiochip0:22","name":"GPIO22"},{"id":"gpiochip0:23","name":"GPIO23"},{"id":"gpiochip0:24","name":"GPIO24"},{"id":"gpiochip0:25","name":"GPIO25"},
 {"id":"gpiochip0:26","name":"GPIO26"},{"id":"gpiochip0:27","name":"GPIO27"},{"id":"gpiochip0:28","name":"PCIE_RP1_WAKE"},{"id":"gpiochip0:29","name":"FAN_TACH"},
 {"id":"gpiochip0:30","name":"HOST_SDA"},{"id":"gpiochip0:31","name":"HOST_SCL"},{"id":"gpiochip0:32","name":"ETH_RST_N"},{"id":"gpiochip0:33","name":"_"},
 {"id":"gpiochip0:34","name":"CD0_IO0_MICCLK"},{"id":"gpiochip0:35","name":"CD0_IO0_MICDAT0"},{"id":"gpiochip0:36","name":"RP1_PCIE_CLKREQ_N"},{"id":"gpiochip0:37","name":"_"},
 {"id":"gpiochip0:38","name":"CD0_SDA"},{"id":"gpiochip0:39","name":"CD0_SCL"},{"id":"gpiochip0:40","name":"CD1_SDA"},{"id":"gpiochip0:41","name":"CD1_SCL"},
 {"id":"gpiochip0:42","name":"USB_VBUS_EN"},{"id":"gpiochip0:43","name":"USB_OC_N"},{"id":"gpiochip0:44","name":"RP1_STAT_LED"},{"id":"gpiochip0:45","name":"FAN_PWM"},
 {"id":"gpiochip0:46","name":"CD1_IO0_MICCLK"},{"id":"gpiochip0:47","name":"2712_WAKE"},{"id":"gpiochip0:48","name":"CD1_IO1_MICDAT1"},{"id":"gpiochip0:49","name":"EN_MAX_USB_CUR"},
 {"id":"gpiochip0:50","name":"_"},{"id":"gpiochip0:51","name":"_"},{"id":"gpiochip0:52","name":"_"},{"id":"gpiochip0:53","name":"_"}
]

10.2 – Réservation d’une ligne GPIO

Avec les fonctions suivantes on peut réserver une ligne GPIO en entrée ou en sortie. Dans le cas d’une sortie, on précisera la valeur initiale (0 ou 1) à appliquer à cette ligne dès sa réservation. La fonction renvoie 0 si la réservation a réussi ou -1 en cas d’erreur. Si la GPIO est déjà réservée, la fonction échoue.

int eris_request_gpio_for_input(const char *id);
int eris_request_gpio_for_output(const char *id, int value);

Point d’accès Rest sur le port 8080 : POST /api/gpio?id=<gpio-id>&direction={in|out}&value={0|1}

Exemple :

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:23&direction=in"
Ok

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:24&direction=out&value=1"
Ok

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:23&direction=in"
GPIO line is already reserved by Eris API.

10.3 – Libération d’une ligne GPIO

Une ligne précédemment réservée peut être libérée avec la fonction suivante. Une tentative de double libération renvoie une erreur.

int eris_release_gpio(const char *id);

Point d’accès Rest sur le port 8080 : DELETE /api/gpio?id=<gpio-id>

Exemple :

# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:23"
Ok

# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:24"
Ok

# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:24"
GPIO already free.

10.4 – Lecture d’une valeur sur une ligne GPIO

On peut lire l’état d’une entrée GPIO précédemment réservée avec la fonction :

int eris_read_gpio_value(const char *id);

Point d’accès Rest sur le port 8080 : GET /api/gpio/value?id=<gpio-id>

Exemple :

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:23&direction=in"
Ok

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/gpio/value?id=gpiochip0:23"
0   (GPIO 23 broche 16 reliée à la masse broche 20)

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/gpio/value?id=gpiochip0:23"
1   (GPIO 23 broche 16 reliée au +3.3 broche 17)

# curl  -X GET  -w '\n'  "http://host.docker.internal:8080/api/gpio/value?id=gpiochip0:23"
0   (GPIO 23 broche 16 reliée à la masse broche 20)

# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:23"
Ok

10.5 – Écriture d’une valeur sur une ligne GPIO

Pour écrire la valeur de sortie d’une GPIO précédemment réservée on utilisera la fonction suivante :

int eris_write_gpio_value(const char *id, int value);

Point d’accès Rest sur le port 8080 : PUT /api/gpio/value?id=<gpio-id>&value={0|1}

Exemple :

# curl  -X POST  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:24&direction=out&value=0"
Ok

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/gpio/value?id=gpiochip0:24&value=1"
Ok   (On mesure 3.3V sur la broche 18 GPIO 24)

# curl  -X PUT  -w '\n'  "http://host.docker.internal:8080/api/gpio/value?id=gpiochip0:24&value=0"
Ok   (On mesure 0V sur la broche 18 GPIO 24)

# curl  -X DELETE  -w '\n'  "http://host.docker.internal:8080/api/gpio?id=gpiochip0:24"
Ok

Conclusion

Les fonctions et requêtes REST vues ci-dessus constituent les possibilités actuelles d’interaction entre les applications se trouvant dans les containers et le système Eris Linux sous-jacent. Toutefois le projet Eris est toujours en évolution et de nouvelles méthodes seront prochainement ajoutées. Par exemple des fonctions sont en cours de développement pour la communication bas-niveau avec des équipements sur des bus comme SPI et I²C. D’autre part des fonctionnalités de haut-niveau seront bientôt ajoutées comme la géolocalisation si un récepteur GPS est présent ou l’orientation de l’équipement pour rotation automatique de l’écran si un accéléromètre est disponible.

Pour enrichir ces API, le concours d’utilisateurs ou d’entreprises souhaitant expérimenter Eris Linux nous est très précieux. N’hésitez pas à me contacter si vous souhaitez tester Eris et nous faire des retours sur des cas d’usage réels.

URL de trackback pour cette page