diff --git a/src/FabReader/FabReader.ino b/src/FabReader/FabReader.ino deleted file mode 100644 index 0d526ea..0000000 --- a/src/FabReader/FabReader.ino +++ /dev/null @@ -1,1418 +0,0 @@ - -/* - ESP8266 RFID Reader - MQTT with OLED display for WiFi and Enthernet - - The aim of the project is, to have a RFID-cardreader which has Wifi and Ethernet capabilities at low costs. - The hardware therfor consists of low cost modules like: - - ESP8266 or ESP32 - - 0.96" OLED module (ESP8266) or e-ink module (ESP32) - - RC522 RFID module - - ENC28j60 Ethernet module - - With only a minimum of additional components they provide a full functioning hardware - - General function: - The RC522 reads a RFID token and sends the UID via MQTT to a broker. The data is sent in JASON format. For security reasons, the tokens can be encrypted - and a timestamp can be stored on the card wich changes each time the card is read. The old and new timestamp will be transmitted - to the broker as well (if activated). - The hardware forsees an input (ADC in case of the EPS8266), where a button can (must, for the first configuration) be connected. During boot, this button can be pressed to enter - into configuration mode. This creates an access point (AP). By connecting to this access point via a browser (http://192.168.4.1/ ), all connection - parameters of the unit can be changed. Here the connection mode (WiFI or ethernet) can be set aswell. - - Seceurity issues: - PLEASE BE AWARE - 1. the used Mifare Classic technology has been hacked and RFID-tokens can be copied including the UID. Do not use this - technology for sensitive applications. Use DESfire or Mifare Ultralight C instead. - 2. all connection data are stored in the EEPROM. To prevent someone from reading these data, they need to be encrypted. - Only the ESP32 is capable of encrypting the EEPROM (allthough this encryption can be hacked in a day by skillfull people). - When using a ESP8266 use a separate network for MQTT or secure the devices against theft. - - - Version description: - Version 01 - initial Version - Version 01 - include ESP32 as option - Version 6 - show text messages. - -*/ - -#ifdef ESP32 - #include // ESP32 - #include // ESP32 - #include // ESP32 - #include - #include // E-Paper - //#include // 2.13" b/w - //#include // 2.13" b/w new panel - #include // E-Paper - #include - #include - #include - #include - #include - #include -#else - #include // EPS8266 - #include // ESP8266 - #include // ESP8266 - // #include /// -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// #include // for retreiving the MAC adress - - -// Definition der Pins -#ifdef ESP32 - #define SS_PIN 32 // GPIO17 - #define RST_PIN 33 // GPIO16 - #define BEEP_PIN 27 // GPIO16 - #define BUTTON_PIN 39 // GPIO39 - #define CS 19 // ESP32 - - #define SPI_MOSI 23 - #define SPI_MISO -1 - #define SPI_CLK 18 - - #define ELINK_SS 5 - #define ELINK_BUSY 4 - #define ELINK_RESET 16 - #define ELINK_DC 17 -#else -// #define SS_PIN 15 // GPIO15 -> uncomment this for the old PCB - #define SS_PIN 2 // GPIO2 - #define RST_PIN 0 // GPIO00 - #define BEEP_PIN 16 // GPIO16 - #define BUTTON_PIN 13 // GPIO2 -> uncomment this for the old PCB - #define CS 15 // ESP8266 -#endif - -#define HSPI_MOSI 15 -#define HSPI_MISO 2 -#define HSPI_SCLK 14 - - -// to make some messages easier to read -#define CONNECT_TO_WIFI 0 -#define CONNECT_TO_MQTT 1 -#define PUSH_BUTTON 2 -#define IN_AP_MODE 3 -#define CONNECT_TO_LAN 4 -#define ERROR_RFID 5 -#define MQTT_RFID 6 -#define WRONG_RFID_TYPE 7 -#define ERROR_DHCP 8 - - -int Old_PCB=0; - - -/* configuration variables for your wifi -> will be loaded from the EEPROM !!! */ -char ssid[32] = "WLAN"; // WLAN ID -char password[64] = "Passwort"; // WLAN password for WPA PSK - -/* configuration variables MQTT-client mode -> will be loaded from the EEPROM !!!*/ -char host[128] = "rfid_reader"; // Name at the MQTT Broker -char broker[16] = "192.168.2.13"; // IP adresse of the MQTT broker in your local (W)LAN -char mqttUser[32] = "mqttuser"; // to access the the MQTT broker, if broker is configured that way -char mqttPass[32] = "mqttpassword"; // to access the the MQTT broker, if broker is configured that way -char ReaderID[5] ; //= "000"; // identifyer for the reader. -char subTopic[18] = "/cmnd/reader/"; // MQTT Topic where to find commands for the reader + ReaderID + 0x00 -char ConType [3] = "0"; - -/* Configuration for access point mode -> can be anything you like*/ -const char *ssidAP = "RFID-Reader"; // modify to your needs -const char *passwordAP = "Passwort"; // modify to your needs - -const char* vers = "V02"; // Software Version -boolean StartUpMode = 0; // to start either as access point (0) and MQTT-client (1) -boolean OTA=0; // is there currently an OTA process running? -byte Wifi_Ether = 0; // to connect either via Wifi (0) or Ethernet (1) -> using a Byte to store it in EEPROM easily -byte RFID_Mod; // what card type to be read -> using a Byte to store it in EEPROM easily -byte Format_Mod; // what format to send data -> using a Byte to store it in EEPROM easily - -uint64_t IV=0; -byte C_key[24]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -//= { 0x49, 0x45, 0x4D, 0x4B, 0x41, 0x45, 0x52, 0x42, 0x21, 0x4E, 0x41, 0x43, 0x55, 0x4F, 0x59, 0x46, 0x49, 0x45, 0x4D, 0x4B, 0x41, 0x45, 0x52, 0x42}; - -unsigned long oldMillis; // used to identify time outs - -int maxMessage = 18; - -String lastLine1, lastLine2; // to save previous displayed messages -boolean linesSaved = 0; // no previous message has been saved -int fsize=0; // current font size (for E-paper) - -String Message_Disp[] = {"verfuegbar", // 0 - equipment available // 0 - "reserviert", // 0 - equipment reserved // 1 - "reserviert ab", // 13 - reserved starting from // 2 - "in Benutzung", // 0 - equipment in use // 3 - "freigegeben", // 0 - access granted // 4 - "Anmeld. fehlgeschlagen", // 8 - login error // 5 - "Nutzungsgebuehr", // 15 - usage fee // 6 - "Nutzung nicht erlaubt", // 13 - operation not allowed // 7 - "Nutzung auf eigenem Risiko", // 11 - operation at own risk // 8 - "gesperrt durch", // 14 - equipment locked by // 9 - "freizugeben durch", // 11 - to be released by // 10 - "ausserhalb der Nutzungzeit", // 15 - outside ooperating hours// 11 - "Nutzungsdauer", // 13 - duration of use // 12 - "abgemeldet", // 0 - logged out // 13 - "abschalten in", // 13 - equipment will lock down// 14 - "Karte gesperrt", // 0 - card locked // 15 - "Karte unbekannt", // 0 - card unknown // 16 - "Berechtigung endet", // 12 - training to expire // 17 - "Ruhemodus", // 0 - sleep mode // 18 - "Aufsicht bestaetigen"}; // 8 - confirm presence // 19 - -int SplitAt[]={0,0,13,0,0,8,15,13,11,15,11,14,14,0,13,0,0,12,0,8}; - -/* -String Message_Com[] = {"1", // equipment available - "2", // equipment reserved - "3", // reserved starting from - "4", // equipment in use - "5", // access granted - "6", // login error - "7", // usage fee - "8", // operation not allowed - "9", // operation at own risk - "10", // equipment locked by - "11", // to be released by - "12", // outside ooperating hours - "13", // duration of use - "14", // logged out - "15" // equipment will lock down - "16", // card locked - "17", // card unknown - "18", // training to expire - "19", - "20"}; // sleep mode -*/ - - -//----------- E-Paper-Stuff -#ifdef ESP32 - SPIClass eSPI(HSPI); - GxIO_Class io(eSPI, /*CS=5*/ ELINK_SS, /*DC=*/ ELINK_DC, /*RST=*/ ELINK_RESET); - GxEPD_Class EPaper(io, /*RST=*/ ELINK_RESET, /*BUSY=*/ ELINK_BUSY); -#endif - - -EthernetClient ethClient; // in case of Ethernet connection -WiFiClient wifiClient; // in case of Wifi connection -PubSubClient MQTTclient; // The MQTT Client - -#ifdef ESP32 - WebServer httpServer(80); // ESP32 -#else - ESP8266WebServer httpServer(80); // ESP8266 -#endif - - -// instance for the RFID-Reader -MFRC522 rfid(SS_PIN, RST_PIN); -MFRC522::MIFARE_Key key; -MFRC522::StatusCode status; -DES des; - -//Starting page for parameter configuration -const char INDEX_HTML[] = -"" -"" -"" -"" -"" -"Verbindungsdaten RFID-Reader" -"" -"" -"" -"

