1 line
16 KiB
C
1 line
16 KiB
C
// **********************************************************************************************************************************************************************************
|
|
// Fichier DEBUG.C
|
|
//
|
|
// Contient toutes les fonctions de debug et de logs.
|
|
// **********************************************************************************************************************************************************************************
|
|
|
|
// Include :
|
|
#include "main.h"
|
|
|
|
// Prototypes :
|
|
void clrscr(void);
|
|
void affichage_debug_bus(uint8_t bus, char * sens, char *commande, uint8_t output);
|
|
void affichage_debug(char *fichier, int ligne, char *message, char type);
|
|
void affichage_debug_creation_ligne(char * chaine, char *fichier, int ligne, char *message, char type);
|
|
int8_t init_affichage_debug(void);
|
|
void append_chaine_fichier(char * chaine, char * fichier);
|
|
char * nom_type_carte(uint8_t type);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Variables globales :
|
|
struct Struct_debug debug; // Valeurs récupérées au démarrage dans la champs 'Mode_debug' de la table TB_Configuation dans la BDD.
|
|
|
|
|
|
//**********************************************************************************************************************************************************************************
|
|
// Fonction CLRSCR
|
|
//
|
|
// Efface l'écran en mode console
|
|
//**********************************************************************************************************************************************************************************
|
|
void clrscr(void)
|
|
{
|
|
printf("\033[H\033[2J"); //Clear Screen cf page http://pub.phyks.me/sdz/sdz/des-couleurs-dans-la-console-linux.html
|
|
}
|
|
|
|
|
|
// *****************************************************************************************************************************************************************
|
|
// Fonction : Créé une chaine formattée avec la commande reçue. L'affichage se fait soit sur rien selon la valeur 'output' (0=rien, 1=que écran, 2=que fichier, 3=les deux).
|
|
// Reçoit : Le type de bus (cf 'debug.h' pour la liste), une chaine indiquant le sens de l'échange (par exemple : "Tx" ou "Tx-Down"), la commande et le type d'output.
|
|
// Renvoit : Rien
|
|
// ******************************************************************************************************************************************************************
|
|
void affichage_debug_bus(uint8_t bus, char * sens, char *commande, uint8_t output)
|
|
{
|
|
char chaine[MAX_LONGUEUR_LIGNE_FICHIER_LOG];
|
|
char date_formatee[MAX_LONGUEUR_DATE_COURANTE];
|
|
char nom_bus[30];
|
|
char prefixe_couleur[20] = "";
|
|
char suffixe_couleur[20] = "";
|
|
char prefixe_commande[10] = "";
|
|
|
|
if (output == 0) return;
|
|
|
|
// Préparation de la chaine de date :
|
|
date_courante(date_formatee, DATE_COURANTE_AVEC_MS, FORMAT_DATE_COURANTE_USER);
|
|
|
|
// Préparation du nom de bus :
|
|
switch(bus)
|
|
{
|
|
case TYPE_BUS_DEBUG_C_BUS :
|
|
{
|
|
strcpy(nom_bus, "C-Bus");
|
|
if (strstr(sens, "Up") != NULL) strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_CYAN);
|
|
else strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_BLUE);
|
|
if (strstr(sens, "Rx") != NULL) strcpy(prefixe_commande, "<\t\t");
|
|
else strcpy(prefixe_commande, ">\t");
|
|
break;
|
|
}
|
|
case TYPE_BUS_DEBUG_M_BUS :
|
|
{
|
|
strcpy(nom_bus, "M-Bus");
|
|
if (strstr(sens, "Rx") != NULL)
|
|
{
|
|
strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_CYAN);
|
|
strcpy(prefixe_commande, "<\t\t");
|
|
}
|
|
else
|
|
{
|
|
strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_PURPLE);
|
|
strcpy(prefixe_commande, ">\t");
|
|
}
|
|
strcpy(suffixe_couleur, DEBUG_TEXT_COLOR_RESET);
|
|
break;
|
|
}
|
|
default :
|
|
{
|
|
strcpy(nom_bus, "Unknown");
|
|
strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_RED);
|
|
strcpy(suffixe_couleur, DEBUG_TEXT_COLOR_RESET);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Génération de la chaine complète pour l'écran :
|
|
if ((output == AFFICHAGE_DEBUG_ECRAN) || (output == AFFICHAGE_DEBUG_ECRAN_ET_FICHIER)) printf("[%s] [%5s] %s %s%s %s \n", date_formatee, nom_bus, prefixe_couleur, prefixe_commande, commande, suffixe_couleur);
|
|
|
|
// Génération de la chaine complète pour le fichier :
|
|
if ((output == AFFICHAGE_DEBUG_FICHIER) || (output == AFFICHAGE_DEBUG_ECRAN_ET_FICHIER))
|
|
{
|
|
sprintf(chaine, "[%s] [%5s] %s%s", date_formatee, nom_bus, prefixe_commande, commande);
|
|
append_chaine_fichier(chaine, NOM_FICHIER_DEBUG_BUS);
|
|
}
|
|
}
|
|
|
|
|
|
// *****************************************************************************************************************************************************************
|
|
// Fonction : Envoi le message de debug reçu vers l'écran et/ou le fichier de log après l'avoir formaté et horodaté.
|
|
// Reçoit : Le fichier d'origine de la demande, la ligne où la demande a été faite dans ce fichier, le contenu du message à afficher et le type (donc sa couleur à l'écran).
|
|
// Renvoit : Rien
|
|
// ******************************************************************************************************************************************************************
|
|
void affichage_debug(char *fichier, int ligne, char *message, char type)
|
|
{
|
|
char chaine[MAX_LONGUEUR_LIGNE_FICHIER_LOG];
|
|
|
|
|
|
if (debug.mode == AFFICHAGE_DEBUG_AUCUN) return;
|
|
|
|
// Affichage écran :
|
|
if ((debug.mode == AFFICHAGE_DEBUG_ECRAN) ||
|
|
(debug.mode == AFFICHAGE_DEBUG_ECRAN_ET_FICHIER))
|
|
{
|
|
affichage_debug_creation_ligne(chaine, fichier, ligne, message, type);
|
|
printf("%s \n", chaine);
|
|
}
|
|
|
|
// Affichage fichier :
|
|
if ((debug.mode == AFFICHAGE_DEBUG_ECRAN_ET_FICHIER) ||
|
|
(debug.mode == AFFICHAGE_DEBUG_FICHIER))
|
|
{
|
|
affichage_debug_creation_ligne(chaine, fichier, ligne, message, TYPE_MESSAGE_DEBUG_FICHIER_SEULEMENT);
|
|
append_chaine_fichier(chaine, debug.nom_fichier);
|
|
}
|
|
}
|
|
|
|
|
|
// *****************************************************************************************************************************************************************
|
|
// Fonction : Renvoit la ligne de debug formatée sous la forme '[JJ/MM/AAAA HH:mm:ss.mmm][<nom_de_fichier> : <no_de_ligne>] <message>'. De plus, la partie
|
|
// du <message> est colorée en fonction du 'type' de message si l'affichage est destiné à l'écran.
|
|
// Reçoit : Le pointeur sur la chaine à créer, le fichier d'origine de la demande, la ligne dans el fichier où la demande a été faite, le message et le type de message.
|
|
// Renvoit : Rien
|
|
// ******************************************************************************************************************************************************************
|
|
void affichage_debug_creation_ligne(char * chaine, char *fichier, int ligne, char *message, char type)
|
|
{
|
|
char date_formatee[MAX_LONGUEUR_DATE_COURANTE];
|
|
char *fichier_court = "";
|
|
char prefixe_couleur[20];
|
|
char suffixe_couleur[20];
|
|
|
|
// Préparation de la chaine de date :
|
|
date_courante(date_formatee, DATE_COURANTE_AVEC_MS, FORMAT_DATE_COURANTE_USER);
|
|
|
|
// Calcul du préfixe et du suffixe de couleur à utiliser pour l'écran en fonction du type de message :
|
|
switch(type)
|
|
{
|
|
case TYPE_MESSAGE_DEBUG_OK: { strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_GREEN); strcpy(suffixe_couleur, DEBUG_TEXT_COLOR_RESET); break; }
|
|
case TYPE_MESSAGE_DEBUG_WARNING: { strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_YELLOW); strcpy(suffixe_couleur, DEBUG_TEXT_COLOR_RESET); break; }
|
|
case TYPE_MESSAGE_DEBUG_ERREUR: { strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_RED); strcpy(suffixe_couleur, DEBUG_TEXT_COLOR_RESET); break; }
|
|
case TYPE_MESSAGE_DEBUG_DEBUG: { strcpy(prefixe_couleur, DEBUG_TEXT_COLOR_PURPLE); strcpy(suffixe_couleur, DEBUG_TEXT_COLOR_RESET); break; }
|
|
case TYPE_MESSAGE_DEBUG_PAR_DEFAUT:
|
|
case TYPE_MESSAGE_DEBUG_FICHIER_SEULEMENT:
|
|
default: { strcpy(prefixe_couleur, ""); strcpy(suffixe_couleur, ""); break; } // Couleur de police par défaut
|
|
}
|
|
|
|
if (fichier[0] != 0) // Si le nom de fichier est vide, on n'affichera pas l'entête de ligne...
|
|
{
|
|
// Préparation du nom de fichier :
|
|
fichier_court = strrchr (fichier, '/'); // Positionne le pointeur 'fichier_court' sur la première occurence de '\' en partant de la fin de la chaine 'fichier'.
|
|
if (fichier_court == NULL) fichier_court = fichier;
|
|
else fichier_court ++; // Le '+1' permet d'éliminer le '/' de début de chaine...
|
|
}
|
|
|
|
// Génération de la chaine complète :
|
|
sprintf(chaine, "[%s] [%15s : %4i] %s %s %s", date_formatee, fichier_court, ligne, prefixe_couleur, message, suffixe_couleur);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************************************************************************************************************************
|
|
Fonction INIT_AFFICHAGE_DEBUG
|
|
|
|
En fonction de la l'état de la variable "debug", affiche ou non les messages qui lui sont adressés
|
|
**********************************************************************************************************************************************************************************/
|
|
int8_t init_affichage_debug(void)
|
|
{
|
|
char date_formatee[MAX_LONGUEUR_DATE_COURANTE];
|
|
uint32_t no_ligne;
|
|
uint32_t nb_lignes;
|
|
FILE * ptr_fichier_tmp;
|
|
char ligne[MAX_LONGUEUR_LIGNE_FICHIER_LOG];
|
|
|
|
|
|
switch (debug.mode) // NB : la valeur de 'debug' est évaluée à l'initialisation en fonction du champs 'Mode_debug' de TB_Configuration.
|
|
{
|
|
// ******************************************************************************************************
|
|
case AFFICHAGE_DEBUG_AUCUN: // Ni sortie sur écran ni sortie sur fichier.
|
|
{
|
|
break;
|
|
}
|
|
|
|
// ******************************************************************************************************
|
|
case AFFICHAGE_DEBUG_ECRAN: // Sortie sur écran mais pas sur fichier.
|
|
case AFFICHAGE_DEBUG_ECRAN_ET_FICHIER: // Sortie sur écran et sur fichier :
|
|
{
|
|
clrscr(); // Effacement de l'écran
|
|
printf("\n----------------- Début d'initialisation --------------------\n\n");
|
|
|
|
if (debug.mode == AFFICHAGE_DEBUG_ECRAN) break; // Dans ce cas, on n'effectue pas la partie Fichier ci-dessous...
|
|
}
|
|
|
|
// ******************************************************************************************************
|
|
case AFFICHAGE_DEBUG_FICHIER: // Sortie sur fichier mais pas sur écran :
|
|
{
|
|
// Purge du fichier :
|
|
|
|
debug.ptr_fichier = fopen(debug.nom_fichier, "a+"); // Ouverture fichier de log en mode "append et lecture" qui permet, s'il n'existe pas, qu'il soit créé (sinon, avec "r", il n'est pas créé tout seul)
|
|
if (debug.ptr_fichier == NULL)
|
|
{
|
|
printf("Ouverture du fichier %s impossible. L'initialisation est arrêtée !\n", debug.nom_fichier);
|
|
exit(0); // NB : le 'return(-1)' ne semble pas fonctionner. Comme on est sur des cas de démarrage, je n'ai pas cherché plus loin...
|
|
break;
|
|
}
|
|
|
|
// Recherche du nombre de lignes du fichier :
|
|
nb_lignes = 0;
|
|
|
|
if (debug.ptr_fichier != NULL)
|
|
{
|
|
rewind(debug.ptr_fichier); // Retour au début du fichier de logs puisque l'ouverture en 'append' nous a amené à la fin...
|
|
while (fgets(ligne, MAX_LONGUEUR_LIGNE_FICHIER_LOG, debug.ptr_fichier) != NULL) nb_lignes ++;
|
|
}
|
|
// Si NULL, on considère que le fichier est nouveau et le test suivant sera négatif (nb_lignes = 0)...
|
|
|
|
|
|
// Vérification si besoin de purger le fichier :
|
|
if (nb_lignes > MAX_NOMBRE_LIGNES_FICHIER_LOG)
|
|
{
|
|
no_ligne = 0;
|
|
rewind(debug.ptr_fichier); // Retour au début du fichier de logs puisque le comptage nous a amené à la fin...
|
|
|
|
// Lecture du fichier jusqu'à MAX_NOMBRE_LIGNES_FICHIER_LOG avant la fin :
|
|
while (fgets(ligne, MAX_LONGUEUR_LIGNE_FICHIER_LOG, debug.ptr_fichier) != NULL) // Lecture d'une ligne
|
|
{
|
|
no_ligne ++;
|
|
if (no_ligne == (nb_lignes - MAX_NOMBRE_LIGNES_FICHIER_LOG)) break;
|
|
}
|
|
|
|
ptr_fichier_tmp = fopen(NOM_FICHIER_DEBUG_TMP, "w"); // Ouverture fichier de log temporaire en mode "overwrite"...
|
|
|
|
if (ptr_fichier_tmp != NULL)
|
|
{
|
|
|
|
|
|
// Réécriture complète du fichier en ne gardant que le nombre de lignes souhaité (en supprimant les premières) :
|
|
date_courante(date_formatee, DATE_COURANTE_SANS_MS, FORMAT_DATE_COURANTE_USER);
|
|
fprintf(ptr_fichier_tmp, "#### Fichier de log tronqué le %s (nombre de lignes ramené de %i à %i) #### \n\n", date_formatee, nb_lignes, MAX_NOMBRE_LIGNES_FICHIER_LOG);
|
|
|
|
// Lecture de la fin du fichier :
|
|
while (fgets(ligne, MAX_LONGUEUR_LIGNE_FICHIER_LOG, debug.ptr_fichier) != NULL) // Lecture d'une ligne
|
|
{
|
|
fputs(ligne, ptr_fichier_tmp);
|
|
}
|
|
|
|
fclose(ptr_fichier_tmp);
|
|
fclose(debug.ptr_fichier);
|
|
|
|
|
|
// Copie du fichier temporaire dans le fichier de logs :
|
|
debug.ptr_fichier = fopen(debug.nom_fichier, "w"); // Ouverture fichier de log en mode "overwrite"...
|
|
ptr_fichier_tmp = fopen(NOM_FICHIER_DEBUG_TMP, "r"); // Ouverture fichier de log temporaire en mode "read"...
|
|
while (fgets(ligne, MAX_LONGUEUR_LIGNE_FICHIER_LOG, ptr_fichier_tmp) != NULL) // Lecture d'une ligne
|
|
{
|
|
fputs(ligne, debug.ptr_fichier); // Copie de la ligne
|
|
}
|
|
fclose(ptr_fichier_tmp); // Fermeture du fichier temporaire de logs
|
|
fclose(debug.ptr_fichier); // Fermeture du fichier de logs
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
// Message d'erreur 'brut' car le mode débug n'est pas encore activé :
|
|
printf("\033[31m"); // Police en rouge...
|
|
printf("ERREUR d'ouverture du fichier temporaire [%s]....!", NOM_FICHIER_DEBUG_TMP);
|
|
printf("\033[0m \n"); // Police par défaut et retour à la ligne...
|
|
return(-1);
|
|
}
|
|
}
|
|
else fclose(debug.ptr_fichier);
|
|
|
|
|
|
// Ecriture de la ligne d'inititalisation :
|
|
debug.ptr_fichier = fopen(debug.nom_fichier, "a"); // Ouverture fichier de log en mode "append"...
|
|
if (debug.ptr_fichier == NULL)
|
|
{
|
|
// Message d'erreur 'brut' car le mode débug n'est pas encore activé :
|
|
printf("\033[31m"); // Police en rouge...
|
|
printf("ERREUR d'ouverture du fichier de Logs [%s]....!", debug.nom_fichier);
|
|
printf("\033[0m \n"); // Police par défaut et retour à la ligne...
|
|
return(-1);
|
|
}
|
|
fprintf(debug.ptr_fichier, "\n----------------- Début d'initialisation --------------------\n\n") ;
|
|
fclose(debug.ptr_fichier);
|
|
|
|
if (nb_lignes > MAX_NOMBRE_LIGNES_FICHIER_LOG) sprintf(ligne, "Purge du fichier de log effectuée. Fichier ramené de %i à %i lignes", nb_lignes, MAX_NOMBRE_LIGNES_FICHIER_LOG);
|
|
else sprintf(ligne, "Fichier de log ouvert [%s]. Contient actuellement %i lignes (max = %i)", debug.nom_fichier, nb_lignes, MAX_NOMBRE_LIGNES_FICHIER_LOG);
|
|
affichage_debug(__FILE__, __LINE__, ligne, TYPE_MESSAGE_DEBUG_OK);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Vidage du fichier de log de bus :
|
|
ptr_fichier_tmp = fopen(NOM_FICHIER_DEBUG_BUS, "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_tmp != NULL) fclose(ptr_fichier_tmp); // S'il existait, on le referme immédiatement.
|
|
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
// *****************************************************************************************************************************************************************
|
|
// Fonction : Ouvre le fichier dont le nom est passé en paramètre, ajoute à la fin la chaine reçue et referme le fichier.
|
|
// Reçoit : Le pointeur sur la chaine à ajouter et le nom du fichier de log.
|
|
// Renvoit : Rien
|
|
// ******************************************************************************************************************************************************************
|
|
void append_chaine_fichier(char * chaine, char * fichier)
|
|
{
|
|
FILE * ptr_fichier;
|
|
|
|
ptr_fichier = fopen(fichier, "a"); // Ouverture fichier de log en mode "append"...
|
|
if (ptr_fichier != NULL)
|
|
{
|
|
fprintf(ptr_fichier, "%s \n", chaine);
|
|
fclose(ptr_fichier);
|
|
}
|
|
}
|
|
|
|
|
|
// *****************************************************************************************************************************************************************
|
|
// Fonction : Retourne sous forme de chaine le type de carte passé en paramètre
|
|
// Reçoit : Le type de carte (sous forme d'entier, selon les valeurs dans 'systeme.c')
|
|
// Renvoit : Le pointeur sur la chaine de nom
|
|
// ******************************************************************************************************************************************************************
|
|
char * nom_type_carte(uint8_t type)
|
|
{
|
|
|
|
switch(type)
|
|
{
|
|
case TYPE_CARTE_SHIPBASE : { return("ShipBase"); break; }
|
|
case TYPE_CARTE_SP812 : { return("ShipPower812"); break; }
|
|
case TYPE_CARTE_SBS : { return("ShipBS"); break; }
|
|
case TYPE_CARTE_SP4AC : { return("ShipPower4AC"); break; }
|
|
case TYPE_CARTE_SP8DC : { return("ShipPower8DC"); break; }
|
|
default : { return("Inconnu..."); break; }
|
|
}
|
|
|
|
} |