299 lines
8.8 KiB
C++
299 lines
8.8 KiB
C++
#pragma once
|
|
#include "databasebackend.h"
|
|
#include <Arduino.h>
|
|
#include <ArduinoJson.h>
|
|
#include <MFRC522.h>
|
|
#include <SPI.h>
|
|
|
|
|
|
// RFID Konfiguration
|
|
#define RST_PIN 21 // Configurable, see typical pin layout above
|
|
#define SS_PIN 5 // Configurable, see typical pin layout above
|
|
|
|
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
|
|
std::map<String, unsigned long>
|
|
blockedUIDs; // Map to store blocked UIDs and their timestamps
|
|
const unsigned long BLOCK_DURATION = 10 * 1000; // 10 Seconds in milliseconds
|
|
|
|
// Neue Variablen für API-basiertes Lesen
|
|
bool rfidReadRequested = false;
|
|
String lastReadUID = "";
|
|
bool rfidReadSuccess = false;
|
|
unsigned long rfidReadStartTime = 0;
|
|
const unsigned long RFID_READ_TIMEOUT =
|
|
10000; // 10 Sekunden Timeout für API Requests
|
|
|
|
// Initialisiert den RFID-Reader und das SPI-Interface.
|
|
void setupRFID() {
|
|
|
|
// SPI und RFID initialisieren
|
|
SPI.begin(); // Init SPI bus
|
|
mfrc522.PCD_Init(); // Init MFRC522
|
|
delay(4); // Optional delay. Some boards need more time after init to be ready
|
|
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card
|
|
// Reader details
|
|
}
|
|
|
|
// Liest automatisch eine RFID-Karte ein und blockiert die UID für eine
|
|
// bestimmte Zeit.
|
|
void handleAutomaticRFID() {
|
|
if (!mfrc522.PICC_IsNewCardPresent()) {
|
|
return;
|
|
}
|
|
|
|
// Select one of the cards
|
|
if (!mfrc522.PICC_ReadCardSerial()) {
|
|
return;
|
|
}
|
|
|
|
// Read the UID
|
|
String uid = "";
|
|
for (byte i = 0; i < mfrc522.uid.size; i++) {
|
|
if (i > 0)
|
|
uid += ":";
|
|
if (mfrc522.uid.uidByte[i] < 0x10)
|
|
uid += "0";
|
|
uid += String(mfrc522.uid.uidByte[i], HEX);
|
|
}
|
|
|
|
// Check if the UID is blocked
|
|
unsigned long currentTime = millis();
|
|
if (blockedUIDs.find(uid) != blockedUIDs.end()) {
|
|
if (currentTime - blockedUIDs[uid] < BLOCK_DURATION) {
|
|
Serial.print(F("UID blocked for 10 seconds. Remaining time: "));
|
|
Serial.print((BLOCK_DURATION - (currentTime - blockedUIDs[uid])) / 1000);
|
|
Serial.println(F(" seconds."));
|
|
Serial.println(uid);
|
|
return;
|
|
} else {
|
|
// Remove the UID from the blocked list if the block duration has passed
|
|
blockedUIDs.erase(uid);
|
|
}
|
|
}
|
|
|
|
// Process the UID
|
|
Serial.print(F("UID: "));
|
|
Serial.println(uid);
|
|
|
|
// Block the UID for 10 seconds
|
|
blockedUIDs[uid] = currentTime;
|
|
// show the remaining time for the block
|
|
Serial.print(F("UID blocked for 10 seconds. Remaining time: "));
|
|
Serial.print((BLOCK_DURATION - (currentTime - blockedUIDs[uid])) / 1000);
|
|
Serial.println(F(" seconds."));
|
|
|
|
// Halt the card
|
|
mfrc522.PICC_HaltA();
|
|
}
|
|
|
|
// Neue Funktion für API-basiertes RFID Lesen
|
|
|
|
// Liest eine RFID-Karte im API-Modus ein (für Web-Requests).
|
|
void handleAPIRFIDRead() {
|
|
unsigned long currentTime = millis();
|
|
|
|
// Timeout prüfen
|
|
if (currentTime - rfidReadStartTime > RFID_READ_TIMEOUT) {
|
|
Serial.println("RFID API Timeout - keine Karte erkannt");
|
|
rfidReadRequested = false;
|
|
rfidReadSuccess = false;
|
|
lastReadUID = "";
|
|
return;
|
|
}
|
|
|
|
// Prüfen ob neue Karte vorhanden ist
|
|
if (!mfrc522.PICC_IsNewCardPresent()) {
|
|
return;
|
|
}
|
|
|
|
// Karte auswählen
|
|
if (!mfrc522.PICC_ReadCardSerial()) {
|
|
return;
|
|
}
|
|
|
|
// UID für API lesen (ohne Doppelpunkt-Trenner, Großbuchstaben)
|
|
String uid = "";
|
|
for (byte i = 0; i < mfrc522.uid.size; i++) {
|
|
if (mfrc522.uid.uidByte[i] < 0x10) {
|
|
uid += "0"; // Leading Zero für einstellige Hex-Werte
|
|
}
|
|
uid += String(mfrc522.uid.uidByte[i], HEX);
|
|
}
|
|
|
|
// UID in Großbuchstaben konvertieren
|
|
uid.toUpperCase();
|
|
|
|
Serial.println("RFID API UID gelesen: " + uid);
|
|
|
|
// Ergebnis speichern
|
|
lastReadUID = uid;
|
|
rfidReadSuccess = true;
|
|
rfidReadRequested = false;
|
|
|
|
// Karte "halt" setzen
|
|
mfrc522.PICC_HaltA();
|
|
mfrc522.PCD_StopCrypto1();
|
|
}
|
|
|
|
// API Funktion: RFID Lesevorgang starten
|
|
|
|
// Startet einen neuen RFID-Lesevorgang über die API.
|
|
void startRFIDRead() {
|
|
Serial.println("RFID API Lesevorgang gestartet...");
|
|
rfidReadRequested = true;
|
|
rfidReadSuccess = false;
|
|
lastReadUID = "";
|
|
rfidReadStartTime = millis();
|
|
}
|
|
|
|
// API Funktion: Prüfen ob Lesevorgang abgeschlossen
|
|
|
|
// Prüft, ob der aktuelle RFID-Lesevorgang abgeschlossen ist.
|
|
bool isRFIDReadComplete() { return !rfidReadRequested; }
|
|
|
|
// API Funktion: Ergebnis des Lesevorgangs abrufen
|
|
// Gibt das Ergebnis des letzten RFID-Lesevorgangs zurück.
|
|
String getRFIDReadResult(bool &success) {
|
|
success = rfidReadSuccess;
|
|
return lastReadUID;
|
|
}
|
|
|
|
// Richtet die HTTP-API-Routen für RFID-Operationen ein.
|
|
void setupRFIDRoute(AsyncWebServer &server) {
|
|
server.on("/api/rfid/read", HTTP_GET, [](AsyncWebServerRequest *request) {
|
|
Serial.println("api/rfid/read");
|
|
|
|
// Start RFID-Lesevorgang
|
|
startRFIDRead();
|
|
unsigned long startTime = millis();
|
|
|
|
// Warten, bis eine UID gelesen wird oder Timeout eintritt
|
|
while (!isRFIDReadComplete()) {
|
|
if (millis() - startTime > RFID_READ_TIMEOUT) {
|
|
break;
|
|
}
|
|
delay(10); // Kurze Pause, um die CPU nicht zu blockieren
|
|
}
|
|
|
|
DynamicJsonDocument response(200);
|
|
|
|
if (rfidReadSuccess && lastReadUID.length() > 0) {
|
|
response["success"] = true;
|
|
response["uid"] = lastReadUID;
|
|
response["message"] = "UID erfolgreich gelesen";
|
|
} else {
|
|
response["success"] = false;
|
|
response["error"] = "Keine RFID Karte erkannt oder Timeout";
|
|
response["uid"] = "";
|
|
}
|
|
|
|
String jsonString;
|
|
serializeJson(response, jsonString);
|
|
request->send(200, "application/json", jsonString);
|
|
});
|
|
|
|
server.on(
|
|
"/api/users/insert", HTTP_POST, [](AsyncWebServerRequest *request) {},
|
|
NULL,
|
|
[](AsyncWebServerRequest *request, uint8_t *data, size_t len,
|
|
size_t index, size_t total) {
|
|
Serial.println("/api/users/insert");
|
|
|
|
// Parse the incoming JSON payload
|
|
DynamicJsonDocument doc(512);
|
|
DeserializationError error = deserializeJson(doc, data, len);
|
|
|
|
DynamicJsonDocument response(200);
|
|
|
|
if (error) {
|
|
Serial.println("Fehler beim Parsen der JSON-Daten");
|
|
response["success"] = false;
|
|
response["error"] = "Ungültige JSON-Daten";
|
|
} else {
|
|
// Extract user data from the JSON payload
|
|
String uid = doc["uid"] | "";
|
|
String vorname = doc["vorname"] | "";
|
|
String nachname = doc["nachname"] | "";
|
|
String geburtsdatum = doc["geburtsdatum"] | "";
|
|
int alter = doc["alter"] | 0;
|
|
|
|
// Validate the data
|
|
if (uid.isEmpty() || vorname.isEmpty() || nachname.isEmpty() ||
|
|
geburtsdatum.isEmpty() || alter <= 0) {
|
|
Serial.println("Ungültige Eingabedaten");
|
|
response["success"] = false;
|
|
response["error"] = "Ungültige Eingabedaten";
|
|
} else {
|
|
// Process the data using the enterUserData function
|
|
Serial.println("Benutzerdaten empfangen:");
|
|
Serial.println("UID: " + uid);
|
|
Serial.println("Vorname: " + vorname);
|
|
Serial.println("Nachname: " + nachname);
|
|
Serial.println("Alter: " + String(alter));
|
|
|
|
bool dbSuccess =
|
|
enterUserData(uid, vorname, nachname, geburtsdatum, alter);
|
|
|
|
if (dbSuccess) {
|
|
response["success"] = true;
|
|
response["message"] = "Benutzer erfolgreich gespeichert";
|
|
} else {
|
|
response["success"] = false;
|
|
response["error"] = "Fehler beim Speichern in der Datenbank";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Send the response back to the client
|
|
String jsonString;
|
|
serializeJson(response, jsonString);
|
|
request->send(200, "application/json", jsonString);
|
|
});
|
|
}
|
|
|
|
// API Funktion: RFID Reader Status prüfen
|
|
|
|
// Prüft, ob der RFID-Reader korrekt funktioniert und gibt den Status zurück.
|
|
bool checkRFIDReaderStatus() {
|
|
byte version = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
|
|
|
|
// Bekannte MFRC522 Versionen: 0x91, 0x92
|
|
if (version == 0x91 || version == 0x92) {
|
|
Serial.println("RFID Reader OK (Version: 0x" + String(version, HEX) + ")");
|
|
return true;
|
|
} else {
|
|
Serial.println("RFID Reader Fehler (Version: 0x" + String(version, HEX) +
|
|
")");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Hilfsfunktion: Blockierte UIDs aufräumen
|
|
|
|
// Entfernt UIDs aus der Blockliste, deren Blockdauer abgelaufen ist.
|
|
void cleanupBlockedUIDs() {
|
|
unsigned long currentTime = millis();
|
|
|
|
// Iterator für sicheres Löschen während der Iteration
|
|
for (auto it = blockedUIDs.begin(); it != blockedUIDs.end();) {
|
|
if (currentTime - it->second >= BLOCK_DURATION) {
|
|
it = blockedUIDs.erase(it);
|
|
} else {
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Hauptschleife für das RFID-Handling (automatisch und API-basiert).
|
|
void loopRFID() {
|
|
// Originale Funktionalität für automatisches Lesen
|
|
if (!rfidReadRequested) {
|
|
handleAutomaticRFID();
|
|
}
|
|
|
|
// API-basiertes Lesen verarbeiten
|
|
if (rfidReadRequested) {
|
|
handleAPIRFIDRead();
|
|
}
|
|
}
|