Zugangsbeschränkung zu Geräten per Contactless Card mit der NodeMCU und dem RC522 Modul Teil 5 – Sicherheit. - AZ-Delivery

Bonjour et Bienvenue pour un nouveau billet de Blog pour le lecteur de Carte MiFare.

Dans l'actuel et le prochain billet de la Série, nous nous pencherons sur les Domaines de la Sécurité et de Flexibilité.

Nous voulons la Sécurité et la Flexibilité de notre Lecteur de lumière, ainsi que plus de Transparence dans les Kartenleseraktionen soucis. Un grand Manque, le précédent Parties de cette Série avaient été que, bien que le Mot de passe de connexion de l'Administrateur (admin) sur l'Interface web, de Lecteur de cartes Lecteur de cartes différence, ce Mot de passe n'est pas modifiable individuellement était.
Ce que nous voulons aujourd'hui de changer. Il est maintenant possible, sur les W

eboberfläche sous Système -> Sécurité d'une salle de Mot de passe pour l'Utilisateur "admin" à l'enregistrement.

Menu: modification du mot de passe

Ce Mot de passe peut être entre 3 et 16 Caractères.
Peut être réglé de cette définie Zeichenspanne avec les Définitions PwMinLength et PwMaxLength dans le Code. Si plus courte ou plus longue Passwortgrenzen désiré, les Valeurs peuvent être adaptés individuellement.

 

La Procédure de changement de mot de passe de l'Utilisateur "admin" est:

• votre première connexion à l'Interface web à l'aide du nom d'Utilisateur "admin" et le Mot de passe composé de l'ESP ChipId. (Comme dans les Parties précédentes de la Série décrit précédemment)
• Navigation sous-Système -> Sécurité, puis 2x la même chose (nouveau) Mot de passe et Bouton ... appuyez sur.
• Déconnexion du Système> Déconnexion. Le nouveau Mot de passe est immédiatement valable.

Nous avons donc la Sécurité, ou au contraire augmente, de sorte que quelqu'un de notre Projet connaît et Accès à l'Interface série et sur le Réseau a, pas le valide mot de passe de connexion à comprendre.
Nous arrivons maintenant à un autre Point de la Rubrick de la Sécurité: Il serait de Sicherheitssicht souhaitable de savoir par qui, quand et avec quelle Carte nos Lecteur de cartes correctement ou n'est pas correctement utilisé. Pour ce faire, nous créons maintenant la Possibilité. Sous la nouvelle Rubrique "Journal des événements", nous voyons maintenant les différentes Entrées pour certains d'Actions ou d'Événements autour de nos Lecteurs.
Par exemple, nous voyons maintenant, dans le Journal des événements, toutes les Tentatives en cours de validité et carte non valide nos Lecteurs à une Action pour se déplacer.

La Capture d'écran suivante illustre cela de façon exemplaire:

Journal des événements

 

Comme dans l'o. g la Capture d'écran est la Collection de l'Heure et de la Date, ni générique à un prix fixe de Valeur, puisque nous une source d'heure valide manquant. Cette Source, nous sommes dans l'une des prochaines Parties pour ajouter.
Essentiel pour le Journal d'événements de l'Initialisation correcte et d'une Utilisation interne, programme de stabilité électronique SPIFFS Filesystems. Pour cela, nous les Kompilieroptionen pour un de nos disponibles 4 MO de mémoire de programme 2 MO SPIFFS système de Fichiers sont formatés. Comment ce passe, j'ai déjà parlé dans un autre billet de Blog "ESP8266 – Tout SPIFFS ou quoi?" de moi à l'Établissement.

Important: Sans le bon SPIFFS Paramètre, le Code est bien compilé et sur le programme de stabilité électronique téléchargé, mais reste au Démarrage de l'ESP avec le Message "ATF:NOK" sur l'Interface série "accrocher" et les autres Initalisierung échoue. Cette SPIFFS devons-nous pour toutes les autres Parties suivantes de cette Série est conservée.

 

Le Code de notre aujourd'hui le Blog est:

 

#include <SPI.h>
#include <MFRC522.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <EEPROM.h>
#include <FS.h>           // Include the SPIFFS library

#define RST_PIN     5     // SPI Broche Reset (D1 Sortie)
#define RELAIS_PIN  16    // Relais (D0 Sortie) [Active LOW] - Internes LED, à proximité du Port USB
#define SS_PIN      15    // Broche de sélection esclave SPI

#define RGBLED_R    2     // rouge (sortie D4) 
#define RGBLED_G    0     // Vert (sortie D3) - Également LED interne sur le module ESP
#define RGBLED_B    4     // bleu (sortie D2)

#define WiFiPwdLen 25     // Longueur maximale du mot de passe WiFi
#define STANAMELEN 20     // Longueur maximale du SSID WiFi
#define ESPHostNameLen 20 // Nombre maximum de caractères ESPHostName

#define KEYA vrai         // Définition du drapeau PICC
#define KEYB faux        // Définition du drapeau PICC

#define LED_BUILTIN 16
#define PIN_WIRE_SDA 4
#define PIN_WIRE_SCL 5

#define PwMinLength 3  // Longueur minimale du mot de passe de connexion
#define PwMaxLength 16  // Longueur maximale du mot de passe de connexion
#define LoginNameMaxLength 16  // Longueur maximale du nom de connexion

#define USED_Sector 1  // Secteur de carte utilisé pour les données d'authentification et de configuration (valide: 1 à 15)

ADC_MODE(ADC_TOUT);   // Configurez l'entrée analogique A0 sur externe. ADC_TOUT (pour tension externe), ADC_VCC (pour tension système).
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Créer une instance du MFRC522
MFRC522::MIFARE_Key clé;
ESP8266WebServer serveur(80);        // Créer une instance de serveur Web
Fichier monfichier;               // crée une variable de gestion SPIFFS
FSInfo fs_info;

struct WiFiEEPromData // Longueur d'objet de 68 octets
{   char ESPHostName[ESPHostNameLen]; // 20   char APSTAName[STANAMELEN]; // Nom du point STATION / AP TO Connect, si défini 20   char WiFiPwd[WiFiPwdLen]; // WiFiPAssword, si défini 25   char ConfigValid[3]; // Si la configuration est Vaild, le tag "TK" est requis "3
};

struct MiFareClassicKeyTable
{   octet Key_A[6] = {0x22, 0x44, 0xFA, 0xAB, 0x90, 0x11}; // Veuillez changer la clé de la carte PICC.   octet Key_B[6] = {0xFE, 0xE1, 0xAA, 0x3D, 0xDF, 0x37}; // Veuillez changer la clé de la carte PICC.   char ConfigValid[3]; // Si Config est Vaild, le tag "TK" est requis "
};

struct SysConf //
{   char LoginName[LoginNameMaxLength]; // 16   char LoginPassword[PwMaxLength];  // 16   bool PCD_Disabled; // 1   octet USED_PICC_Sector; // 1   char ConfigValid[3]; // Si Config est Vaild, le tag "TK" est requis "// 3
};




MiFareClassicKeyTable MiFareClassicKey;
WiFiEEPromData MyWiFiConfig;
SysConf SystemConfiguration;