Verbindungsdaten RFID-Reader

" -"
" -"

" -"
" -"
" -"
" -"
" -"Connection
" -"Ehternet
" -"WiFi
" -"RFID-Type
" -"Mifare Classic
" -"Mifare Classic + Timestamp
" -"Mifare DESFire
" -"Mifar Ultralight C
" -"Data Package Format
" -"JSON
" -"Text
" -" " -"

" -"
" -"" -""; - - -// Initialize the OLED display using Wire library -#ifdef ESP32 - SSD1306Wire display(0x3c, 21, 22); // ESP32 SSD1306Wire display(0x3c, SDA, SCL); -#else - SSD1306Wire display(0x3c, 4, 5); // ESP8266 SSD1306Wire display(0x3c, SDA, SCL); -#endif - - - - -void setup(void){ - - pinMode(BEEP_PIN, OUTPUT); // buzzer pin - pinMode(BUTTON_PIN, INPUT); // button pin - pinMode(CS, OUTPUT); // CS-Pin of the ENC28J60 Module - - digitalWrite(CS, HIGH); // -> needs to be set, otherwise MISO will be pulled LOW - - #ifdef ESP32 - SPI.begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, CS); // for the LAN Module and the RC522 module - eSPI.begin(SPI_CLK, SPI_MISO, SPI_MOSI, ELINK_SS); // For the e-Paper Module - #else - SPI.begin(); - #endif - - rfid.PCD_Init(); // RC522 initialize - // rfid.PCD_PerformSelfTest(); - - Serial.begin(115200); - Serial.println(); - Serial.println("Booting..."); - - des.init(C_key,IV); - - #ifdef ESP32 - EPaper.init(); // enable diagnostic output on Serial - EPaper.setRotation(3); - EPaper.fillScreen(GxEPD_WHITE); - EPaper.setTextColor(GxEPD_BLACK); - EPaper.setFont(&FreeMonoBold12pt7b); - EPaper.setCursor(0, 0); - EPaper.update(); - #endif - - display.init(); // initialize display - display.clear(); - display.flipScreenVertically(); - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.display(); - - EEPROM.begin(512); // initialize EEPROM - - StatusToDisplay(PUSH_BUTTON); - - // displayPushButton(); // message shown during the boot up - delay(5000); // dealy, to give time to press the button - - int value=800; - if(Old_PCB){ - if(digitalRead(BUTTON_PIN)==LOW) - value=0; - } - else{ - value = analogRead(A0); - } - - Serial.print("value: "); - Serial.println(value); - - if (value > 512) // button pressed? -> attention: button signal is inverted - setupAP(); // -> configuration - else - setupMQTT(); // -> start MQTT-Client - - oldMillis=millis(); - -} - -void setupAP(void){ - StartUpMode = 0; - - Serial.println("Configuring access point..."); - WiFi.mode(WIFI_AP); //Access Point mode IP: 192.168.4.1 - - // Serial.println("Setting soft-AP configuration ... "); - // WiFi.softAPConfig(ap_local_IP, ap_gateway, ap_subnet); - Serial.println("Setting soft-AP ... "); - WiFi.softAP(ssidAP, passwordAP); - Serial.print("Soft-AP IP address = "); - Serial.println(WiFi.softAPIP()); - - //Configuring the web server - httpServer.on("/", handleRootAP); - httpServer.onNotFound(handleNotFoundAP); - httpServer.begin(); - Serial.println("HTTP server started"); - StatusToDisplay(IN_AP_MODE); -} - -void setupMQTT(void){ - uint8_t mac[6]; - - StartUpMode = 1; - readConfig(); // loading parameter set from EEPROM - MQTTclient.setBufferSize(356); // 256 APDU size + topic + JSON chars - if(Wifi_Ether){ // either start via ethernet or Wifi - // esp_read_mac(mac, ESP_MAC_WIFI_STA); // reading teh MAC address of the unit - StatusToDisplay(CONNECT_TO_LAN); - - WiFi.macAddress(mac); - Ethernet.init(CS); // set the correct pin - if(Ethernet.begin(mac) == 0) { - Serial.println(F("Ethernet configuration using DHCP failed")); - StatusToDisplay(ERROR_DHCP); - while(1); - } - else{ - Serial.println(F("Ethernet configuration using DHCP OK")); - } - Serial.print("set Client to Ethernet: "); - MQTTclient.setClient(ethClient); - //WiFi.forceSleepBegin(); // TODO - //WiFi.mode(WIFI_OFF); // TODO - Serial.println("OK"); - } - else{ - StatusToDisplay(CONNECT_TO_WIFI); - WiFi.mode(WIFI_STA); // only station, no access point - WiFi.begin(ssid, password); - Serial.print("set Client to Wifi: "); - MQTTclient.setClient(wifiClient); - Serial.println("OK"); - Serial.print("MAC address: "); - Serial.println(WiFi.macAddress()); - } - StatusToDisplay(CONNECT_TO_MQTT); - Serial.print("set MQTT-Server..."); - MQTTclient.setServer(broker,1883); //for using local broker - Serial.println(" OK"); - Serial.print("setting callback..."); - MQTTclient.setCallback(callback); - Serial.println(" OK"); - //Serial.print("starting MDNS..."); - //MDNS.begin(host); - //Serial.println(" OK"); - Serial.println("Up and running!"); - -/* Generate the Mifare Keys (key A and B) - * Standard key is FFFFFFFFFFFFh for unformatted RFID tokens - * Special key can be configured and will be loaded from EEPROM (To-Do) - */ - - for (byte i = 0; i < 6; i++) { - key.keyByte[i] = 0xFF; - } - StatusToDisplay(MQTT_RFID); -} - - - -void loop(void){ - if(StartUpMode){ // if in MQTT-Mode - if(!MQTTclient.connected()) { // if not connected - connect(); - } - MQTTclient.loop(); // do all the MQTT-stuff - delay(10); - if(!OTA) // search only for new cards if there is no OTA process ongoing - handleRFID(); // if a card was found and data was sent - delay(50); - } - - httpServer.handleClient(); -} - - -/* - * ------------------------------------------------------------------------------------------------------------------ - * Code for Access Point mode - */ - -/* - * Show configuration page - */ -void handleRootAP() { - - if (httpServer.hasArg("ssid")&& httpServer.hasArg("Passwort")&& httpServer.hasArg("BrokerIP")&&httpServer.hasArg("ReaderID") ) {//If all form fields contain data call handelSubmit() - handleSubmit(); - } - else { - String s = INDEX_HTML; - httpServer.send(200, "text/html", s); - } - -} - -/* - * Shows the data, to be saved in the EEPROM - */ - -void handleSubmit(){ - - // TO DO - check if entries are too long and promt an error! - - String response="

