Files
shipheart-appli/sources/reseaux.c
T

1080 lines
46 KiB
C

// **********************************************************************************************************************************************************************************
// Fichier RESEAUX.C
//
// Contient toutes les fonctions liées aux réseaux (Ethernet et Wifi en mode STA et AP notamment).
// **********************************************************************************************************************************************************************************
//#define __DEBUG_RESEAUX //Décommenter cette ligne pour avoir les messages de debug concernant les reseaux
//#define __DEBUG_SHIP2NET //Décommenter cette ligne pour avoir les messages de debug concernat les accès à Ship2net
// Include :
#include "main.h"
// Prototypes :
void gestion_reseaux(void);
int8_t init_reseaux(void);
int8_t connexion_ship2net();
int8_t process_webgl(uint8_t no);
int8_t get_ip_address(void);
int8_t get_ssid_list(void);
// Variables globales :
struct Struct_reseaux reseaux;
//**********************************************************************************************************************************************************************************
// Fonction : Gestion des interfaces Wifi
// Reçoit : Rien
// Retourne : Rien
//**********************************************************************************************************************************************************************************
void gestion_reseaux(void)
{
uint16_t i;
FILE * ptr_fichier;
uint8_t channel;
char hw_mode[5]; // A priori, 'a' ou 'g'...
char commande[MAX_TAILLE_COMMANDE_SHELL];
char ligne[MAX_LONGUEUR_LIGNE_FICHIER_CONFIG_RESEAUX];
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
switch(reseaux.sequenceur.etat)
{
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_INIT :
{
if (reseaux.sequenceur.compteur == 0)
{
reseaux.compteur_check_adresses_ip = RESEAUX_PERIODE_CHECK_ADRESSE_IP_INIT; // En plaçant l'init de la tempo ici, on est sûr qu'elle démarre après la phase d'initialisation
reseaux.compteur_connexion_ship2net = RESEAUX_PERIODE_CONNEXION_SHIP2NET_INIT;
reseaux.compteur_scan_sta = RESEAUX_PERIODE_SCAN_WIFI_STA_INIT;
reseaux.compteur_check_webgl = RESEAUX_PERIODE_CHECK_WEBGL_INIT;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_REPOS;
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_REPOS :
{
//==================================
// Nouvelle configuration Wifi reçue :
if (reseaux.wifi_new.flag_new_config)
{
reseaux.wifi_new.flag_new_config = FALSE;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_LANCEMENT_MISE_A_JOUR_WIFI_STA;
break;
}
//==================================
// Demande de scan de Wifi STA reçue :
if (reseaux.wifi_new.sta.flag_dde_scan)
{
reseaux.wifi_new.sta.flag_dde_scan = false;
reseaux.compteur_scan_sta = reseaux.periode_scan_sta; // Réarmement du compteur automatique puisqu'une demande manuelle a été reçue
if ((reseaux.wifi.sta.cde == ON) && (reseaux.wifi_new.sta.cde == ON)) reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_SCAN_WIFI_STA_LANCEMENT; // Si le Wifi STA est OFF ou si on demande qu'il passe OFF, il est inutile de faire un scan (qui pourra bloquer le séquenceur 20 secondes si time-out)
break;
}
//==================================
// Scan périodique du Wifi STA :
if ((reseaux.periode_scan_sta != 0) && (reseaux.compteur_scan_sta == 0))
{
reseaux.compteur_scan_sta = reseaux.periode_scan_sta;
if ((reseaux.wifi.sta.cde == ON) && (reseaux.wifi_new.sta.cde == ON)) reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_SCAN_WIFI_STA_LANCEMENT; // Si le Wifi STA est OFF ou si on demande qu'il passe OFF, il est inutile de faire un scan (qui pourra bloquer le séquenceur 20 secondes si time-out)
break; // Pas obligatoire mais permet de lisser la charge
}
//==================================
// Vérification périodique des adresses IP :
if ((reseaux.periode_check_adresses_ip != 0) && (reseaux.compteur_check_adresses_ip == 0))
{
reseaux.compteur_check_adresses_ip = reseaux.periode_check_adresses_ip;
get_ip_address();
break; // Pas obligatoire mais permet de lisser la charge
}
//==================================
// Connexion Ship2net :
if ((reseaux.periode_connexion_ship2net != 0) && (reseaux.compteur_connexion_ship2net == 0))
{
reseaux.compteur_connexion_ship2net = reseaux.periode_connexion_ship2net;
connexion_ship2net();
break; // Pas obligatoire mais permet de lisser la charge
}
//==================================
// Processus WebGL :
if (reseaux.compteur_check_webgl == 0)
{
reseaux.compteur_check_webgl = RESEAUX_PERIODE_CHECK_WEBGL;
for (i = 0; i < MAX_NOMBRE_PROCESS_WEBGL; i++)
{
if ((reseaux.webgl_new[i].validite != reseaux.webgl[i].validite) ||
(strcmp(reseaux.webgl_new[i].parametres, reseaux.webgl[i].parametres) != 0))
{
process_webgl(i);
}
}
break; // Pas obligatoire mais permet de lisser la charge
}
break;
}
//=========================================================================================================
// Wifi mode STA :
//=========================================================================================================
// La procédure est la suivante :
// - Si modification demandée du fichier 'wpa_supplicant' :
// - mise à jour du fichier,
// - redémarrage du service dhcp Attention : le restart du service redemarre wlan0 s'il était OFF. D'où la nécessité de traiter les commandes APRES le fichier...
// - redémarrage du daemon de service Pas sûr que ce soit aboslument nécessaire - A TESTER
// - Si changement de commande :
// - Si commande == ON, passage à up de wlan0 Utile s'il était Off ET qu'on n'a pas fait de modif de fichier (sinon, le restart de dhcp a dû le redémarrer)
// - Sinon (OFF), passage à down de wlan0 Utile s'il était On OU si on a fait une modif de fichier (et que le restart de dhcp l'a redémarré)
// - Fin pour STA
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_LANCEMENT_MISE_A_JOUR_WIFI_STA :
{
// Vérification si une modification du fichier 'wpa_supplicant.conf' est nécessaire :
if ((strcmp(reseaux.wifi_new.sta.ssid, reseaux.wifi.sta.ssid) != 0) ||
(strcmp(reseaux.wifi_new.sta.bssid, reseaux.wifi.sta.bssid) != 0) ||
(strcmp(reseaux.wifi_new.sta.psk, reseaux.wifi.sta.psk) != 0) )
{
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_MAJ_FICHIER_WPA_SUPPLICANT; // Début de mise à jour du fichier
}
else // S'il n'y a pas besoin de modifier le fichier 'hostapd.conf' :
{
if (reseaux.wifi_new.sta.cde != reseaux.wifi.sta.cde)
{
if (reseaux.wifi_new.sta.cde == ON) reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_STA_UP; // Commande de mise à ON
else reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_STA_DOWN; // Commande de mise à OFF
}
else reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_FIN_MISE_A_JOUR_WIFI_STA; // Fin de traitement STA
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_MAJ_FICHIER_WPA_SUPPLICANT :
{
// Regénération complete (plus simple...) du fichier de config 'wpa_supplicant.conf' :
ptr_fichier = fopen(NOM_FICHIER_WPA_SUPPLICANT, "w"); // Le fichier est juste ouvert en écriture (donc il est créé s'il n'existe pas et il est vidé s'il existe)
if (ptr_fichier != NULL)
{
sprintf(ligne, "country=FR\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "ap_scan=1\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "update_config=1\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "network={\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "\tssid=\"%s\"\n", reseaux.wifi_new.sta.ssid);
fputs(ligne, ptr_fichier);
sprintf(ligne, "\tpsk=\"%s\"\n", reseaux.wifi_new.sta.psk);
fputs(ligne, ptr_fichier);
sprintf(ligne, "\tbssid=%s\n", reseaux.wifi_new.sta.bssid);
fputs(ligne, ptr_fichier);
sprintf(ligne, "}\n");
fputs(ligne, ptr_fichier);
fclose(ptr_fichier);
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "Le fichier 'wpa_supplicant.conf' a été mis à jour avec succès.");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
else
{
sprintf(tmp, "/!\\ La mise à jour du fichier de 'wpa_supplicant.conf' n'est pas possible. La configuration se poursuit néanmoins...");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_MAJ_FICHIER_WPA_SUPPLICANT;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_DHCPCD_RESTART;
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_COMMANDE_DHCPCD_RESTART :
{
if (reseaux.sequenceur.compteur == 0)
{
// Rechargement du service DHCPCD (mode STA) :
sprintf(commande, "sudo systemctl restart dhcpcd.service &"); // Le '&' permet de libérer l'exécution. La tempo en fin de Case permet de gérer l'attente...
if (commande_shell(commande) != 0)
{
sprintf(tmp, "Le rechargement de DHCPCD (Wifi STA) par la commande [%s] a rencontré une erreur. La procédure continue néanmoins...", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
#ifdef __DEBUG_RESEAUX
else
{
sprintf(tmp, "Le rechargement de DHCPCD (Wifi STA) par la commande [%s] a été effectuée avec succès.", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
}
#endif
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_DHCPCD_RESTART;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_DAMEON_SERVICES_RESTART;
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_COMMANDE_DAMEON_SERVICES_RESTART :
{
if (reseaux.sequenceur.compteur == 0)
{
// Rechargement du Daemon de services (mode STA) :
sprintf(commande, "sudo systemctl daemon-reload &"); // Le '&' permet de libérer l'exécution. La tempo en fin de Case permet de gérer l'attente...
if (commande_shell(commande) != 0)
{
sprintf(tmp, "Le rechargement du Daemon de Services (Wifi STA) par la commande [%s] a rencontré une erreur. La procédure continue néanmoins...", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
#ifdef __DEBUG_RESEAUX
else
{
sprintf(tmp, "Le rechargement du Daemon de Services (Wifi STA) par la commande [%s] a été effectuée avec succès.", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
}
#endif
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_DAMEON_SERVICES_RESTART;
if (reseaux.wifi_new.sta.cde == ON) reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_STA_UP; // Commande de mise à ON
else reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_STA_DOWN; // Commande de mise à OFF
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_STA_UP :
{
if (reseaux.sequenceur.compteur == 0)
{
// Passage de l'interface WLAN0 (mode STA) à UP :
sprintf(commande, "sudo ip link set wlan0 up &"); // Le '&' permet de libérer l'exécution. La tempo en fin de Case permet de gérer l'attente...
if (commande_shell(commande) != 0)
{
sprintf(tmp, "La passage de l'interface WLAN0 (Wifi STA) à UP par la commande [%s] a rencontré une erreur. La procédure continue néanmoins...", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
#ifdef __DEBUG_RESEAUX
else
{
sprintf(tmp, "La passage de l'interface WLAN0 (Wifi STA) à UP par la commande [%s] a été effectuée avec succès.", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
}
#endif
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_COMMANDE_WIFI_STA_UP;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_FIN_MISE_A_JOUR_WIFI_STA;
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_STA_DOWN :
{
if (reseaux.sequenceur.compteur == 0)
{
// Passage de l'interface WLAN0 (mode STA) à DOWN :
sprintf(commande, "sudo ip link set wlan0 down &"); // Le '&' permet de libérer l'exécution. La tempo en fin de Case permet de gérer l'attente...
if (commande_shell(commande) != 0)
{
sprintf(tmp, "La passage de l'interface WLAN0 (Wifi STA) à DOWN par la commande [%s] a rencontré une erreur. La procédure continue néanmoins...", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
#ifdef __DEBUG_RESEAUX
else
{
sprintf(tmp, "La passage de l'interface WLAN0 (Wifi STA) à DOWN par la commande [%s] a été effectuée avec succès.", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
}
#endif
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_COMMANDE_WIFI_STA_DOWN;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_FIN_MISE_A_JOUR_WIFI_STA;
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_FIN_MISE_A_JOUR_WIFI_STA :
{
if (reseaux.sequenceur.compteur == 0) reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_LANCEMENT_MISE_A_JOUR_WIFI_AP;
break;
}
//=========================================================================================================
// Wifi mode AP :
//=========================================================================================================
// La procédure est la suivante :
// - Si modification demandée du fichier 'hostapd' :
// - mise à jour du fichier,
// - redémarrage du service hostapd
// - Si changement de commande :
// - Si commande == ON, passage à up de uap0
// - Sinon (OFF), passage à down de uap0
// - Fin pour AP
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_LANCEMENT_MISE_A_JOUR_WIFI_AP :
{
// Vérification si action sur AP est nécessaire :
if ((strcmp(reseaux.wifi_new.ap.ssid, reseaux.wifi.ap.ssid) != 0) ||
(strcmp(reseaux.wifi_new.ap.pwd, reseaux.wifi.ap.pwd) != 0) ||
(reseaux.wifi_new.ap.canal != reseaux.wifi.ap.canal) )
{
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_MAJ_FICHIER_HOSTPAD;
}
else // S'il n'y a pas besoin de modifier le fichier 'hostapd.conf' :
{
if (reseaux.wifi_new.ap.cde != reseaux.wifi.ap.cde)
{
if (reseaux.wifi_new.ap.cde == ON) reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_AP_UP; // Commande de mise à ON
else reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_AP_DOWN; // Commande de mise à OFF
}
else reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_FIN_MISE_A_JOUR_WIFI; // Fin de traitement
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_MAJ_FICHIER_HOSTPAD :
{
// Regénération complete (plus simple...) du fichier de config 'hostapd.conf' :
ptr_fichier = fopen(NOM_FICHIER_HOSTAPD, "w"); // Le fichier est juste ouvert en écriture (donc il est créé s'il n'existe pas et il est vidé s'il existe)
if (ptr_fichier != NULL)
{
sprintf(ligne, "country_code=FR\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "interface=uap0\n");
fputs(ligne, ptr_fichier);
switch(reseaux.wifi_new.ap.canal)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
{
channel = reseaux.wifi_new.ap.canal;
strcpy(hw_mode, "g");
break;
}
case 36:
case 40:
case 44:
case 48:
// Les canaux > 48 déclenchent une erreurlors de la prise en compte par 'hostapd'...
// Ils apparaissent effectivement avec la mention '(no IR, radar detection)' dans le retour de 'iw list'.
/* case 52:
case 56:
case 60:
case 64:
case 100:
case 104:
case 108:
case 112:
case 116:
case 120:
case 124:
case 128:
case 132:
case 136:
case 140:
*/
{
channel = reseaux.wifi_new.ap.canal;
strcpy(hw_mode, "a");
break;
}
default:
{
channel = 8;
strcpy(hw_mode, "g");
}
}
sprintf(ligne, "hw_mode=%s\n", hw_mode);
fputs(ligne, ptr_fichier);
sprintf(ligne, "channel=%i\n", channel);
fputs(ligne, ptr_fichier);
sprintf(ligne, "ssid=%s\n", reseaux.wifi_new.ap.ssid);
fputs(ligne, ptr_fichier);
sprintf(ligne, "wpa_passphrase=%s\n", reseaux.wifi_new.ap.pwd);
fputs(ligne, ptr_fichier);
sprintf(ligne, "macaddr_acl=0\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "auth_algs=1\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "ignore_broadcast_ssid=0\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "wpa=2\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "wpa_key_mgmt=WPA-PSK\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "wpa_pairwise=TKIP\n");
fputs(ligne, ptr_fichier);
sprintf(ligne, "rsn_pairwise=CCMP\n");
fputs(ligne, ptr_fichier);
fclose(ptr_fichier);
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "Le fichier 'hostpad.conf' a été mis à jour avec succès.");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
else
{
sprintf(tmp, "/!\\ La mise à jour du fichier de 'hostapd' n'est pas possible. La configuration se poursuit néanmoins...");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_MAJ_FICHIER_HOSTAPD;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_HOSTAPD_RESTART;
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_COMMANDE_HOSTAPD_RESTART :
{
if (reseaux.sequenceur.compteur == 0)
{
// Rechargement du service HOSTAPD (mode AP) :
sprintf(commande, "sudo systemctl restart hostapd.service &"); // Le '&' permet de libérer l'exécution. La tempo en fin de Case permet de gérer l'attente...
if (commande_shell(commande) != 0)
{
sprintf(tmp, "Le rechargement de HOSTAPD (Wifi AP) par la commande [%s] a rencontré une erreur. La procédure continue néanmoins...", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
#ifdef __DEBUG_RESEAUX
else
{
sprintf(tmp, "Le rechargement de HOSTAPD (Wifi AP) par la commande [%s] a été effectuée avec succès.", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
}
#endif
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_HOSTAPD_RESTART;
if (reseaux.wifi_new.ap.cde == ON) reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_AP_UP; // Commande de mise à ON
else reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_AP_DOWN; // Commande de mise à OFF
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_AP_UP :
{
if (reseaux.sequenceur.compteur == 0)
{
// Passage de l'interface UAP0 (mode AP) à UP :
sprintf(commande, "sudo ip link set uap0 up &"); // Le '&' permet de libérer l'exécution. La tempo en fin de Case permet de gérer l'attente...
if (commande_shell(commande) != 0)
{
sprintf(tmp, "Le passage de l'interface UAP0 (Wifi AP) à UP par la commande [%s] a rencontré une erreur. La procédure continue néanmoins...", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
#ifdef __DEBUG_RESEAUX
else
{
sprintf(tmp, "Le passage de l'interface UAP0 (Wifi AP) à UP par la commande [%s] a été effectuée avec succès.", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
}
#endif
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_COMMANDE_WIFI_AP_UP;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_FIN_MISE_A_JOUR_WIFI;
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_COMMANDE_WIFI_AP_DOWN :
{
if (reseaux.sequenceur.compteur == 0)
{
// Passage de l'interface UAP0 (mode AP) à DOWN :
sprintf(commande, "sudo ip link set uap0 down &"); // Le '&' permet de libérer l'exécution. La tempo en fin de Case permet de gérer l'attente...
if (commande_shell(commande) != 0)
{
sprintf(tmp, "Le passage de l'interface UAP0 (Wifi AP) à DOWN par la commande [%s] a rencontré une erreur. La procédure continue néanmoins...", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
}
#ifdef __DEBUG_RESEAUX
else
{
sprintf(tmp, "Le passage de l'interface UAP0 (Wifi AP) à DOWN par la commande [%s] a été effectuée avec succès.", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
}
#endif
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_COMMANDE_WIFI_AP_DOWN;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_FIN_MISE_A_JOUR_WIFI; // Le mode AP est déjà arrêté, on a terminé...
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_FIN_MISE_A_JOUR_WIFI :
{
if (reseaux.sequenceur.compteur == 0)
{
strcpy(reseaux.wifi_new.sta.adresse_ip, reseaux.wifi.sta.adresse_ip); // Ce sont les 2 seuls champs qui sont à jour dans 'wifi' et pas dans 'wifi_new'....
strcpy(reseaux.wifi_new.ap.adresse_ip, reseaux.wifi.ap.adresse_ip);
reseaux.wifi = reseaux.wifi_new; // Mise à jour d'un coup de 'wifi' avec les valeurs de 'wifi_new'.
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_REPOS;
}
break;
}
//=========================================================================================================
// Scan Wifi STA :
//=========================================================================================================
// La procédure est la suivante :
// - Lancement de la commande shell qui va réaliser le scan et déposer le résultat dans un fichier temporaire
// - Attente d'une seconde, et vérification si la taille du fichier est nulle.
// - si taille = 0, relance la tempo (1s) et boucle
// - si taille != 0, lecture du fichier, formatage de la liste et mise à jour dans la BDD
// - Fin du scan
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_SCAN_WIFI_STA_LANCEMENT :
{
get_ssid_list(); // Lancement du scan proprement dit
reseaux.time_out_scan_sta = RESEAUX_TIME_OUT_LECTURE_FICHIER_SCAN_STA;
reseaux.sequenceur.compteur = TEMPO_ATTENTE_BOUCLE_SCAN_WIFI_STA;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_SCAN_WIFI_STA_ATTENTE_FIN;
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_SCAN_WIFI_STA_ATTENTE_FIN :
{
if ((reseaux.wifi.sta.cde == OFF) || (reseaux.wifi_new.sta.cde == OFF)) // Si le Wifi STA est OFF ou si on demande à le passer OFF, inutile de continuer le scan qui risque de bloquer le séquenceur jusqu'à 20 secondes (de time-out)
{
sprintf(tmp, "La commande du Wifi STA est OFF ou une demande à passer OFF est en cours. Le scan du Wifi STA est donc arrêtée...");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
reseaux.time_out_scan_sta = 0;
reseaux.sequenceur.compteur = 0;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_REPOS;
}
if (reseaux.sequenceur.compteur == 0)
{
// Lire la taille du fichier :
sprintf(tmp, "%s/%s", REPERTOIRE_TMP_WIFI, NOM_FICHIER_SCAN_WIFI_STA);
ptr_fichier = fopen(tmp, "rb"); // Ouverture du fichier en "lecture"...
if (ptr_fichier != NULL)
{
fseek (ptr_fichier, 0, SEEK_END); // Place le curseur à la fin du fichier
if (ftell(ptr_fichier) != 0) // Lit la position du curseur, donc la taille...
{
fclose(ptr_fichier); // Fermeture du fichier (on duplique le close ici car il y a un break juste après...)
reseaux.time_out_scan_sta = 0; // RAZ "par principe"
reseaux.sequenceur.compteur = TEMPO_ATTENTE_FIN_SCAN_WIFI_STA; // Lancement petite tempo pour être sûr que le remplissage du fichier est terminé
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_SCAN_WIFI_STA_TRAITEMENT; // Passage du séquenceur au traitement à la fin de cette petite tempo
break;
}
}
fclose(ptr_fichier); // Fermeture du fichier si l'on n'est pas sorti avant avec un fichier non vide
// Vérification s'il faut poursuivre l'attente ou considérer le scan comme ayant échoué :
if (-- reseaux.time_out_scan_sta != 0) reseaux.sequenceur.compteur = TEMPO_ATTENTE_BOUCLE_SCAN_WIFI_STA; // Si on n'a pas encore atteint le time-out, on relance une tempo d'attente
else reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_REPOS; // Time out !!
}
break;
}
//--------------------------------------------------------
case ETAT_SEQUENCEUR_RESEAUX_SCAN_WIFI_STA_TRAITEMENT :
{
if (reseaux.sequenceur.compteur == 0)
{
sprintf(tmp, "%s/%s", REPERTOIRE_TMP_WIFI, NOM_FICHIER_SCAN_WIFI_STA);
ptr_fichier = fopen(tmp, "rb"); // Ouverture du fichier en "lecture"...
if (ptr_fichier != NULL)
{
//fseek (ptr_fichier, 0, SEEK_SET); // Place le curseur au début du fichier
clear_scan_wifi_sta(); // Supprime les entrées non 'connues' de TB_Wifi_sta
int val, tot; // L'utilisation de 'int' est guidée par l'utilisation de sscanf
char * ptr;
char chaine[100];
char mac_ssid[100];
char nom_ssid[100];
uint8_t canal_ssid = 0;
uint8_t qualite_ssid = 0;
// Lecture d'une ligne :
while (fgets(commande, MAX_TAILLE_COMMANDE_SHELL, ptr_fichier) != NULL)
{
commande[strlen(commande) - 1] = 0; // Suppression du LF de fin
//----------------------------------------------
// Détection de début de cellule :
// Ligne du type : Cell 01 - Address: 94:A6:7E:B0:BE:C7
if ((strstr(commande, "Cell") != NULL) && (strstr(commande, "- Address") != NULL))
{
mac_ssid[0]= 0;
canal_ssid = 0;
qualite_ssid = 0;
nom_ssid[0] = 0;
}
//----------------------------------------------
ptr = strstr(commande, "Address: ");
if (ptr != NULL) // Ligne du type : Cell 01 - Address: 94:A6:7E:B0:BE:C7
{
sprintf(mac_ssid, "%s", (ptr + strlen("Address: ")) ); // Positionnement du début de chaine après "Address: " donc extraction de "94:A6:7E:B0:BE:C7'
}
//----------------------------------------------
ptr = strstr(commande, "Channel:");
if (ptr != NULL) // Ligne du type : Channel:44
{
sprintf(chaine, "%s", (ptr + strlen("Channel:")) ); // Positionnement du début de chaine après "Channel:" donc extraction de "44"
canal_ssid = atoi(chaine);
}
//----------------------------------------------
ptr = strstr(commande, "Quality=");
if (ptr != NULL) // Ligne du type : Quality=57/70 Signal level=-53 dBm
{
sprintf(chaine, "%s", (ptr + strlen("Quality=")) ); // Positionnement du début de chaine après "Quality=" donc extraction de "57/70 Signal level=-53 dBm"
sscanf(chaine, "%d/%d", &val, &tot); // Extraction de 57 et 70
if (tot != 0) qualite_ssid = ((val * 100) / tot);
else qualite_ssid = 1; // On évite le 0 qui ferait supprimer cette entrée (et le fait de ne pas décoder correctement le niveau n'est pas bloquant)
}
//----------------------------------------------
ptr = strstr(commande, "SSID:");
if (ptr != NULL) // Ligne du type : ESSID:"Koriolan"
{
sprintf(nom_ssid, "%s", (ptr + strlen("SSID:") + 1) ); // Le '+1' permet de supprimer le '"' de début du nom
nom_ssid[strlen(nom_ssid) - 1] = 0; // Suppression du '"' de fin de nom
}
// Traitement d'une cellule :
if ((mac_ssid[0] != 0) && (canal_ssid != 0) && (qualite_ssid != 0) && (nom_ssid[0] != 0))
{
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "SSID lu dans fichier de scan : %s [mac = %s, canal = %i et niveau = %i %%]", nom_ssid, mac_ssid, canal_ssid, qualite_ssid);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
#endif
enregistrement_scan_wifi_sta(mac_ssid, nom_ssid, canal_ssid, qualite_ssid); // Enregistrement du SSID dans la liste (ou mise à jour si déjà connu)
// Pour ne pas enregistrer à nouveau ce SSID si d'autres champs suivent avant la prochaine cellule :
mac_ssid[0]= 0;
canal_ssid = 0;
qualite_ssid = 0;
nom_ssid[0] = 0;
}
}
}
else ; // Dans le cas où on ne peut pas ouvrir le fichier, on abandonne le scan...
fclose(ptr_fichier); // Fermeture du fichier
reseaux.sequenceur.compteur = 0;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_REPOS;
}
break;
}
//=========================================================================================================
// Default :
//=========================================================================================================
//--------------------------------------------------------
default :
{
sprintf(tmp, "L'état du séquenceur Reseaux est inconnu [%i]. Il est repositionné au REPOS", reseaux.sequenceur.etat);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_REPOS;
break;
}
}
}
//**********************************************************************************************************************************************************************************
// Fonction : Init des interfaces Wifi
// Reçoit : Rien
// Retourne : 0 si aucune erreur, -1 sinon
//**********************************************************************************************************************************************************************************
int8_t init_reseaux(void)
{
uint8_t i;
if (systeme.generation_shipbase == GENERATION_SHIPBASE_V1)
{
reseaux.compteur_connexion_ship2net = 0;
reseaux.periode_connexion_ship2net = 0; // Permet de "bloquer" toute connexion réseau (la connexion se fait alors par 'modem.c')
}
else
{
// L'init des compteurs se fait dans la phase d'init du séquenceur. Cela permet de les déclncher après la tempo d'init du séquenceur.
}
// Variables générales :
strcpy(reseaux.ethernet.adresse_ip, ADRESSE_IP_INCONNUE);
strcpy(reseaux.wifi.sta.adresse_ip, ADRESSE_IP_INCONNUE);
strcpy(reseaux.wifi.ap.adresse_ip, ADRESSE_IP_INCONNUE);
reseaux.wifi_new = reseaux.wifi; // Permet par la suite de comparer 'wifi_new' avec 'wifi' pour détecter les changements
reseaux.wifi.sta.cde = -1; // Valeur d'init pour forcer une mise à jour de la commande.
reseaux.wifi.ap.cde = -1; // Valeur d'init pour forcer une mise à jour de la commande.
reseaux.wifi_new.flag_new_config = TRUE;
for (i = 0; i < MAX_NOMBRE_PROCESS_WEBGL; i++) reseaux.webgl[i].parametres[0] = 0; // Chaine vide pour être sûr de déclencher une analyse au premier passage si la config existe
reseaux.sequenceur.compteur = RESEAUX_TEMPO_INIT;
reseaux.sequenceur.etat = ETAT_SEQUENCEUR_RESEAUX_INIT;
// Affichage du message de débug :
affichage_debug(__FILE__, __LINE__, "Initialisation des interfaces Wifi\t: OK", TYPE_MESSAGE_DEBUG_OK);
return(0);
}
//==================================================================================================================================================================
// Fonction : Lancement de l'utilitaire de connexion à ship2net
// Reçoit : Rien
// Renvoit : 0 si aucune erreur, -1 si une erreur a été détectée
//==================================================================================================================================================================
int8_t connexion_ship2net(void)
{
int8_t retour = 0;
int32_t pid_nb;
char commande[MAX_TAILLE_COMMANDE_SHELL];
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
// Récupération du nombre de process incluant 'connexion_ship2net.php' :
pid_nb = get_pid_numbers_from_name(NOM_FICHIER_CONNEXION_SHIP2NET, "");
// Connexion si aucun processus équivalent n'est déjà en cours :
if (pid_nb <= 0) // Il ny a aucun processus de connexion à Ship2net en cours...
{
sprintf(download.nom_repertoire_source, "%s/%s%s/", REPERTOIRE_SERVEUR, conversion_adresse_mac_chaine(systeme.modules_physiques[0].adresse_mac, tmp, '_'), REPERTOIRE_DOWNLOAD_SOURCE);
sprintf(commande, "runuser -l koriolan --session-command='nice -n 18 php %s/%s %s >%s/%s &'", REPERTOIRE_UTILS, NOM_FICHIER_CONNEXION_SHIP2NET, conversion_adresse_mac_chaine(systeme.modules_physiques[0].adresse_mac, tmp, '_'), REPERTOIRE_LOGS, NOM_FICHIER_CONNEXION_SHIP2NET_LOG); // AVEC '&' de terminaison car c'était bien l'objectif, de faire exécuter cette tâche en tâche de fond...!
// Attention : le lancement de la commande ne doit PAS se faire depuis 'root' car la gestion des mots de passe est faite sur le user 'koriolan'.... Comme l'appli est lancée via 'sudo', il faut demander explicitement l'éxécution de la commande depuis le user 'koriolan'.
commande_shell(commande);
if (pid_nb == 0)
{
if (systeme.compteur_check_new_download > RESEAUX_PERIODE_CHECK_DOWWNLOAD_APRES_CONNEXION) // SDIR #295
{
systeme.compteur_check_new_download = RESEAUX_PERIODE_CHECK_DOWWNLOAD_APRES_CONNEXION; // SDIR #196 : Raccourci la tempo pour qu'une vérification soir effectuée 60s après la connexion
}
sprintf(tmp, "La commande de connexion à Ship2net [%s] vient d'être lancée en tâche de fond car aucun processus équivalent n'a été détecté en cours d'exécution", commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK);
}
else
{
sprintf(tmp, "Le retour de recherche de processus de connexion à Ship2net en cours a détecté une erreur (%i). La connexion demandée est exécutée quand même...", pid_nb);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
retour = -1;
}
}
else // Il y a déjà un processus en cours :
{
sprintf(tmp, "Au moins un processus de connexion à Ship2net a été détecté en cours d'exécution (nb = %i). La connexion demandée n'est donc pas exécutée...", pid_nb);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
retour = -1;
}
return(retour);
}
//==================================================================================================================================================================
// Fonction : Lancement de l'utilitaire de lancement/arrêt d'un process WebGL
// Reçoit : le n° de process WebGL à traiter (entre 0 et MAX_NOMBRE_PROCESS_WEBGL)
// Renvoit : 0 si aucune erreur, -1 si une erreur a été détectée
//==================================================================================================================================================================
int8_t process_webgl(uint8_t no)
{
int8_t retour = 0;
int32_t pid_nb;
int32_t pid;
char commande[MAX_TAILLE_COMMANDE_SHELL];
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
// Récupération du nombre de process incluant 'shipheart_qt' :
pid_nb = get_pid_numbers_from_name(NOM_FICHIER_QT, reseaux.webgl_new[no].parametres);
//----------------------------------------------------------------------------------
// Il n'y a aucun processus WebGL correspondant en cours :
if (pid_nb <= 0)
{
if (reseaux.webgl_new[no].validite > 0) // La commande est ON :
{
sprintf(commande, "runuser -l koriolan --session-command='%s/%s* %s >/dev/null 2>&1 &' ", REPERTOIRE_VERSIONS_CURRENT, NOM_FICHIER_QT, reseaux.webgl_new[no].parametres); // AVEC '&' de terminaison car c'était bien l'objectif, de faire exécuter cette tâche en tâche de fond...!
// Attention : le lancement de la commande ne doit PAS se faire depuis 'root' car la gestion des mots de passe est faite sur le user 'koriolan'.... Comme l'appli est lancée via 'sudo', il faut demander explicitement l'éxécution de la commande depuis le user 'koriolan'.
sprintf(tmp, "Démarrage du processus WebGL #%i par la commande [ %s ]", no, commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
commande_shell(commande);
}
else ; // La commande est OFF, on ne fait rien...
}
//----------------------------------------------------------------------------------
// Il y a un ou plusieurs processus WebGL correspondand en cours :
else
{
if (reseaux.webgl_new[no].validite > 0) ; // La commande est ON, on ne fait rien...
else // La commande est OFF :
{
pid = get_pid_from_name(NOM_FICHIER_QT, reseaux.webgl_new[no].parametres);
if (pid >= 0)
{
sprintf(commande, "sudo kill %i ", pid);
sprintf(tmp, "Fermeture du processus WebGL #%i par la commande [ %s ]", no, commande);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
commande_shell(commande);
}
else
{
sprintf(tmp, "Le processus WebGL #%i semble être en cours d'exécution mais la recherche de son PID est impossible. Le processus ne peut donc pas être tué...", no);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
retour = -1;
}
}
}
// Mise à jour des valeurs courantes :
reseaux.webgl[no].validite = reseaux.webgl_new[no].validite;
strcpy(reseaux.webgl[no].parametres, reseaux.webgl_new[no].parametres);
return(retour);
}
//==================================================================================================================================================================
// Fonction : Récupère la liste des SSID accessibles via 'wlan0' (en mode STA donc)
// Reçoit : Rien
// Renvoit : 0 si aucune erreur, -1 si une erreur a été détectée
//==================================================================================================================================================================
int8_t get_ssid_list(void)
{
char commande[MAX_TAILLE_COMMANDE_SHELL];
// sprintf(commande, "sudo iw dev wlan0 scan | grep -i 'ssid\\|signal' | grep -i -v 'ssid list' >%s/%s & ", REPERTOIRE_TMP_WIFI, NOM_FICHIER_SCAN_WIFI_STA); // Le '&' est impératif à la fin car la commande prend plusieurs secondes en général...
sprintf(commande, "sudo iwlist wlan0 scan | grep -i 'Address:\\|Channel:\\|ESSID:\\|Quality=' >%s/%s & ", REPERTOIRE_TMP_WIFI, NOM_FICHIER_SCAN_WIFI_STA); // Le '&' est impératif à la fin car la commande prend plusieurs secondes en général...
//printf("Commande = [%s] \n", commande);
commande_shell(commande);
/*
sudo iw dev wlan0 scan | grep -i 'ssid\|signal' | grep -i -v 'ssid list'
signal: -55.00 dBm
SSID: Koriolan
signal: -35.00 dBm
SSID: DIRECT-87-HP M277 LaserJet
signal: -78.00 dBm
SSID: ShipHeartkbane
signal: -62.00 dBm
SSID: Koriolan
*/
/*
sudo iwlist wlan0 scan | grep -i 'Address:\|Channel:\|ESSID:\|Quality='
Cell 01 - Address: 94:A6:7E:B0:BE:C7
Channel:44
Quality=43/70 Signal level=-67 dBm
ESSID:"Koriolan"
Cell 02 - Address: 94:A6:7E:B0:BE:C6
Channel:2
Quality=59/70 Signal level=-51 dBm
ESSID:"Koriolan"
Cell 03 - Address: 46:1C:A8:3D:63:87
Channel:6
Quality=70/70 Signal level=-37 dBm
ESSID:"DIRECT-87-HP M277 LaserJet"
Cell 04 - Address: F8:F0:05:7D:22:0F
Channel:7
Quality=34/70 Signal level=-76 dBm
ESSID:"ShipHeartkbane"
*/
return (0);
}
//==================================================================================================================================================================
// Fonction : Récupère l'adresse IP en cours
// Cette fonction a été trouvée ici : https://subscription.packtpub.com/book/cloud-and-networking/9781789349863/1/ch01lvl1sec22/listing-network-adapters-from-c
// dans la partie Unix.
// Par défaut, elle retourne quelque chose comme :
// lo IPv4 127.0.0.1
// eth0 IPv4 192.168.1.31
// wlan0 IPv4 192.168.1.155
// uap0 IPv4 192.168.4.1
// lo IPv6 ::1
// eth0 IPv6 fdee:db1c:59f9:4580:4c1d:fd37:e2de:a1ec
// eth0 IPv6 fe80::7a6a:c1c1:b0f1:3b13%eth0
// wlan0 IPv6 fdee:db1c:59f9:4580:b9d:6312:d3e8:3c09
// wlan0 IPv6 fe80::46f3:ad7e:44b2:2802%wlan0
// uap0 IPv6 fe80::e65f:1ff:feed:e67c%uap0
// La version du site a été adaptée pour ne prendre en compte que les interfaces en IPV4 puis uniquement les interfaces appelées 'eth0', 'wlan0' et 'uap0'
// Mais il est facile de l'étendre à d'autres interfaces si besoin voire en IPV6. ATTENTION dans ce cas, certains tailles (comme 'family_size' seront à revoir...)
// A noter que les exemples trouvées le plus fréquemment, à base de 'socket()' et 'ioctl()', ne fonctionnent pas bien !!
// Reçoit : Rien
// Renvoit : 0 si aucune erreur, -1 si une erreur a été détectée
//==================================================================================================================================================================
int8_t get_ip_address(void)
{
struct ifaddrs *addresses;
struct ifaddrs *address;
char chaine_ip[TAILLE_ADRESSE_IP];
const uint32_t family_size = sizeof(struct sockaddr_in);
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
// Recherche de la liste de toutes les interfaces disponibles :
if (getifaddrs(&addresses) == -1)
{
sprintf(tmp, "L'appel de la fonction 'getifaddrs()' a échoué. La recherche d'adresse IP ne peut pas se poursuivre...");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
return -1;
}
// Valeur par défaut, dans le cas où la liaison serait perdue (après la recherche des interfaces, car si celle-ci a échoué, on garde les anciennes valeurs) :
strcpy(reseaux.ethernet.adresse_ip, ADRESSE_IP_INCONNUE);
strcpy(reseaux.wifi.sta.adresse_ip, ADRESSE_IP_INCONNUE);
strcpy(reseaux.wifi.ap.adresse_ip, ADRESSE_IP_INCONNUE);
// Boucle sur toutes les interfaces reçues :
address = addresses;
while(address)
{
int family = address->ifa_addr->sa_family;
// if (family == AF_INET || family == AF_INET6) // AF_INET correspond à IPV4 et AF_INET6 correspond à IPV6
if (family == AF_INET) // On ne traite que les IPV4 pour le moment...
{
getnameinfo(address->ifa_addr, family_size, chaine_ip, TAILLE_ADRESSE_IP_V4, 0, 0, NI_NUMERICHOST); // Permet de récupérer la
if (strstr(address->ifa_name, "eth0") != NULL)
{
if ((address->ifa_flags & IFF_RUNNING) != 0) strcpy(reseaux.ethernet.adresse_ip, chaine_ip); // Le test du bit 'IFF_RUNNING' est nécessaire car le port peut être UP (visible via IFF_UP équivalent de 'ifconfig') mais ne pas être physiquement connecté...
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "Adresse IP sur le réseau Ethernet du bord = %s [IFF_RUNNING=%s]", reseaux.ethernet.adresse_ip, ((address->ifa_flags & IFF_RUNNING) == 0 ? "Non" : "Oui") );
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
else if (strstr(address->ifa_name, "wlan0") != NULL)
{
if ((address->ifa_flags & IFF_RUNNING) != 0) strcpy(reseaux.wifi.sta.adresse_ip, chaine_ip); // Le test du bit 'IFF_RUNNING' est nécessaire car le port peut être UP (visible via IFF_UP équivalent de 'ifconfig') mais ne pas être physiquement connecté...
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "Adresse IP sur le réseau Wifi du bord (connecté en mode STA) = %s [IFF_RUNNING=%s]", reseaux.wifi.sta.adresse_ip, ((address->ifa_flags & IFF_RUNNING) == 0 ? "Non" : "Oui") );
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
else if (strstr(address->ifa_name, "uap0") != NULL)
{
if ((address->ifa_flags & IFF_RUNNING) != 0) strcpy(reseaux.wifi.ap.adresse_ip, chaine_ip); // Le test du bit 'IFF_RUNNING' est nécessaire car le port peut être UP (visible via IFF_UP équivalent de 'ifconfig') mais ne pas être physiquement connecté...
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "Adresse IP de ShipBase sur le réseau Wifi ShipHeart (mode AP) = %s [IFF_RUNNING=%s]", reseaux.wifi.ap.adresse_ip, ((address->ifa_flags & IFF_RUNNING) == 0 ? "Non" : "Oui") );
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
/*
printf("%s\t", address->ifa_name);
printf("%s\t", family == AF_INET ? "IPv4" : "IPv6");
getnameinfo(address->ifa_addr, family_size, chaine_ip, TAILLE_ADRESSE_IP_V4, 0, 0, NI_NUMERICHOST);
printf("\t%s\n", chaine_ip);*/
}
address = address->ifa_next;
}
freeifaddrs(addresses);
return 0;
}