// Variables utilisées mondialement
bool Résultat  = faux;
bool LearnNewCard = faux;
bool EraseCard = faux;
bool ExpirationDateActive = faux;
bool PCD_Disabled = faux;
String Nom de famille;
String Givenname;
String ExpirationDate;
String temp;
non signé longue SessionID;
non signé longue PCD_ServiceCall_Handler = 0;
non signé longue PCD_WatchDog_Handler = 0;
uint8_t DataBuffer[18]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };


nul configuration()
{   pinMode(RST_PIN, SORTIE);   digitalWrite(RST_PIN, ÉLEVÉ);   pinMode(RELAIS_PIN, SORTIE);   pinMode(RGBLED_R, SORTIE);   pinMode(RGBLED_G, SORTIE);   pinMode(RGBLED_B, SORTIE);   digitalWrite(RELAIS_PIN, ÉLEVÉ);   // relais inactif   SetRGBLed(255, 0, 255, faux);    // La couleur LED pourpre commence l'initialisation   Série.commencer(115200);               // Initialise la communication série avec le PC avec 115200 bauds   Série.println(F(" "));   temp = "ATSN:" + String(ESP.getChipId());   Série.println(temp);   // Serial.print ("Valeur ADC:"); Serial.println (analogRead (A0));   SPI.commencer();                      // Initialiser la communication SPI   PCDHardReset();   SessionID = millis();   Résultat = loadSysConfig();   Résultat = InitalizeFileSystem();   Résultat = startWiFiClient();   InitalizeHTTPServer();   temp = "Démarrage du système:";   temp += String(ESP.getResetReason());   WriteToLog(temp, 0);   temp = "";   ESP.wdtEnable(4000);             // Démarrer le chien de garde   SetRGBLed(0, 0, 255, faux);    // L'initialisation de la couleur bleue de la LED est terminée
}


// ******************* Démarrer les fonctions d'aide / d'optimisation ************************ ********

nul SetRGBLed(octet RedValue, octet GreenValue, octet BlueValue, booléen SlowFade) // Fonction de contrôle de la led RGB
{   digitalWrite(RGBLED_R, LOW);   digitalWrite(RGBLED_G, LOW);   digitalWrite(RGBLED_B, LOW);   if (RedValue == 255)   {     digitalWrite(RGBLED_R, HIGH);   }   if (GreenValue == 255) {     digitalWrite(RGBLED_G, HIGH);   }   if (BlueValue == 255)  {     digitalWrite(RGBLED_B, HIGH);   }
}

// ******************* Stop Helper/ Optimisation de Fonctions *********************************

// ******************* Démarrer Functions Serveur web *******************************************