SSID: "; - response += httpServer.arg("ssid"); // max 32 characters - response +="
"; - response +="Password: "; - response +=httpServer.arg("Passwort"); // max 64 characters - response +="
"; - response +="The broker IP-Address is: "; - response +=httpServer.arg("BrokerIP"); // max 16 characters - response +="
"; - response +="Hostname is: "; // max 128 characters - response +="rfid_reader_"; // TO DO -> complete argument for the Hostname - response +=httpServer.arg("ReaderID"); // max 3 characters - response +="
"; - response +="Topic name is: "; - response +="/rfid_reader/"; // TO DO -> complete argument for the topic - response +=httpServer.arg("ReaderID"); - response +="
"; - response +="connection via: "; - if(httpServer.arg("ConType")=="1"){ - response +="Ethernet"; - Wifi_Ether=1; - } - else{ - response +="Wifi"; - Wifi_Ether=0; - } - response +="
"; - response +="RFID-ID: "; - if (httpServer.arg("RFIDType")=="1"){ - response +="Mifare Classic + Timestamp"; - RFID_Mod=1; - } - else if (httpServer.arg("RFIDType")=="2"){ - response +="Mifare DESFire"; - RFID_Mod=2; - } - else if (httpServer.arg("RFIDType")=="3"){ - response +="Mifar Ultralight C"; - RFID_Mod=3; - } - else{ // default - response +="Mifare Classic"; - RFID_Mod=0; - } - response +="
"; - response +="MQTT-Data Format: "; - if (httpServer.arg("DatFormat")=="1"){ - response +="Text"; - Format_Mod=1; - } - else{ - response +="JSON"; - Format_Mod=0; - } - - - response +="


"; - response +="

go home


"; - - // show data - httpServer.send(200, "text/html", response); - - // write data to EEPROM - write_to_Memory(String(httpServer.arg("ssid")),String(httpServer.arg("Passwort")),String(httpServer.arg("BrokerIP")),String(httpServer.arg("ReaderID")), Wifi_Ether, RFID_Mod, Format_Mod ); -} - - -/* - * Write data to the EEPROM - * The data is merged to a single string, separated by "\r" - * TO DO -> the complete string is then encrypted. - * resulting String is wrtitten to the EEPROM - * - */ -void write_to_Memory(String s,String p,String i, String g, byte w, byte r, byte f){ - EEPROM.write(0,w); // how to connect - EEPROM.write(1,r); // what type of RFID tokens are used - EEPROM.write(2,f); // how to format MQTT-data - s+="\r"; // SSID max 32 characters - s+=p; // password max 64 characters - s+="\r"; - s+=i; // Broker-IP 16 charaacters - s+="\r"; - s+=g; // ID max 3 characters - s+="\r"; - write_EEPROM(s,3); - EEPROM.commit(); -} - -//Daten in den EEPROM schreiben -void write_EEPROM(String x,int pos){ - for(int n=pos;ngo home
"; - httpServer.send(404, "text/plain", message); -} - - - -/*--------------------------------------------------------------------------------------------------------------------------------------- - * Code for MQQT Client mode - */ - -/* - * connect to Wifi / MQTT-broker - */ -void connect() { - if(!Wifi_Ether){ // only if connected by Wifi !!! - StatusToDisplay(CONNECT_TO_WIFI); - while(WiFi.waitForConnectResult() != WL_CONNECTED){ - WiFi.begin(ssid, password); - Serial.println("WiFi failed, retrying."); - } - - Serial.print("IP address: "); - Serial.println(WiFi.localIP()); - } - while (!MQTTclient.connected()) { - StatusToDisplay(CONNECT_TO_MQTT); - Serial.println("Reconnecting MQTT..."); - if (!MQTTclient.connect(ReaderID, mqttUser, mqttPass)) { - Serial.print("failed, rc="); - Serial.println(MQTTclient.state()); - } - } - byte topicLenght=sizeof(subTopic); - topicLenght=topicLenght-1; - for (int i=0; i<3 ;i++){ - subTopic[(topicLenght-4)+i]=ReaderID[i]; - } - subTopic[topicLenght]=0x00; - MQTTclient.subscribe(subTopic); - Serial.println(F("connected!")); - Serial.print(F("subscribed to topic: ")); - Serial.println(subTopic); - StatusToDisplay(MQTT_RFID); -} - - -/* - * answer to HTTP-requests - */ - -void handleRootMQTT() { - httpServer.send(200, "text/plain", "It works!!!"); -} - -/* - * Handle received MQTT Messages - * examples: - * show message on Display - JSON object = {"Cmd": "message", "MssgID": 4 , "ClrTxt":"Hello World" , "AddnTxt":"3:00"} // mID as int - * communicate with reader - JSON object = {"Cmd": "sendPICC", "data": "0123456789ABCDEF"} // data in ASCII - * communicate with reader - JSON object = {"Cmd": "haltPICC"} - * recieve auth Key - JSON object = {"Cmd": "Key", "data": 0123456789ABCDEF} // data in ASCII - * Confirm User attendence - JSON object = {"Cmd": "ConfirmUser"} - */ - -void callback(char* topic, byte* payload, unsigned int length) { -int mID; -int len; - - Serial.print("Received message ["); - Serial.print(topic); - Serial.print("] "); - for (int i = 0; i < length; i++) { - Serial.print((char)payload[i]); - } - Serial.println(); - - DynamicJsonDocument doc(256); - deserializeJson(doc, (char*)payload); - JsonObject root = doc.as(); - - - - if(!root["Cmd"].isNull()) { - if(root["Cmd"] == "message") { // Message to display - if(!root["MssgID"].isNull()) { - mID=root["MssgID"]; - MessageToDisplay(mID, root["ClrTxt"], root["AddnTxt"]); - } - } - if(root["Cmd"] == "sendPICC") { // command for OTA communication with the PICC - if(!root["data"].isNull()) { - APDUtrancieve( root["data"]); - } - } - if(root["Cmd"] == "haltPICC") { // command for ending OTA communication with the PICC - rfid.PICC_HaltA(); - OTA=0; - } - if(root["Cmd"] == "Key"){ // set the auth key for Mifare Ultralight C or NTAG216 - setAuthKey( root["data"]); - } - if(root["Cmd"] == "ConfirmUser") { // start beeping and flashing -> user needs to confirm its presence at the equipment - - } - } -} - - -/* - * Reading the RFID Token - * - * When a token is recocnized.... - * - read the UID and SAK-value - * - * Mifare Classic without time stamp (Mode=0) - * Mifare Classic Mode + timestamp (Mode=1) - * DESFire - Mode (Mode=2) - * Ultralight C - Mode (Mode=3) - - * - * CAUTION: The total MQTT message (topic + payload) must not be too long, otherwise the data and the connection will be lost!!!! - * - */ - -void handleRFID(void) { - - // Try to access a RFID-token - if (!rfid.PICC_IsNewCardPresent()) return; // is there a RFID token at all? - if (!rfid.PICC_ReadCardSerial()) return; // can I read it? - - Serial.print(F("Mod = ")); - Serial.println(RFID_Mod); - - if((RFID_Mod==0)||(RFID_Mod==1)){ - if((rfid.uid.sak != 0x08)&&(rfid.uid.sak != 0x09)&&(rfid.uid.sak != 0x18)){ - Serial.println(F("should be Mifare Classic, but isn't")); - popRFIDerror(); - } - else{ - if(!RequestMifare()){ // test for Ultralight "C" - popRFIDerror(); - } - } - } - if(RFID_Mod==2){ - if(rfid.uid.sak != 0x20){ // should be Mifare DESFire, but isn't - Serial.println(F("should be Mifare DESFire, but isn't")); - popRFIDerror(); - } - else{ - if(!HandleDESFire()){ - popRFIDerror(); - } - } - } - if(RFID_Mod==3){ - if(rfid.uid.sak != 0x00){ // should be Mifare Ultralight C, but isn't - Serial.println(F("should be Mifare Ultralight C, but isn't")); - popRFIDerror(); - } - else{ - if(!RequestAuthUltralightC()){ // test for Ultralight "C" - popRFIDerror(); - } - } - } - if(!OTA){ // close only when OTA there is no OTA process ongoing - rfid.PICC_HaltA(); - rfid.PCD_StopCrypto1(); - } -} - - -boolean HandleDESFire(void){ -byte buffer[67]; // buffer for reading data max 63 bytes per frame + 2 bytes status + 2 bytes CRC -byte bufferSize=sizeof(buffer); -char UID[21]; - - byte2charArray(rfid.uid.uidByte, UID, rfid.uid.size); - Serial.print(F("UID: ")); - Serial.println(UID); - - // start with ATS- Build command buffer - buffer[0] = 0xE0; //PICC_CMD_RATS; - buffer[1] = 0x50; // FSD=64, CID=0 - rfid.PCD_CalculateCRC(buffer, 2, &buffer[2]); - status = rfid.PCD_TransceiveData(buffer, 4, buffer, &bufferSize, NULL, 0, true); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("Failed to get ATS: ")); - Serial.println(rfid.GetStatusCodeName(status)); - return 0; - } - - bufferSize=sizeof(buffer); - - byte cid=0x00; - - buffer[0] = 0xD0 | (cid & 0x0F); - buffer[1] = 0x11; // PPS0: PPS1 will follow - buffer[2] = 0x00; // PPS1: set to 106kBaud in both directions DSI and DRI - rfid.PCD_CalculateCRC(buffer, 3, &buffer[3]); - status = rfid.PCD_TransceiveData(buffer, 5, buffer, &bufferSize, NULL, 0, true); - if (status == MFRC522::STATUS_OK) { - // This is how my MFRC522 is by default. - // Reading https://www.nxp.com/documents/data_sheet/MFRC522.pdf it seems CRC generation can only be disabled in this mode. - // if (pps1 == 0x00) { // =buffer[2] TODO why? - rfid.PCD_WriteRegister(MFRC522::TxModeReg, 0x00); - rfid.PCD_WriteRegister(MFRC522::RxModeReg, 0x00); - //} - } - else - return 0; - - OTA=1; // Over The Air (OTA) Communication enabled - sendUID(UID, NULL, NULL); - return 1; -} - -/* - * APDUtrancieve(char* in, char* out, byte len) - * Sends the string "in" to the PICC and provides "out" as the response. - * "in" and "out" are formatted as readable chars, and converted internally to bytes. - * "len" provides the length of the provided string (twice the len of the real bytes transfered) - * communicate with reader - JSON object = {"Cmd": "readPICC", "data": "0123456789ABCDEF"} - */ - -boolean APDUtrancieve(String in){ -byte buffer[67]; // buffer for reading data max 63 bytes per frame + 2 bytes status + 2 bytes CRC -byte len; -byte len_send; -char JSONmessageBuffer[200]; // contains the full JSON message -char topic[32]; - - for(len=0; len<126; len++){ - if(in[len]==0x00) - break; - } - - buffer[0]=0x0A; // PCB - Protocol Control Byte - buffer[1]=0x00; // CID - Card ID, always assumed as 0x00 as multicard reading is not implemented - // NAD - Node Address - not implemented and not required according to the setting of Protocol Control Byte (PCB) - char2byteArray(in, &buffer[2], len); - len=len/2; - len=len+2; // two first bytes - status = rfid.PCD_CalculateCRC(buffer, len, &buffer[len]); - if (status != rfid.STATUS_OK) { - Serial.print(F("CRC-gen failed: ")); - Serial.println(rfid.GetStatusCodeName(status)); - return 0; - } - - Serial.print(F("APDU-Command: ")); - dump_byte_array(&buffer[2], len-2); - - len_send=len+2; - len=sizeof(buffer); - status = rfid.PCD_TransceiveData(buffer, len_send, buffer, &len, NULL, 0, true); - if (status != rfid.STATUS_OK) { - Serial.print(F("APDU-command failed: ")); - Serial.println(rfid.GetStatusCodeName(status)); - return 0; - } - - len=len-4; // two bytes at the beginning (status-bytes) and the two CRC bytes - - Serial.print(F("APDU-Response: ")); - dump_byte_array(&buffer[2], len); - - // communicate with reader - JSON object = {"Cmd": "readPICC", "data": "0123456789ABCDEF"} // data in ASCII - - snprintf(JSONmessageBuffer, sizeof(JSONmessageBuffer), R"({"Cmd":"readPICC","data":")"); // 27 characters - byte2charArray(&buffer[2], &JSONmessageBuffer[26], len); - // org: snprintf(JSONmessageBuffer, sizeof(JSONmessageBuffer), R"({"UID":"%s","KeyOld":"%s","KeyNew":"%s"})", UID, KeyOld, KeyNew); - - len=len*2; // as we have now a char array 00-AA instead of bytes 0x00-0xFF - - JSONmessageBuffer[26+len]='"'; - JSONmessageBuffer[26+len+1]='}'; - JSONmessageBuffer[26+len+2]=0x00; - - Serial.print(F("payload :")); - Serial.println(JSONmessageBuffer); - - snprintf(topic, sizeof(topic), "/rfid_reader/%s", ReaderID); // generat a topic with the ReaderID - Serial.print(F("topic :")); - Serial.println(topic); - Serial.println(""); - MQTTclient.publish(topic, JSONmessageBuffer); // send it to the broker - - return 1; - -} - -/* - * Handle Mifare Classic cards - */ - -boolean RequestMifare(void){ -int i; - -char UID [21]; -char KeyOld [33]; // 16 bytes in HEX = 32 + 1 for 0x00 -char KeyNew[33]; // 16 bytes in HEX = 32 + 1 for 0x00 -byte sector = 1; -byte blockAddr = 4; // where to find the data -byte trailerBlock = 7; // block for autentification - -byte buffer[18]; // buffer for reading data -byte size = sizeof(buffer); -unsigned long KeyGen; - - Serial.println(printHex(rfid.uid.uidByte, rfid.uid.size)); // found somthing - - byte2charArray(rfid.uid.uidByte, UID, rfid.uid.size); - Serial.print(F("UID: ")); - Serial.println(UID); - - if(RFID_Mod==1){ // Timestamp enabled - - Serial.println(F("Authenticating using key A...")); - status = (MFRC522::StatusCode) rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(rfid.uid)); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("PCD_Authenticate() failed: ")); - Serial.println(rfid.GetStatusCodeName(status)); - popRFIDerror(); - return 0; - } - - // reading the first block - Serial.print(F("Reading data from block ")); Serial.print(blockAddr); - Serial.println(F(" ...")); - status = (MFRC522::StatusCode) rfid.MIFARE_Read(blockAddr, buffer, &size); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("MIFARE_Read() failed: ")); - Serial.println(rfid.GetStatusCodeName(status)); - popRFIDerror(); - rfid.PCD_PerformSelfTest(); // reset the reader - return 0; - } - else{ // OK, Card can be accesse - Serial.print(F("Data in block ")); - Serial.print(blockAddr); - Serial.println(F(":")); - dump_byte_array(buffer, 16); - - byte2charArray(buffer, KeyOld, 8); // Only the first 8 Bytes are used, otherwise the MQTT message will be too long - - KeyGen=millis(); // generate a a new time stamp - - for(i=0; i<16; i++){ // convert it to a byte array - buffer[i]=KeyGen&0xFF; - KeyGen=KeyGen/10; - } - - byte2charArray(buffer, KeyNew, 8); // Only the first 8 Bytes are used, otherwise the MQTT message will be too long - - Serial.print(F("Writing data into block ")); Serial.print(blockAddr); - Serial.println(F(" ...")); - dump_byte_array(buffer, 16); - status = (MFRC522::StatusCode) rfid.MIFARE_Write(blockAddr, buffer, 16); - if (status != MFRC522::STATUS_OK) { - Serial.print(F("MIFARE_Write() failed: ")); - Serial.println(rfid.GetStatusCodeName(status)); - popRFIDerror(); - return 0; - } - } - } - - sendUID(UID, KeyOld, KeyNew); - - return 1; -} - -/* - * This small routine starts a request for encryption. - * for details see https://www.nxp.com/docs/en/data-sheet/MF0ICU2.pdf - */ -boolean RequestAuthUltralightC(void){ -int i; - byte AuthBuffer[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // - byte AuthLength=24; - byte RndARndB[16]; - byte RndA[8]={0,0,0,0,0,0,0,0}; - byte dRndA[8]={0,0,0,0,0,0,0,0}; // decrypted RndA - byte iv_ar[8]; // this is the starting IV for decryption - // byte buffer[24]; - // byte byteCount=sizeof(buffer); - char UID [21]; - - byte2charArray(rfid.uid.uidByte, UID, rfid.uid.size); - Serial.print(F("UID: ")); - Serial.println(UID); - - - // set IV to 0x00 - for(i=0 ; i<8 ; i++){ - iv_ar[i] = 0x00; - } - memcpy(&IV,iv_ar,8); // set IV - des.set_IV(IV); - - // Build command buffer - AuthBuffer[0] = 0x1A; // CMD_3DES_AUTH -> Ultralight C 3DES Authentication. - AuthBuffer[1] = 0x00; // - - // Calculate CRC_A - status = rfid.PCD_CalculateCRC(AuthBuffer, 2, &AuthBuffer[2]); - if (status != rfid.STATUS_OK) { - return 0; - } - - AuthLength=sizeof(AuthBuffer); - - // Transmit the buffer and receive the response, validate CRC_A. - status = rfid.PCD_TransceiveData(AuthBuffer, 4, AuthBuffer, &AuthLength, NULL, 0, true); - if (status != rfid.STATUS_OK) { - Serial.println("Ultralight C Auth failed"); - Serial.println(rfid.GetStatusCodeName(status)); - return 0; - } - - memcpy(iv_ar,AuthBuffer+1,8); // use enc(RndB) as new IV for the next encryption. - - des.set_size(8); - des.tdesCbcDecipher(AuthBuffer+1,RndARndB+8); // decrypt enc(RndB) -> now we have RndB in the last 8 bytes of RndARndB - - randomSeed(AuthBuffer[1]); - int number; - for(int i=0; i<8; i++){ - number=random(255); - RndARndB[i]=number&0xFF; // write random Bytes to the first part of RndARndB - } - - rol(RndARndB+8,8); // roll the "RndB"-part of RndARndB - memcpy(RndARndB,RndA,8); // backup of RndA for later - - AuthBuffer[0] = 0xAF; // set the PCD-command - - memcpy(&IV,iv_ar,8); // set IV = to enk(RndB) for later encryption - des.set_IV(IV); - des.set_size(16); - des.tdesCbcEncipher(RndARndB, &AuthBuffer[1]); // careful! for some kind of reason RndARndB ist modified in this process - - status = rfid.PCD_CalculateCRC(AuthBuffer, 17, &AuthBuffer[17]); - if (status != rfid.STATUS_OK) { - return 0; - } - - memcpy(&IV,&AuthBuffer[9],8); // set IV to decrypt reply from PICC enc(RndA') -> RndA - des.set_IV(IV); - - status = rfid.PCD_TransceiveData(AuthBuffer, 19, AuthBuffer, &AuthLength, NULL, 0, true); - if (status != rfid.STATUS_OK) { - Serial.print(F("Auth failed failed: ")); - Serial.println(rfid.GetStatusCodeName(status)); - return 0; - } - else{ - if(AuthBuffer[0]==0x00){ // reply from PICC should start with 0x00 - des.set_size(8); - des.tdesCbcDecipher(AuthBuffer+1,dRndA); // decrypt now we have decrypted RndA' - - rol(RndA,8); // rotate orgiginal RndA to RndA' - for(i=0; i<8; i++){ // compare RndA' and dRndA - if(RndA[i] != dRndA[i]){ - i=9; - } - } - if(i==8){ - Serial.println(F("Keys match :-)")); - sendUID(UID, NULL, NULL); - } - else{ - Serial.println(F("Keys do not match")); - return 0; - } - } - else{ - Serial.println(F("Wrong answer!!!")); - return 0; - } - } - return 1; -} - -// Needed to create RndB' out of RndB -void rol(byte *data, int len){ - byte first = data[0]; - for (int i = 0; i < len-1; i++) { - data[i] = data[i+1]; - } - data[len-1] = first; -} - - - -void sendUID(char *UID, char *KeyOld, char *KeyNew){ - -char JSONmessageBuffer[200]; // contains the full JSON message -char topic[32]; - - if (Format_Mod==0){ // JSON object - if(RFID_Mod==1) // including timestamp - snprintf(JSONmessageBuffer, sizeof(JSONmessageBuffer), R"({"UID":"%s","KeyOld":"%s","KeyNew":"%s"})", UID, KeyOld, KeyNew); - else // only UID - snprintf(JSONmessageBuffer, sizeof(JSONmessageBuffer), R"({"UID":"%s"})", UID); - } - else{ // simple Text, sparated by ; - if(RFID_Mod==1) - snprintf(JSONmessageBuffer, sizeof(JSONmessageBuffer), "UID %s; KeyOld %s; KeyNew %s", UID, KeyOld, KeyNew); - else - snprintf(JSONmessageBuffer, sizeof(JSONmessageBuffer), "UID %s" , UID); - } - Serial.print(F("payload: ")); - Serial.println(JSONmessageBuffer); - - snprintf(topic, sizeof(topic), "/rfid_reader/%s", ReaderID); // generat a topic with the ReaderID - Serial.print(F("topic: ")); - Serial.println(topic); - Serial.println(""); - MQTTclient.publish(topic, JSONmessageBuffer); // send it to the broker -} - - -boolean setAuthKey(String Sdata){ -int i; -byte C_key[24]; - - for(i=0;i<32;i++){ - if(Sdata[i]==0x00){ - Serial.println(F("Key too short! (needs to be 32 digits)")); - return 0; - } - else{ - if((i%2==0)){ - C_key[i/2]=char2byte(&Sdata[i]); - } - } - } - for(i=0;i<8;i++){ - C_key[i+16]=C_key[i]; - } - des.change_key(C_key); - Serial.println(F("key set successfully!")); - return 1; -} - - - - - -/* ------------------------------------------------------------------------------------------------- - * Display stuff - */ - -/* - * Show a predefined message on the display. If the the message id is unknow, show the - * clear text message. The addText is used to provide variable information to a predefined - * text like "duration" - */ -void MessageToDisplay(int ID, String clearText, String addnText){ -String dump = ""; -String s1, s2; -int len, split=16; - - if(ID < maxMessage){ // if a predefined message is used - split=SplitAt[ID]; // look up where it should be splitted - dump += Message_Disp[ID]; // copy the predefined message - } - else{ - dump += clearText; // display the message provided as clear text - } - - if(addnText!=""){ - dump += " "; // add a space between - dump += addnText; // add a potential flexible Message like "countdown" or "Username" to the message - } - - len = dump.length(); // how long is the message? - - if(len>32) // if too long - len=32; // make it shorter - - if((len>split)&&(split>0)){ // if pre defined message is too long for a single line - s1 = dump.substring(0, split); - s2 = dump.substring(split,(len)); - } - else if(len>15){ // if a user defined message is too long for a single line - s1 = dump.substring(0, 15); - s2 = dump.substring(15,len); - } - else{ - s1 = dump.substring(0, len); // Just create a single line - } - s1 += ""; // terminate the strings properly - s2 += ""; // same for the second line. - display2lines(s1,s2); - - // save the lines in case an error needs to be prompted - lastLine1 = ""; - lastLine1 += s1; - lastLine2 = ""; - lastLine2 += s2; - linesSaved=1; -} - - -/* - * used to show reader generated status messages - */ - -void StatusToDisplay(int item){ - #ifdef ESP32 - EPaper.setFont(&FreeMonoBold18pt7b); - fsize=18; - #endif - display.setFont(ArialMT_Plain_24); - - if(item==CONNECT_TO_WIFI){ - display2lines("connecting...", "Wifi"); - } - else if (item==CONNECT_TO_MQTT){ - display2lines("connecting...", "MQTT"); - } - else if (item==PUSH_BUTTON){ - display2lines("For AP-Mode", "press button"); - } - else if(item==CONNECT_TO_LAN){ - display2lines("LAN", "connecting..."); - } - else if(item==MQTT_RFID){ - display2linesRAW("MQTT", "RFID"); - } - else if(item==IN_AP_MODE){ - display2linesRAW("AP-", "MODE"); - } - else if(item==ERROR_RFID){ - display2linesRAW("RFID-", "ERROR"); - } - else if(item==WRONG_RFID_TYPE){ - display2linesRAW("Read-", "ERROR"); - } - else if(item==ERROR_DHCP){ - display2lines("DHCP-ERROR", "pls. reboot"); - } -} - -void LastMessageDisplay(void){ - if(linesSaved){ - display.setFont(ArialMT_Plain_16); - #ifdef ESP32 - EPaper.setFont(&FreeMonoBold12pt7b); - fsize=12; - #endif - display2linesRAW(lastLine1, lastLine2); - } - else - StatusToDisplay(MQTT_RFID); -} - -void popRFIDerror(void){ - StatusToDisplay(ERROR_RFID); // show error - delay(2000); - LastMessageDisplay(); // show last message displayed -} - -/* - * Displays 2 lines of text in size 16 - */ - -void display2lines(String str1, String str2) { - display.setFont(ArialMT_Plain_16); - #ifdef ESP32 - EPaper.setFont(&FreeMonoBold12pt7b); - fsize=12; - #endif - display2linesRAW(str1, str2); -} - -/* - * Displays 2 lines of text in any size defined by the calling function - */ - -void display2linesRAW(String str1, String str2) { - display.clear(); - display.setTextAlignment(TEXT_ALIGN_CENTER); - display.drawString(64, 13, str1); - display.drawString(64, 35, str2); - display.setFont(ArialMT_Plain_10); - display.drawString(64, 0, ReaderID); // Show the reader ID on top of the screen - display.display(); - #ifdef ESP32 - EPaper.fillScreen(GxEPD_WHITE); - int x1=(EPaper.width()/2-(str1.length()*fsize)/2); - EPaper.setCursor(x1,20+2*fsize); - EPaper.println(str1); - int x2=(EPaper.width()/2-(str2.length()*fsize)/2); - EPaper.setCursor(x2,50+2*fsize); - EPaper.println(str2); - EPaper.setFont(&FreeMonoBold9pt7b); - EPaper.setCursor(EPaper.width()-8*9,12); - EPaper.print(F("ID:")); - EPaper.println(ReaderID); - EPaper.updateWindow(0, 0, EPaper.width()-1, EPaper.height()-1, true); - // EPaper.update(); - #endif -} - - -/* - * Reading data from EEPROM - */ - -void readConfig (void){ -int i=0, j=0; -int item=0; // how many items to be read -char val; - - Wifi_Ether = EEPROM.read(0); - RFID_Mod = EEPROM.read(1); - Format_Mod = EEPROM.read(2); - - - i=3; - while(i<512){ - val=EEPROM.read(i); - if(val!='\r'){ - if(item==0){ // host - ssid[j]=val; - ssid[j+1]=0x00; - } - else if(item==1){ - password[j]=val; - password[j+1]=0x00; - } - else if(item==2){ - broker[j]=val; - broker[j+1]=0x00; - } - else if(item==3){ - ReaderID[j]=val; - ReaderID[j+1]=0x00; - } - else if(item==4){ - if(val=='1') - Wifi_Ether=1; - else if(val == '0') - Wifi_Ether=0; - } - else if(item==5){ - i=512; // stop. - } - j++; - } - else if((val==0x00)||(val==0xFF)){ // momory not initialized - i=512; - } - else{ - item++; - j=0; - } - i++; - } -} - - -void char2byteArray(String in, byte *out, int len_in){ - for(int i=0; i= '0' && c <= '9') { - x *= 16; - x += c - '0'; - } - else if (c >= 'A' && c <= 'F') { - x *= 16; - x += (c - 'A') + 10; - } - else if (c >= 'a' && c <= 'f') { - x *= 16; - x += (c - 'a') + 10; - } - s++; - } - return x; -} - - - - - -// convert byte array to HEX-character array -void byte2charArray(byte *in, char *out, int len_in){ -char translate[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - - for(int i=0;i +#include + +Config::Config() +{ + EEPROM.begin(512); +} + +Config::Config(int ID, char broker[], char username[], char password[]) +{ + this->Data.ID = ID; + strcpy(this->Data.MQTT_Broker, broker); + strcpy(this->Data.MQTT_Username, username); + strcpy(this->Data.MQTT_Password, password); + + EEPROM.begin(512); +} + +void Config::Load() +{ + EEPROM.get(0, this->Data); +} + +void Config::Save() +{ + EEPROM.put(0, this->Data); + EEPROM.commit(); +} + +bool Config::IsEmpty() +{ + return this->Data.ID == 0; +} \ No newline at end of file diff --git a/src/FabReader_v2/Config.h b/src/FabReader_v2/Config.h new file mode 100644 index 0000000..0883808 --- /dev/null +++ b/src/FabReader_v2/Config.h @@ -0,0 +1,28 @@ +#ifndef CONFIG_H +#define CONFIG_H + +struct Config_Data +{ + int ID = 0; + + char MQTT_Broker[256]; + char MQTT_Username[64]; + char MQTT_Password[64]; +}; + +class Config { + public: + const char WLAN_SSID[32] = "FabReader"; + const char WLAN_Password[64] = "FabReader"; + + Config_Data Data; + + Config(); + Config(int ID, char broker[], char username[], char password[]); + + void Load(); + void Save(); + + bool IsEmpty(); +}; +#endif \ No newline at end of file diff --git a/src/FabReader_v2/Display.cpp b/src/FabReader_v2/Display.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/FabReader_v2/Display.h b/src/FabReader_v2/Display.h new file mode 100644 index 0000000..5cf31c5 --- /dev/null +++ b/src/FabReader_v2/Display.h @@ -0,0 +1,21 @@ +#ifndef DISPLAY_H +#define DISPLAY_H +enum State +{ + CONNECT_WIFI, + CONNECT_MQTT, + FREE, + INUSE, + AUTHORIZE +}; + +String Messages [] = +{ + "Connecting to WIFI ...", + "Connecting to MQTT ...", + "Free", + "In Use", + "Authorize ..." +} + +#endif \ No newline at end of file diff --git a/src/FabReader_v2/FabReader_v2.ino b/src/FabReader_v2/FabReader_v2.ino new file mode 100644 index 0000000..a106bef --- /dev/null +++ b/src/FabReader_v2/FabReader_v2.ino @@ -0,0 +1,37 @@ +#include "Config.h" +#include "Pins.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +Config config; +WiFiClient wifiClient; +PubSubClient MQTTclient; +MFRC522 rfid(PIN_RFID_SPI_SS, PIN_RFID_RST); + +void setup() +{ + Serial.begin(115200); + + pinMode(PIN_BUZZER, OUTPUT); + pinMode(PIN_BUTTON, INPUT); + pinMode(PIN_ETH_SPI_SS, OUTPUT); + digitalWrite(PIN_ETH_SPI_SS, HIGH); + + rfid.PCD_Init(); +} + +void loop() +{ + if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) + { + Serial.println(rfid.uid.sak); + } +} \ No newline at end of file diff --git a/src/FabReader_v2/NFC.cpp b/src/FabReader_v2/NFC.cpp new file mode 100644 index 0000000..e702fa4 --- /dev/null +++ b/src/FabReader_v2/NFC.cpp @@ -0,0 +1,36 @@ +#include "NFC.h" +#include + +NFC::NFC(int pin_ss, int pin_rst, PubSubClient mqtt) +{ + SPI.begin(); + + this->rfid = rfid(pin_ss, pin_rst); + this->rfid.PCD_Init(); +} + +bool NFC::hasNewCard() +{ + return this->rfid.PICC_IsNewCardPresent() && this->rfid.PICC_ReadCardSerial() + +} + +void NFC::hasActiveOTA() +{ + return this->activOTA; +} + +void NFC::startOTA() +{ + // TODO +} + +void NFC::continueOTA() +{ + // TODO +} + +void NFC::cancelOTA() +{ + +} \ No newline at end of file diff --git a/src/FabReader_v2/NFC.h b/src/FabReader_v2/NFC.h new file mode 100644 index 0000000..d6dc953 --- /dev/null +++ b/src/FabReader_v2/NFC.h @@ -0,0 +1,24 @@ +#ifndef NFC_H +#define NFC_H + +#include +#include + +class NFC_H +{ + private: + MFRC522 rfid; + PubSubClient* mqtt; + bool activOTA = false; + + public: + NFC(int pin_ss, int pin_rst, PubSubClient* mqtt); + bool hasNewCard(); + void hasActiveOTA(); + + void startOTA(); + void continueOTA(); + void cancelOTA(); +} + +#endif \ No newline at end of file diff --git a/src/FabReader_v2/Pins.h b/src/FabReader_v2/Pins.h new file mode 100644 index 0000000..f6e195f --- /dev/null +++ b/src/FabReader_v2/Pins.h @@ -0,0 +1,18 @@ +#ifndef PINS_H +#define PINS_H + +// Pins for ESP8266 +#define PIN_SDA 5 +#define PIN_SCL 4 + +#define PIN_SPI_MOSI 13 +#define PIN_SPI_MISO 12 +#define PIN_SPI_SCK 14 + +#define PIN_RFID_RST 0 +#define PIN_RFID_SPI_SS 2 +#define PIN_ETH_SPI_SS 15 + +#define PIN_BUZZER 16 +#define PIN_BUTTON A0 +#endif \ No newline at end of file diff --git a/src/FabReader_v2/Website.h b/src/FabReader_v2/Website.h new file mode 100644 index 0000000..6a0e3e2 --- /dev/null +++ b/src/FabReader_v2/Website.h @@ -0,0 +1,60 @@ +#ifndef WEBSITE_H +#define WEBSITE_H +const struct Website +{ + const char INDEX[] = + "" + "" + "" + "" + "" + "Verbindungsdaten RFID-Reader" + "" + "" + "" + "

Verbindungsdaten RFID-Reader

" + "
" + "

" + "
" + "
" + "
" + "
" + "Connection
" + "Ehternet
" + "WiFi
" + "RFID-Type
" + "Mifare Classic
" + "Mifare Classic + Timestamp
" + "Mifare DESFire
" + "Mifar Ultralight C
" + "Data Package Format
" + "JSON
" + "Text
" + " " + "

" + "
" + "" + ""; + + const char SAVED[] = + "" + "" + "" + "" + "" + "Verbindungsdaten RFID-Reader" + "" + "" + "" + "

Saved

" + "

go back

" + "" + ""; + }; +#endif \ No newline at end of file