//le Cookie Basisroutinen sont basés sur GIT est un Extrait:
//https://github.com/esp8266/ESPWebServer/blob/master/examples/SimpleAuthentification/SimpleAuthentification.ino
bool is_authentified()
{   if (serveur.hasHeader("Cookie")) {     // Cookie trouvé     temp = serveur.header("Cookie");     //Serial.println(temp);     String SessionStr = String(ESP.getChipId()) + "=" + String(Idsession);     rendement();     si (temp.indexOf(SessionStr) != -1) {       // Web de l'Authentification erfolgreich       temp = "";       de retour true;     }   }   // Web de l'Authentification fehlgeschlagen   temp = "";   SessionID = millis();   retour de faux;
}

vide handleLogin() {   String msg;   //Chaîne de cookie = server.l'en-tête("Cookie");   //Serial.println(cookie);   si (le serveur.hasArg("DÉCONNECTER")) {     //Déconnexion de Benutzers;     SessionID = millis();     temp = Chaîne(ESP.getChipId()) + "= NA ; HttpOnly ; SameSite=Stricte";     serveur.sendHeader("Set-Cookie", temp);     temp = "Abmeldung von Webinterface.";     WriteToLog(temp, 0);     temp = "";     PCD_Disabled = false; // PCD aktivieren nach déconnexion ;     SetRGBLed(0, 0, 255, false);    //Led Farbe Blau StandardModre     serveur.sendHeader("Emplacement", "/login");     serveur.sendHeader("Cache-Control", "no-cache");     serveur d'.envoyer(301);     serveur.envoyer(301);     //yield();   }   si (le serveur.hasArg("nom d'utilisateur") && serveur.hasArg("MOT de passe")) {     temp = Chaîne(ESP.getChipId());     si (le serveur.arg("nom d'utilisateur") == SystemConfiguration.LoginName &&  serveur.arg("MOT de passe") == SystemConfiguration.LoginPassword ) {       serveur.sendHeader("Emplacement", "/");       serveur.sendHeader("Cache-Control", "no-cache");       SessionID = millis();       temp = Chaîne(ESP.getChipId()) + "=" + Chaîne(SessionID) + "; HttpOnly ; SameSite=Stricte";       serveur.sendHeader("Set-Cookie", temp);       temp = ""Anmeldung von " + serveur.arg("nom d'utilisateur") + " un Webinterface.";       WriteToLog(temp, 0);       temp = "";       serveur.envoyer(301);       PCD_Disabled = vrai; // PCD deaktivieren, solange Par Web gearbeitet wird;       SetRGBLed(255, 0, 255, false);    //Led Couleur Lila dans Servicemode       retour;     }     msg = "<script>alert('Falscher Benutzername oder falsches mot de passe !');</script>";     temp = "Fehlerhafter Anmeldeversuch von " + serveur.arg("nom d'utilisateur") + " un Webinterface. Mot de passe: " + serveur.arg("MOT de passe") ;     WriteToLog(temp, 1);     temp = "";   }   CSS_Header_Template();   temp = "<head><title>Login</title></head><body><DIV ALIGN=CENTER>";   serveur.sendContent(temp);   temp = "<h2> " Anmeldung un Kartenleser RC522</h2><corps><br><br><table border=0 bgcolor=black><tr><th><DIV ALIGN=RIGHT>";   serveur.sendContent(temp);   temp = "<form action='/login' method='post'>Benutzername: <input type=text Name='nom d'utilisateur' Size=17 required><br>";   serveur.sendContent(temp);   temp = "mot de passe: <input type=password Name= "PASSWORD" Size=17 required><br><br><br><button type= "submit"";   serveur.sendContent(temp);   temp = "nom='Login_Button' value='1' style='height: 30px; width: 100px' >Login</bouton><br></th></tr></form></DIV></table>";   serveur.sendContent(temp);   temp = "<br><SMALL>Damit die " Anmeldung funktioniert, sind Cookies für diese Webseite zu erlauben.</SMALL>";   serveur.sendContent(temp);   temp = msg + "</DIV></body></HTML>";   serveur.sendContent(temp);   temp = "";
}

vide handleNotFound()
{   SessionID = millis();   temp = "Page nicht gefunden.\n\n";   temp += "URI: ";   temp += serveur.uri();   temp += "\nMethod: ";   temp += (serveur.méthode() == HTTP_GET) ? "GET", : "POST";   temp += "\nArguments: ";   temp += serveur.args();   temp += "\n";   pour (u_int8_t je = 0; je < serveur.args(); je++) {     temp += " " + serveur.argName(je) + ": " + serveur.arg(i) + "\n";   }   rendement();   serveur.envoyer(404, "text/plain", temp);   temp = "Aufruf der ungültigen URL: " + serveur.uri() + " Paramètre: " + Chaîne de(serveur.args()) ;   WriteToLog(temp, 2);   temp = "";
}



vide handleErasePICC()
{   si (!is_authentified())   {     serveur.sendHeader("Emplacement", "/login");     serveur.sendHeader("Cache-Control", "no-cache");     serveur d'.envoyer(301);     le rendement();     de retour;   }   CSS_Header_Template();   rendement();   temp = "<head><title>Kartenleser RC522</title></head><body>";   serveur.sendContent(temp);   HtmlNavStructure();   temp = "<script>alert('Bitte JETZT die zu löschende Karte vor den Leser halten!');</script>";   serveur.sendContent(temp);   rendement();   EraseCard = vrai;   PCD_Disabled = faux;   SetRGBLed(0, 255, 255, false);    //Led Couleur cyan Programmierungsmodus   temp = "</body></html>";   serveur.sendContent(temp);   serveur.client().arrêter();   temp = "";
}

vide handleSettings()
{   si (!is_authentified())   {     serveur.sendHeader("Emplacement", "/login");     serveur.sendHeader("Cache-Control", "no-cache");     serveur d'.envoyer(301);     retour;   }   CSS_Header_Template();   temp = "<head><title>Kartenleser RC522</title></head><body>";   serveur.sendContent(temp);   HtmlNavStructure();   temp = "<br><br><br><div align=center><form method='post' action='/paramètres' method='post'>";   serveur.sendContent(temp);   temp = "<p><label>Neues Anmeldepasswort</label><br / > <input type='mot de passe' nom= "newPassword'>";   serveur.sendContent(temp);   temp = "</p><p><label>Wiederholung Anmeldepasswort</label><br / > <input type= "password" name='confirmNewPassword'><br><br><br>";   serveur.sendContent(temp);   temp = "<button type='submit' name='Enregistrer' value='1' style='height: 30px; width: 200px' >Speichern</bouton></p></form></div>";   serveur.sendContent(temp);   // temp = "</p><p><button type='submit' name='save'>Speichern</bouton></p></form></div></body></html>";   si (le serveur.hasArg("Enregistrer"))   {     si (serveur.arg("confirmNewPassword") == serveur.arg("newPassword"))     {       temp = serveur.arg("newPassword");       si ((temp.longueur() < PwMinLength ) |  (temp.longueur() > PwMaxLength ))       {         temp = "<br><div align=center><br>Das Kennwort muss zwischen minimum ";         serveur.sendContent(temp);         temp = Chaîne(PwMinLength) + " und maximale " + Chaîne(PwMaxLength) + " Zeichen lang sein.</div>";         serveur.sendContent(temp);       } d'autre       {         temp = serveur.arg("newPassword");         temp.toCharArray(SystemConfiguration.LoginPassword , PwMaxLength);         saveSysConfig();         temp = "Das Anmeldekennwort von Benutzer " + Chaîne(SystemConfiguration.LoginName) + " wurde geändert.";         WriteToLog(temp, 0);         temp = "<script>alert ("Das Anmeldekennwort wurde erfolgreich geändert.');</script>";         serveur.sendContent(temp);       }     } d'autre     {       temp = "<br><div align=center><br>Die eingegebenen Kennwörter stimmen nicht überein. Bitte nochmals eingeben.</div>";       serveur.sendContent(temp);     }   }   temp = "</body></html>";   serveur.sendContent(temp);   serveur.client().arrêter();   temp = "";
}

vide handleNewPICC()
{   si (!is_authentified())   {     serveur.sendHeader("Emplacement", "/login");     serveur.sendHeader("Cache-Control", "no-cache");     serveur d'.envoyer(301);     de retour;   }   si (serveur.hasArg("Nom de famille") && serveur.hasArg("Givenname"))   {     Nom = du serveur.arg("Nom de famille");     Givenname = serveur.arg("Givenname");     ExpirationDate = serveur.arg("ExpDate");     si (serveur.hasArg("ExpDateOption")) {       ExpirationDateActive = vrai;     } d'autre {       ExpirationDateActive = faux;     }     temp = "Erstellung einer neuen Karte für: " + serveur.arg("Givenname") + ", " + serveur.arg("Nom de famille");     WriteToLog(temp, 0);     PCD_Disabled = faux;     LearnNewCard = vrai;     CSS_Header_Template();     temp = "<head><title>Kartenleser RC522</title></head><body>";     serveur.sendContent(temp);     HtmlNavStructure();     temp = "<script>alert('Bitte JETZT die neue Karte vor den Leser halten!');</script>";     serveur.sendContent(temp);     temp = "</body></html>";     serveur.sendContent(temp);     serveur.client().arrêter();     SetRGBLed(255, 255, 0, false);    //Led Couleur Gelb Programmierungsmodus     rendement();     de retour;   }   CSS_Header_Template();   temp = "<head><title>Kartenleser RC522</title></head><body>";   serveur.sendContent(temp);   HtmlNavStructure();   temp = "";   temp = "<br><br><br><br><table border=0 ALIGN=CENTER><th>";   serveur.sendContent(temp);   temp = "<table border=1 bgcolor = black><form action='/newPICC' method='post'>";   serveur.sendContent(temp);   temp = "<tr><th>Karteninhaber:<br><div ALIGN=RIGHT>";   serveur.sendContent(temp);   temp = "Vorname: <input type=text Name='Nom' Size=17 maxlenght=16 espace réservé='Max' required><br>";   serveur.sendContent(temp);   temp = "Nachname: <input type=text Name='Prénom' Size=17 maxlenght=16 placeholder='Smith' required><br>";   serveur.sendContent(temp);   temp = "</div></th><th>Kartenmetadaten:<br / ><DIV ALIGN=RIGHT>";   serveur.sendContent(temp);   temp = "<input Name='ExpDateOption' TYPE=checkbox VALUE=1 >Ablaufdatum:<input type= "date" Name='ExpDate' Size = 17 >";   serveur.sendContent(temp);   temp = "<br><th><tr><th></table><br>";   serveur.sendContent(temp);   temp = "<button type='submit' name='NewCard' value='1' style='height: 30px; width: 200px' >Neue carte à puce erstellen</bouton>";   serveur.sendContent(temp);   temp = "<br / ></form></tr></th></table>";   serveur.sendContent(temp);   temp = "</body></html>";   serveur.sendContent(temp);   serveur.client().arrêter();   temp = "";
}


vide handleLog()
{   int Taille =  0;   si (!is_authentified())   {     serveur.sendHeader("Emplacement", "/login");     serveur.sendHeader("Cache-Control", "no-cache");     serveur d'.envoyer(301);     de retour;   }   si (serveur.hasArg("ClearLog"))   {     si (SPIFFS.existe ("/usage_log.csv") )  //Prüfe ob Datei usage_log.csv exisiert.     {       SPIFFS.supprimer("/usage_log.csv");  //Lösche Datei       Série.println(F("ATF:LogDelete"));       temp = "Ereignisprotokollierungsdatei soient supprimés.";       WriteToLog(temp, 0);       temp = "";     } d'autre {       Série.println(F("ATF:LogDelete_ERR"));     }     rendement();   }   CSS_Header_Template();   rendement();   temp = "<head><title>Kartenleser RC522</title></head><body>";   serveur.sendContent(temp);   HtmlNavStructure();   temp = "<br><br><br><br><table border=4 ALIGN=CENTER><th>";   serveur.sendContent(temp);   temp = "<textarea rows='20' cols='110' warp=doux readonly>";   serveur.sendContent(temp);   si (SPIFFS.existe ("/usage_log.csv"))  //Prüfe ob Datei usage_log.csv exisiert.   {     myfile = SPIFFS.ouvrir("/usage_log.csv",, "r");  //Öffne die Datei usage_log.csv im Racine Verzeichnis zum lesen     si (!myfile)     {       temp = "Interner Fehler: Logdatei usage_log.csv konnte nicht geöffnet werden !";       serveur.sendContent(temp);     } d'autre     {       de la Taille du fichier = myfile.taille();       tandis que (myfile .position() < myfile.taille())       {         temp = myfile.readStringUntil('\n');         temp.garniture();         temp += "\n"; // Ajouter un Caractère de saut de Ligne         serveur.sendContent(temp);       }       myfile.proche();     }   } d'autre   {     temp = "Interner Fehler: Logdatei usage_log.csv nicht gefunden !";     serveur.sendContent(temp);   }   temp = "</textarea></th></table><table border=0 ALIGN=CENTER>";   serveur.sendContent(temp);   SPIFFS.info(fs_info);   temp = "<br><div ALIGN=CENTER> Loggroesse " + Chaîne de(Taille) + " Octets.<br>";   serveur.sendContent(temp);   temp = Chaîne(fs_info.usedBytes) + " Octets von " + Chaîne(fs_info.totalBytes) + " Octets belegt.</div>";   serveur.sendContent(temp);   temp = "<th><form action='/log' method='post'><br><br>";   serveur.sendContent(temp);   temp = "<button type='submit' name='RefreshLog' value='1' style='height: 30px; width: 100px' >Actualiser</bouton>";   serveur.sendContent(temp);   temp = "<button type='submit' name='ClearLog' value='1' style='height: 30px; width: 100px' >Effacer Journal</bouton>";   serveur.sendContent(temp);   temp = "</form></th></table></HTML>";   serveur.sendContent(temp);   serveur.client().arrêter();   temp = "";
}

vide handleRoot()
{   si (!is_authentified()) {     serveur.sendHeader("Emplacement", "/login");     serveur.sendHeader("Cache-Control", "no-cache");     serveur d'.envoyer(301);     de retour;   }   // Contenu HTML   CSS_Header_Template();   rendement();   temp = "<head><title>Kartenleser RC522</title></head><body>";   serveur.sendContent(temp);   HtmlNavStructure();   temp = "<div ALIGN=CENTER><br><br><br><br><BIG>Willkommen auf der Smartkartenleser RC522 Site.</BIG><br>";   serveur.sendContent(temp);   temp = "Resetgrund: " + Chaîne(ESP.getResetReason()) + "<br>";   serveur.sendContent(temp);   temp = "Freier Heapspeicher: " + Chaîne(ESP.getFreeHeap()) + " Octets<br>";   serveur.sendContent(temp);   temp = "Int. Flash: " + Chaîne(ESP.getFlashChipRealSize()) + " Octets<br>";   serveur.sendContent(temp);   Résultat = mfrc522.PCD_PerformSelfTest();   mfrc522.PCD_Init();                       // Initialisiere MFRC522 Lesemodul   mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); // Setzt Antenne auf max. Empfang   mfrc522.PCD_AntennaOn();   de rendement();   si le (Résultat) {     temp = "RC522 PCD-Statut: OK<br>";   } d'autre {     temp = "RC522 PCD-Statut: Fehler!<br>";   }   serveur.sendContent(temp);   temp = CPU ID: " + Chaîne(ESP.getChipId()) + " @ " + Chaîne(ESP.getCpuFreqMHz()) + " MHz<br>";   serveur.sendContent(temp);   temp = "<br / >Sie sind erfolgreich angemeldet !<br>";   serveur.sendContent(temp);   temp = "<br>Programmiert von <a href='mailto:tobias.kuch@googlemail.com'>Tobias Kuch</a><br></div></body></html>";   serveur.sendContent(temp);   si (serveur.hasArg("Reboot") )  // Redémarrer le Système   {     temp = "<script>alert('Das System startet JETZT neu.');</script>";     serveur.sendContent(temp);     serveur.client().arrêter();     de rendement();     temp = "";     ESP.réinitialiser le();     délai(4000);   }   de serveur de.client().arrêter();   temp = "";
}

vide CSS_Header_Template() // Formatvorlage für alle internen ESP de nos sites web. https://wiki.selfhtml.org/wiki/CSS
{   serveur.setContentLength(CONTENT_LENGTH_UNKNOWN);   temp = "";   serveur.envoyer (200, "text/html", temp);   temp = "<!DOCTYPE HTML PUBLIC "- /- //W3C//DTD HTML 4.01 Transitional//EN "><html lang= " de " ><meta charset='UTF-8'>";   serveur.sendContent(temp);   temp = "<style type='text/css'>*{margin: 0;padding: 0;}body{background:black;color:darkorchid;font-size: 16px;"; serveur.sendContent(temp); temp = "font-family: sans-serif,arial;}.nav{width: 1300px;height: 30px;margin: 0 auto;border-radius: 5px;}";   serveur.sendContent(temp);   temp = "ul li{list-style: none;width: 200px;line-height: 60px;position: relative;fond: darkorchid;"; serveur.sendContent(temp); temp = "box-shadow: 0px 2px 5px 0px gris;text-align: center;float: left;background-color: #010000;}ul li ul{";   serveur.sendContent(temp);   temp = "position: absolute;}.nav > ul > li:nth-of-type(1){border-radius: 5px 0px 0px 5px;}.nav > ul > li:nth-of-type(5)";   serveur.sendContent(temp);   temp = "{border-radius: 0px 5px 5px 0px;}ul li a{color: rgb(182, 18, 18);width: 200px;height: 58px;display: inline-block;"; serveur.sendContent(temp); temp = "text-decoration: none;}ul li a:hover{font-weight: bold;border-bottom: 2px solid #fff;}ul li ul{display: none;}";   serveur.sendContent(temp);   temp = ".nav ul li:hover ul{display: block;}.fa{margin-right: 5px;}.conteneur{width: 1000px;height: 200px;"; serveur.sendContent(temp); temp = "margin: 0 auto;padding:20px 20px;}@media screen and (max-width: 480px){header{width: 100%;}";   serveur.sendContent(temp);   temp = ".nav{display: none;width: 100%;height: auto;}ul li{width: 100%;float: none;}ul li a{width: 100%;"; serveur.sendContent(temp); temp = "display: block;}ul li ul{position: static;}ul li ul li a{background: #222;}.fa-liste.modifier{display: block;}";   serveur.sendContent(temp);   temp = ".conteneur{width: 100%;height: auto;}body{overflow-x:hidden;}}</style>";   serveur.sendContent(temp);   temp = "";
}

vide HtmlNavStructure()
{   temp = "<div class= "menu" ><nav class='nav'><ul>";   serveur.sendContent(temp);   temp = "<li><a href='#'>Système</a>";   serveur.sendContent(temp);   temp = "<ul><li><a href="/fr">d'Information</a></li>";   serveur.sendContent(temp);   temp = "<li><a href="/fr/paramètres">Sicherheit</a></li>";   serveur.sendContent(temp);   temp = "<li><a href="/fr/login?DÉBRANCHEZ=1">Abmelden</a></li>";   serveur.sendContent(temp);   temp = "<li><a href="/fr/?Reboot=YES">Neustart</a></li>";   serveur.sendContent(temp);   temp = "</ul>";   serveur.sendContent(temp);   temp = "</li><li><a href='#'>CCIP</a>";   serveur.sendContent(temp);   temp = "<ul><li><a href="/fr/newPICC">Neue Karte erstellen</a></li>";   serveur.sendContent(temp);   temp = "<li><a href="/fr/erasePICC">Karte löschen</a></li></ul>";   serveur.sendContent(temp);   temp = "</li>";   temp = "</li><li><a href="/log">Ereignisprotokoll</a></li>";   serveur.sendContent(temp);   temp = "</ul></nav></div>";   serveur.sendContent(temp);   temp = "";
}

vide InitalizeHTTPServer()
{   bool initok = faux;   const char * headerkeys[] = {"User-Agent", "Cookie"} ; //en-Tête zum Tracken   size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*); //en-Tête zum Tracken   serveur.sur("/", handleRoot);   serveur.sur("/login", handleLogin);   serveur.sur("/newPICC", handleNewPICC);   serveur.sur("/erasePICC", handleErasePICC);   serveur.sur("/"paramètres, handleSettings);   serveur.sur("/log", handleLog);   serveur.onNotFound ( handleNotFound );   serveur.collectHeaders(headerkeys, headerkeyssize );// Serveur anweisen, diese zu Tracken   serveur de.commencer(); / serveur Web/ start
}

// ******************* Fin des Fonctions de Serveur web *********************************************

// ******************* Les Fonctions De Démarrage Du Système De Fichiers ******************************************
boolean InitalizeFileSystem()
{   bool initok = faux;   initok = SPIFFS.commencer();   retard(200); // Sans retard, j'ai vu l'adresse IP vide   si (!(initok)) // Format SPIFS, de ne pas formaté. - Essayez 1   {     Série.println(F("ATF:FRM"));     SPIFFS.format();     initok = SPIFFS.commencer();   }   si (!(initok)) // Format SPIFS, de ne pas formaté. - Essayez 2   {     SPIFFS.format();     initok = SPIFFS.commencer();   }   si (initok) {     Série.println(F("ATF:OK"));   } else {     Série.println(F("ATF:NOK"));   }   retour initok;
}

boolean WriteToLog(Chaîne LogEntry, octet Logtype)
{   bool writeok = faux;   SPIFFS.info(fs_info);   si (fs_info.totalBytes - fs_info.usedBytes - 2000 > 1) // Speicherplatz überprüfen   {     myfile = SPIFFS.ouvrir("/usage_log.csv",, "a");  //Öffne die Datei usage_log.csv im Racine Verzeichnis zum schreiben     si (!myfile)     {       myfile.près();       de Série.println(F("ATF:InitLog_ERR"));       retour writeok;     }     temp = "";     temp += "01.01.1980 12:00:00 "; // noch EchtDatum hinzufügen     commutateur (Logtype)     {       cas 0:         temp += "Info: "le;         saut de;       cas 1:         temp += "service warnung: ";         casser;       cas 2:         temp += "Erreur: ";         pause;       par défaut:         temp += "Info: ";         pause;     }     temp += LogEntry;     writeok = myfile.println(temp);     si (!(writeok)) {       Série.println(F("ATF:WriteLog_ERR"));     }     myfile.près();     temp = "";   }   de retour writeok;
}


// ******************* Fin des Fonctions du système de fichiers ********************************************

// ******************* Les Fonctions De Démarrage WiFi De Gestion *************************************
// Funktion von https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/wps-mit-dem-esp8266?ls=de
bool startWPS()
{   bool wpsSuccess = WiFi.beginWPSConfig();   si (wpsSuccess) {     // Muss nicht immer erfolgreich heißen! Nach einem Délai ist die SSID leer     Chaîne newSSID = WiFi.SSID();     si (newSSID.longueur() > 0) {       // Nur wenn eine SSID gefunden wurde waren wir erfolgreich       rendement de la();       Série.println(F("ATWPS:OK"));       saveCredentials(); // Enregistrer les informations d'Identification dans la mémoire EEPROM     } d'autre {       Série.println(F("ATWPS:NOK"));     }   }   retour wpsSuccess;
}

bool startWiFiClient()
{   bool WiFiClientStarted = faux;   size_t A0_ADCValue = 0;   octet je = 0;   octet connRes = 0;   Série.setDebugOutput(false);  // Zu Debugzwecken aktivieren.   WiFi.nom d'hôte("CrdRdr41667");   WiFi.softAPdisconnect(vrai);   WiFi.déconnecter();   le WiFi.en mode(WIFI_STA);   si (loadCredentials())   {     WiFi.commencer(MyWiFiConfig.APSTAName, MyWiFiConfig.WiFiPwd);     tout (( connRes != 3 ) et ( connRes != 4 ) et (j' != 30)) //si connRes == 0 "IDLE_STATUS - changement Statius"     {       j'++;       // Serial.print(F(".")); // Connexion vorgang auf der seriellen Schnittstelle beobachten       //ESP.wdtFeed();       delay(500);       rendement();       connRes  = WiFi.waitForConnectResult();     }     si (connRes == 4 ) { // si le mot de passe est incorrect       Série.println(F("ATWIFI:PWDERR"));       WiFi.déconnecter();     }     si (connRes == 6 ) { // module n'est pas configuré en mode station       de Série.println(F("ATWIFI:STAERR"));       WiFi.déconnecter();     }   }   si (WiFi.statut() == WL_CONNECTED)   {     //ESP.wdtFeed();     Serial.print(F("de l'AIPRP:"));     Série.println(WiFi.localIP());     WiFi.setAutoReconnect(vrai); // Définir si le module va tenter de vous reconnecter à un point d'accès dans le cas où il est déconnecté.     // Le programme d'installation MDNS répondeur     si (!MDNS.commencer("CrdRdr41667"))     {       Série.println(F("ATMDNS:NOK"));     } d'autre {       MDNS.addService("http",, "tcp", 80);     }     WiFiClientStarted = vrai;   } d'autre   {     A0_ADCValue = analogRead(A0);     //Wir waren nicht erfolgreich, daher starten wir WPS, wenn WPS Dégustateur un A0 während des Réinitialise gedrückt ist     si (A0_ADCValue > 499)     {       si (startWPS())       {         //ESP.wdtFeed();         delay(500);         WiFi.déconnecter();         le WiFi.en mode(WIFI_STA);         WiFi.commencer(WiFi.SSID().c_str(), WiFi.psk().c_str());         //ESP.wdtFeed();         WiFiClientStarted = vrai;       } d'autre       {         WiFiClientStarted = faux;         WiFi.déconnecter();       }     } d'autre     {       WiFi.débrancher();     }   }   //WiFi.printDiag(de Série); // Zu Debugzwecken aktivieren.   retour WiFiClientStarted;
}
// ******************* FIN des Fonctions WiFi de Gestion *************************************

// ******************* les Fonctions de Démarrage Store WiFi informations d'Identification dans la mémoire EEPROM ******************
bool loadCredentials()
{   bool RetValue;   EEPROM.commencer(512);   EEPROM.obtenir(0, MyWiFiConfig);   EEPROM.fin();   si (la Chaîne(MyWiFiConfig.ConfigValid) == "SAVOIRS traditionnels")   {     RetValue = vrai;   } d'autre   {     RetValue = false; // Paramètres WLAN nicht gefunden.   }   //ESP.wdtFeed();   retour RetValue;
}

vide saveCredentials() // Speichere WLAN informations d'identification de l'auf EEPROM
{   size_t je;   pour (je = 0 ; je < sizeof(MyWiFiConfig) ; j'++) // Loeschen der alten Konfiguration   {     EEPROM.écrire(je, 0);   }   pour (je = 0 ; je < STANameLen  ; j'++) // Loeschen der alten Konfiguration   {     MyWiFiConfig.WiFiPwd[je] = 0;   }   pour (je = 0 ; je < WiFiPwdLen ; j'++) // Loeschen der alten Konfiguration   {     MyWiFiConfig.APSTAName[je] = 0;   }   temp = WiFi.SSID().c_str();   je = temp.longueur de();   temp.toCharArray(MyWiFiConfig.APSTAName, je + 1);   temp = WiFi.psk().c_str();   je = temp.longueur de();   temp.toCharArray(MyWiFiConfig.WiFiPwd, je + 1);   temp = "";   strncpy(MyWiFiConfig.ConfigValid , "SAVOIRS traditionnels",, sizeof(MyWiFiConfig.ConfigValid) );   EEPROM.commencer(512);   EEPROM.mettre(0, MyWiFiConfig);   EEPROM.commettre();   EEPROM.fin();   //ESP.wdtFeed();
}

void saveSysConfig()
{   octet je;   strncpy(SystemConfiguration.ConfigValid , "SAVOIRS traditionnels",, sizeof(SystemConfiguration.ConfigValid) );   EEPROM.commencer(512);   EEPROM.mettre(80, SystemConfiguration);   EEPROM.commettre();   EEPROM.fin();   //ESP.wdtFeed();

}

bool loadSysConfig()
{   bool RetValue;   EEPROM.commencer(512);   EEPROM.obtenir(80, SystemConfiguration);   EEPROM.fin();   si (la Chaîne(SystemConfiguration.ConfigValid) == "SAVOIRS traditionnels")   {     RetValue = vrai;   } d'autre   {     temp = Chaîne(ESP.getChipId());     temp.toCharArray(SystemConfiguration.LoginPassword , PwMaxLength);     temp = "";     strncpy(SystemConfiguration.LoginName , , "admin",, sizeof(SystemConfiguration.LoginName) );     SystemConfiguration.PCD_Disabled = faux;     SystemConfiguration.USED_PICC_Sector = 1;     saveSysConfig();     RetValue = false; // Paramètres de configuration de nicht gültig //Standardinitalisierung ausführe   }   //ESP.wdtFeed();   return RetValue;
}

// ******************* FIN des Fonctions StoreCredentialsto EEPROM ***************************

// ******************* les Fonctions de Démarrage CardServices *************************************

void PCDHardReset()
{   digitalWrite(RST_PIN, FAIBLE);   retard(200);   digitalWrite(RST_PIN, HAUTE);   mfrc522.PCD_Reset();   mfrc522.PCD_Init();                              // Initialisiere MFRC522 Lesemodul   mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); // Setzt Antenne auf max. Empfang   mfrc522.PCD_AntennaOn();
}

boolean CardAuthenticate(boolean ABKey, octet Secteur de l', octet ikey[6])
{   const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63};   octet situation;   situation = 0;   pour (int un = 0; a < 6; une++)   {     clé.keyByte[un] = ikey[un];   }   // la Clé Un   si (ABKey)   {     situation = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, sectorkeytable[Secteur], &clé, &(mfrc522.uid));     si la (situation != MFRC522::STATUS_OK)     {       Série.println(F("ATAUTH:ERR_A"));       return false;     }   }   // Touche B   d'autre si (pas ABKey)   {     situation = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, sectorkeytable[Secteur], &clé, &(mfrc522.uid));     si la (situation != MFRC522::STATUS_OK)     {       Série.println(F("ATAUTH:ERR_B"));       return false;     }   }   return true;
}

// WriteData . utilise la Variable Globale DataBuffer pour le Retour de Données
boolean CardDataWrite(octet Secteur de l', octet du bloc, d'octets de la valeur[16])
{   de l'octet d'état;   octet writevector;   octet sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63};   writevector = Secteur de * 4 + bloc - 1 ;   pour les (octets un = 0; un < 16; un++)   {     si (writevector ==  sectorkeytable[un])     {       // Serial.println("NAK");       return false;     }   }   statut = mfrc522.MIFARE_Write(writevector, valeur, 16);   si (le statut de != MFRC522::STATUS_OK)   {     Série.println(F("ATPCD:W_ERR"));     //Série".println(mfrc522.GetStatusCodeName(status));     return false;   } else   {     // Serial.print(F("ATPCD:Write_Card_OK"));     return true;   }
}

// Lecture de Données utilise la Variable Globale DataBuffer pour le Retour de Données
boolean CardDataRead(octet Secteur de l', octet du bloc)
{   d'octets statusi;   octet readvector;   const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63};   octets de taille = 18;   readvector = Secteur de * 4 + bloc - 1 ;   pour les (octets un = 0; un < 16; un++)   {     si (readvector ==  sectorkeytable[une])     {       Série.println(F("ATPCD:R_ERR"));       return false;     }   }   statusi = mfrc522.MIFARE_Read(readvector, DataBuffer, &de taille);   si (statusi != MFRC522::STATUS_OK)   {     Série.println(F("ATPCD:R_ERR"));     return false;   } else   {     return true;   }
}

boolean ResetCardToDefault()
{   octet ikey[16];   octet d'état, je;   octet writevector;   const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63};   writevector = sectorkeytable[USED_Sector];   si (CardAuthenticate(KEYB, USED_Sector, MiFareClassicKey.Key_B)) // Secteur Autenticate pour l'Accès en ÉCRITURE   {     pour (je = 0; je <= 16; je++) {       DataBuffer[je] = 0;     }     si (!(CardDataWrite(USED_Sector, 1, DataBuffer))) {       retourner false;     }     pour (je = 0; je <= 16; je++) {       DataBuffer[je] = 0;     }     si (!(CardDataWrite(USED_Sector, 2, DataBuffer))) {       retourner false;     }     pour (je = 0; je <= 16; je++) {       DataBuffer[je] = 0;     }     si (!(CardDataWrite(USED_Sector, 3, DataBuffer))) {       retourner false;     }   }   pour (byte i = 0; i <= 16; i++) {     ikey[j'] = 255;  //Chargement de la Clé par Défaut pour tous les Secteurs   }   ikey[6] = 0xFF; // Le Réglage par défaut pour l'Accès Bits   ikey[7] = 0x07; //   ikey[8] = 0x80; //   ikey[9] = 0x69;   statut = mfrc522.MIFARE_Write(writevector, ikey, 16);   si (le statut de != MFRC522::STATUS_OK)   {     return false;   }   return true;
}

boolean SetSectorAccessControl (octet Secteur de l', octet Akey[6], octet Clef[6])
{   octet ikey[16];   octet d'état;   octet writevector;   const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63};   writevector = sectorkeytable[Secteur];   ikey[0] = Akey[0];   ikey[1] = Akey[1];   ikey[2] = Akey[2];   ikey[3] = Akey[3];   ikey[4] = Akey[4];   ikey[5] = Akey[5];   ikey[6] = 0x78; // Bloc de Données 0 À 3 Conditions d'Accès: Touche B / écriture de la Clé de Lecture   ikey[7] = 0x77; // la CLÉ UN & TOUCHE B & Acces Bits Écrire:B Clé / Clé d'Un Accès en Lecture Bits   ikey[8] = 0x88; // Calculatrice: http://calc.gmss.ru/Mifare1k/   ikey[9] = 0x69; // Fixateur Wert - > par défaut hex 69   ikey[10] = Clef[0];   ikey[11] = Clef[1];   ikey[12] = Clef[2];   ikey[13] = Clef[3];   ikey[14] = Clef[4];   ikey[15] = Clef[5];   statut = mfrc522.MIFARE_Write(writevector, ikey, 16);   si (le statut de != MFRC522::STATUS_OK)   {     Série.println(F("ATPCD:W_KEY_ERR"));     return false;   } else   {     return true;   }
}

boolean CheckforDefaultCardKey ()
{   octet tkey[6];   boolean CardResult;   octet readvector;   octet statusi;   const byte sectorkeytable [16] = {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63};   octets de taille = 18;   pour les (byte i = 0; i <= 6; i++) {     tkey[j'] = 255;  //Chargement de la Clé par Défaut pour tous les Secteurs   }   CardResult = vrai;   si (!CardAuthenticate(KEYA, USED_Sector, tkey)) {     CardResult = faux;   };   readvector = sectorkeytable[USED_Sector];   statusi = mfrc522.MIFARE_Read(readvector, DataBuffer, &de taille);   si (statusi != MFRC522::STATUS_OK) {     CardResult = false;   }   //if (!((DataBuffer[7] = 0x07) & (DataBuffer[7] = 0x80))) { CardResult = false; };   retour CardResult;
}

boolean WriteNewMiFareClassicPICC ()
{   octet tkey[6];   octet j'ai, un;   booléen CardResult;   si (CheckforDefaultCardKey())   {     pour (je = 0; je <= 6; je++) {       tkey[j'] = 255;  //Chargement de la Clé par Défaut pour tous les Secteurs     }     pour (je = 0; je <= 16; je++) {       DataBuffer[j'] = 0;  // Effacer la Variable Tampon     }     CardResult = vrai;     si (CardAuthenticate(KEYA, USED_Sector, tkey)) // Secteur Autenticate     {       // Serial.println("Auth Sec 0 OK");       si le (Nom de famille.de la longueur() > 15) {         d'une = 15;       } autre personne {         un = Nom de famille.longueur();       }       si le (Nom de famille.de la longueur() > 0)       {         pour (je = 0; je <= 16; je++) {           DataBuffer[je] = 0;         }         pour (je = 0; je <= un; je++) {           DataBuffer[je] = Nom[je];         }         si (!(CardDataWrite(USED_Sector, 2, DataBuffer))) {           CardResult = false;  //Le secteur 0 du Bloc 2 Vorname mit la Clé Un schreiben         }       }       si (Givenname.la longueur() > 15) {         d'une = 15;       } autre personne {         un = Prénom.longueur();       }       si (Givenname.la longueur() > 0)       {         pour (je = 0; je <= 16; je++) {           DataBuffer[je] = 0;         }         pour (je = 0; je <= un; je++) {           DataBuffer[je] = Givenname[je];         }         si (!(CardDataWrite(USED_Sector, 3, DataBuffer))) {           CardResult = false;  //Le secteur 0 du Bloc 3 Nachname mit la Clé Un schreiben         }       }       si (!(SetSectorAccessControl (USED_Sector, MiFareClassicKey.Key_A, MiFareClassicKey.Key_B))) {         CardResult = false;  // (octets par Secteur,byte Akey[6],byte Clef[6])       }     } d'autre {       CardResult = faux;       retour CardResult;     }   } d'autre {     CardResult = faux;     retour CardResult;   }   si (CardResult)   {     //Serial.println("PICC écrite");     CardResult = true;   }   else   {     //Serial.println("PICC n'est pas vide");     CardResult = faux;   }   rendement();   de retour CardResult;
}


boolean ReadMiFareClassicPICC ()
{   boolean CardResult;   octet je ;   CardResult = vrai;   si (CardAuthenticate(KEYA, USED_Sector, MiFareClassicKey.Key_A)) // Secteur Autenticate avec la Touche de LECTURE d'Un   {     Givenname = "               "; //espace Réservé     Nom de famille   = "               "; //espace Réservé     pour (je = 0; je < 18; je++) {       DataBuffer[j'] = 0;  // Effacer la Variable Tampon     }     si (CardDataRead(USED_Sector, 2)) // Feld Vorname auslesen     {       pour (je = 0; je < 16; je++) {         Nom[je] = char(DataBuffer[j']);       }     } else {       return false;     }     pour (je = 0; je < 18; je++) {       DataBuffer[j'] = 0;  // Effacer la Variable Tampon     }     si (CardDataRead(USED_Sector, 3)) // Feld Nachname auslesen     {       pour (je = 0; je < 16; je++) {         Givenname[j'] = char(DataBuffer[j']);       }     } else {       return false;     }   } else   {     return false;   }   return true;
}

vide CardServer()
{   byte i ;
#define PCD_Poll_Interval 400
#define PCD_Watchdog_Interval 60000   si (millis() - PCD_ServiceCall_Handler >= PCD_Poll_Interval)   {     PCD_ServiceCall_Handler = millis();     si (mfrc522.PICC_IsNewCardPresent())   // CCIP = proximité integrated circuit card = kontaktlose Chipkarte     {       mfrc522.PICC_ReadCardSerial();       rendement();       // Unterscheidung nach Kartentyp       // 0x08 für MIFARE Classic 1K       // 0x18 für MIFARE Classic 4K       // 0x11 für MIFARE PLUS       si (mfrc522.uid.sak == 0x08 || mfrc522.uid.sak == 0x18)       {         // MiFare_Classic_Processor DÉMARRER (mfrc522.uid.sak); // Nur ausführen wenn Eine Mifare Classic Karte vor den Leser gehalten wurde.         octet tkey[6];         pour (byte i = 0; i <= 6; i++) {           tkey[j'] = 255;  //Chargement de la Clé par Défaut pour tous les Secteurs         }         si (LearnNewCard) // neue Karte soll angelernt werden.         {           si (WriteNewMiFareClassicPICC()) {             SetRGBLed(0, 255, 0, faux);             LearnNewCard = faux;           } d'autre           {             SetRGBLed(255, 0, 0, faux);             LearnNewCard = faux;           }         }         sinon si (EraseCard)  // KartenDaten sollen soient supprimés werden.         {           si (ResetCardToDefault()) {             SetRGBLed(0, 255, 0, faux);             EraseCard = faux;           } d'autre           {             SetRGBLed(255, 0, 0, faux);             EraseCard = faux;           }         }         sinon         {           si (ReadMiFareClassicPICC())           { // Karte gültig !             Série.d'impression (F("ATAUTH_S:"));             Série.println (Nom);             de Série.d'impression (F("ATAUTH_G:"));             Série.println (Givenname);             temp = "Gültige Karte. Benutzer: ";             pour le (je = 0; je < 16; je++)             {               si  (Givenname[je] == 0)               {                 pause;               }               temp += char(Givenname[je]);             }             temp += ", ";             pour (je = 0; je < 16; je++)             {               si  (Nom[je] == 0)               {                 pause;               }               temp += char(Nom de famille[je]);             }             temp += " - UUID der Karte: ";             pour (byte i = 0; i < 4; i++) {               temp += Chaîne(mfrc522.uid.uidByte[je], HEX) + " ";             }             WriteToLog(temp, 0);             temp = " ";             //Faire des actions si elle est bonne Carte est détectée             bool PinState = digitalRead(RELAIS_PIN);             PinState = !PinState;             digitalWrite(RELAIS_PIN, PinState);             SetRGBLed(0, 255, 0, false);     //Led Grün             temp = "";           } d'autre {             SetRGBLed(255, 0, 0, faux);             temp = "";             pour (byte i = 0; i < 4; i++) {               temp += Chaîne(mfrc522.uid.uidByte[je], HEX) + " ";             }             temp = "Unbekannte MiFare Classic Karte. UUID der Karte: " + temp ;             WriteToLog(temp, 1);             temp = "";           }         }         LearnNewCard = faux;         // MiFare_Classic_Processor STOP (mfrc522.uid.sak);       } else if (mfrc522.uid.sak == 0x00) // Mifare Ultralight       {         SetRGBLed(255, 0, 0, false);         temp = "";         for (octets i = 0; i < 7; i++) {           temp += String(mfrc522.uid.uidByte[i], HEX) + " ";         }         temp = "Mifare UltraLight Carte ne prend pas en charge. UUID de la Carte: " + temp;         WriteToLog(temp, 1);         temp = "";       } else       {         SetRGBLed(255, 0, 0, false);         temp = "";         for (octets i = 0; i < mfrc522.uid.size; i++) {           temp += String(mfrc522.uid.uidByte[i], HEX) + " ";         }         temp = "Carte Inconnue et le type de carte. La référence: " + String(mfrc522.uid.sak) + " UUID de la Carte: " + temp ;         WriteToLog(temp, 1);         temp = "";       }       mfrc522.PCD_StopCrypto1();       mfrc522.PICC_HaltA();       delay(2000);       SetRGBLed(0, 0, 255, false);     //Led Couleur Bleu Lecteur est en État     }   }   if (millis() - PCD_WatchDog_Handler >= PCD_Watchdog_Interval)   {     PCD_WatchDog_Handler = millis();     Result = mfrc522.PCD_PerformSelfTest();     yield();     mfrc522.PCD_Init();                       // on Initialise MFRC522 module de lecture de nouveau     mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); // Définit l'Antenne de max. Réception     mfrc522.PCD_AntennaOn();     yield();     if (!(Result))     {       PCDHardReset();       Serial.println(F("ATPCD:ERR_H"));     }   }
}

// ******************* Stop Functions CardServices *************************************

void loop()  // Boucle principale
{   server.handleClient();                    // Webserveranfragen modifier   if (!(PCD_Disabled) | !(SystemConfiguration.PCD_Disabled)) {     CardServer();  // Lecteur de carte et les Demandes spécifiques de modifier   }   ESP.wdtFeed();                            // Watchdog remise à zéro. Désactiver "wdt_disable();"
}

 

Je vous souhaite beaucoup de Plaisir et beaucoup de Succès lors de la reconstruction à l'identique du Projet et jusqu'à la prochaine Fois.

Projekte für fortgeschrittene

3 commentaires

Markus

Markus

Hallo,
vielen Dank für das wunderbare Projekt.
Ich habe es mir einmal durchgelesen und bin gespannt wie es funktionieren wird.
Freundliche Grüße!

Martin Kurth

Martin Kurth

Leider hat Tobias dieses Projekt nicht weiter verfolgt oder veröffentlicht. Ich würde es wirklich gerne einsetzen. Aber leider hat er wohl keine Zeit mehr dafür.

Martin Kurth

Martin Kurth

Ich bekomme die Fehler nicht weg. IDE 1.8.10.

G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-Teil_5.ino:27:0: warning: "PINWIRESDA" redefined [enabled by default]

#define PIN_WIRE_SDA 4 ^

In file included from C:\Users\Martin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\cores\esp8266/Arduino.h:302:0,

from sketch\CardReader_ESP8266_-_Teil_5.ino.cpp:1:

C:\Users\Martin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\variants\nodemcu/pins_arduino.h:29:0: note: this is the location of the previous definition

#define PIN_WIRE_SDA (4) ^

G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-Teil_5.ino:28:0: warning: "PINWIRESCL" redefined [enabled by default]

#define PIN_WIRE_SCL 5 ^

In file included from C:\Users\Martin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\cores\esp8266/Arduino.h:302:0,

from sketch\CardReader_ESP8266_-_Teil_5.ino.cpp:1:

C:\Users\Martin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\variants\nodemcu/pins_arduino.h:30:0: note: this is the location of the previous definition

#define PIN_WIRE_SCL (5) ^

G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-_Teil5.ino: In function ‘void saveCredentials()’:

G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-_Teil5.ino:806:34: warning: iteration 20u invokes undefined behavior [-Waggressive-loop-optimizations]

MyWiFiConfig.APSTAName[i] = 0; ^

G:\BOX.heidelberg.projekt\MiFare_CardReader-master\CardReader_ESP8266_-Teil_5\CardReader_ESP8266_-_Teil5.ino:804:3: note: containing loop

for (i = 0 ; i < WiFiPwdLen ; i++) // Loeschen der alten Konfiguration ^

In file included from C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522Extended.cpp:8:0:

C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522Extended.h: In constructor ‘MFRC522Extended::MFRC522Extended(uint8_t)’:

C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522Extended.h:81:44: warning: ‘MFRC522::MFRC522’ is deprecated (declared at C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.h:339): use MFRC522 [-Wdeprecated-declarations]

MFRC522Extended(uint8_t rst) : MFRC522 {}; ^

C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp: In member function ‘bool MFRC522::MIFARE_SetUid(byte*, byte, bool)’:

C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp:1853:39: warning: ‘bool MFRC522::MIFARE_OpenUidBackdoor(bool)’ is deprecated (declared at C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp:1709): will move to extra class in next version [-Wdeprecated-declarations]

if (!MIFARE_OpenUidBackdoor(logErrors)) { ^

C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp: In member function ‘bool MFRC522::MIFARE_UnbrickUidSector(bool)’:

C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp:1882:34: warning: ‘bool MFRC522::MIFARE_OpenUidBackdoor(bool)’ is deprecated (declared at C:\Users\Martin\Documents\Arduino\libraries\MFRC522\src\MFRC522.cpp:1709): will move to extra class in next version [-Wdeprecated-declarations]

MIFARE_OpenUidBackdoor(logErrors); ^

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés

Articles de blog recommandés

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery