From e54ae5d721d6a5497b0d7fd9297d4ce082369b8c Mon Sep 17 00:00:00 2001 From: Rennan Cockles Date: Tue, 7 Jan 2025 21:40:30 -0300 Subject: [PATCH 1/6] move wigle files into gps folder --- src/core/sd_functions.cpp | 4 ++-- src/modules/{wifi => gps}/wigle.cpp | 0 src/modules/{wifi => gps}/wigle.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/modules/{wifi => gps}/wigle.cpp (100%) rename src/modules/{wifi => gps}/wigle.h (100%) diff --git a/src/core/sd_functions.cpp b/src/core/sd_functions.cpp index 9d8638ea..7c6a1e23 100644 --- a/src/core/sd_functions.cpp +++ b/src/core/sd_functions.cpp @@ -9,7 +9,7 @@ #include "modules/rf/rf.h" #include "modules/ir/TV-B-Gone.h" #include "modules/ir/custom_ir.h" -#include "modules/wifi/wigle.h" +#include "modules/gps/wigle.h" #include "modules/others/bad_usb.h" #include "modules/others/qrcode_menu.h" #include "modules/bjs_interpreter/interpreter.h" @@ -498,7 +498,7 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) { displayScrollingText(fileList[index].filename, coord); #ifdef HAS_KEYBOARD - const short PAGE_JUMP_SIZE = 5; + const short PAGE_JUMP_SIZE = 5; char pressed_letter = checkLetterShortcutPress(); if(check(EscPress)) goto BACK_FOLDER; // quit diff --git a/src/modules/wifi/wigle.cpp b/src/modules/gps/wigle.cpp similarity index 100% rename from src/modules/wifi/wigle.cpp rename to src/modules/gps/wigle.cpp diff --git a/src/modules/wifi/wigle.h b/src/modules/gps/wigle.h similarity index 100% rename from src/modules/wifi/wigle.h rename to src/modules/gps/wigle.h From f368dd190badafbb6b36d9c51c130672b39d2e37 Mon Sep 17 00:00:00 2001 From: Rennan Cockles Date: Tue, 7 Jan 2025 22:32:39 -0300 Subject: [PATCH 2/6] add rootPath parameter to loopSD and new function createNewFile --- src/core/sd_functions.cpp | 27 ++++++++++++++++++++++++--- src/core/sd_functions.h | 4 +++- src/modules/rfid/PN532.cpp | 10 ++-------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/core/sd_functions.cpp b/src/core/sd_functions.cpp index 7c6a1e23..fde76492 100644 --- a/src/core/sd_functions.cpp +++ b/src/core/sd_functions.cpp @@ -445,15 +445,15 @@ void readFs(FS fs, String folder, String allowed_ext) { ** Function: loopSD ** Where you choose what to do with your SD Files **********************************************************************/ -String loopSD(FS &fs, bool filePicker, String allowed_ext) { +String loopSD(FS &fs, bool filePicker, String allowed_ext, String rootPath) { Opt_Coord coord; String result = ""; bool reload=false; bool redraw = true; int index = 0; int maxFiles = 0; - String Folder = "/"; - String PreFolder = "/"; + String Folder = rootPath; + String PreFolder = rootPath; tft.fillScreen(bruceConfig.bgColor); tft.drawRoundRect(5,5,tftWidth-10,tftHeight-10,5,bruceConfig.priColor); if(&fs==&SD) { @@ -834,3 +834,24 @@ void fileInfo(FS fs, String filepath) { return; } + +/********************************************************************* +** Function: createNewFile +** Function will save a file into FS. If file already exists it will +** append a version number to the file name. +**********************************************************************/ +File createNewFile(FS *&fs, String filepath) { + int extIndex = filepath.lastIndexOf('.'); + String filename = filepath.substring(0, extIndex); + String ext = filepath.substring(extIndex); + + if ((*fs).exists(filename + ext)) { + int i = 1; + filename += "_"; + while((*fs).exists(filename + String(i) + ext)) i++; + filename += String(i); + } + + File file = (*fs).open(filename + ext, FILE_WRITE); + return file; +} diff --git a/src/core/sd_functions.h b/src/core/sd_functions.h index 77fac02d..77ff3404 100644 --- a/src/core/sd_functions.h +++ b/src/core/sd_functions.h @@ -44,7 +44,7 @@ void readFs(FS fs, String folder, String allowed_ext = "*"); bool sortList(const FileList& a, const FileList& b); -String loopSD(FS &fs, bool filePicker = false, String allowed_ext = "*"); +String loopSD(FS &fs, bool filePicker = false, String allowed_ext = "*", String rootPath = "/"); void viewFile(FS fs, String filepath); @@ -56,4 +56,6 @@ bool getFsStorage(FS *&fs); void fileInfo(FS fs, String filepath); +File createNewFile(FS *&fs, String filepath); + #endif \ No newline at end of file diff --git a/src/modules/rfid/PN532.cpp b/src/modules/rfid/PN532.cpp index 1648d871..7ec6f2de 100644 --- a/src/modules/rfid/PN532.cpp +++ b/src/modules/rfid/PN532.cpp @@ -92,7 +92,7 @@ int PN532::load() { FS *fs; if(!getFsStorage(fs)) return FAILURE; - filepath = loopSD(*fs, true, "RFID|NFC"); + filepath = loopSD(*fs, true, "RFID|NFC", "/BruceRFID"); file = fs->open(filepath, FILE_READ); if (!file) { @@ -129,13 +129,7 @@ int PN532::save(String filename) { if(!getFsStorage(fs)) return FAILURE; if (!(*fs).exists("/BruceRFID")) (*fs).mkdir("/BruceRFID"); - if ((*fs).exists("/BruceRFID/" + filename + ".rfid")) { - int i = 1; - filename += "_"; - while((*fs).exists("/BruceRFID/" + filename + String(i) + ".rfid")) i++; - filename += String(i); - } - File file = (*fs).open("/BruceRFID/"+ filename + ".rfid", FILE_WRITE); + File file = createNewFile(fs, "/BruceRFID/" + filename + ".rfid"); if(!file) { return FAILURE; From f79cb5ae65abe1588f182be12d34c3b7698c7306 Mon Sep 17 00:00:00 2001 From: Rennan Cockles Date: Thu, 9 Jan 2025 10:21:12 -0300 Subject: [PATCH 3/6] using multiple keys for mifare classic --- src/modules/rfid/PN532.cpp | 105 ++++++++++++++++--------------- src/modules/rfid/PN532.h | 7 ++- src/modules/rfid/RFID2.cpp | 100 +++++++++++++++-------------- src/modules/rfid/RFID2.h | 5 +- src/modules/rfid/tag_o_matic.cpp | 18 +++--- 5 files changed, 122 insertions(+), 113 deletions(-) diff --git a/src/modules/rfid/PN532.cpp b/src/modules/rfid/PN532.cpp index 7ec6f2de..aa9b7271 100644 --- a/src/modules/rfid/PN532.cpp +++ b/src/modules/rfid/PN532.cpp @@ -236,7 +236,6 @@ bool PN532::read_data_blocks() { dataPages = 0; totalPages = 0; bool readSuccess = false; - uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; strAllPages = ""; @@ -244,7 +243,7 @@ bool PN532::read_data_blocks() { case PICC_TYPE_MIFARE_MINI: case PICC_TYPE_MIFARE_1K: case PICC_TYPE_MIFARE_4K: - readSuccess = read_mifare_classic_data_blocks(keya); + readSuccess = read_mifare_classic_data_blocks(); break; case PICC_TYPE_MIFARE_UL: @@ -259,7 +258,7 @@ bool PN532::read_data_blocks() { return readSuccess; } -bool PN532::read_mifare_classic_data_blocks(uint8_t *key) { +bool PN532::read_mifare_classic_data_blocks() { byte no_of_sectors = 0; bool sectorReadSuccess; @@ -285,24 +284,16 @@ bool PN532::read_mifare_classic_data_blocks(uint8_t *key) { if (no_of_sectors) { for (int8_t i = 0; i < no_of_sectors; i++) { - sectorReadSuccess = read_mifare_classic_data_sector(key, i); + sectorReadSuccess = read_mifare_classic_data_sector(i); if (!sectorReadSuccess) break; } } return sectorReadSuccess; } -bool PN532::read_mifare_classic_data_sector(uint8_t *key, byte sector) { - uint8_t success; +bool PN532::read_mifare_classic_data_sector(byte sector) { byte firstBlock; byte no_of_blocks; - bool isSectorTrailer; - byte c1, c2, c3; - byte c1_, c2_, c3_; - bool invertedError; - byte g[4]; - byte group; - bool firstInGroup; if (sector < 32) { no_of_blocks = 4; @@ -318,49 +309,20 @@ bool PN532::read_mifare_classic_data_sector(uint8_t *key, byte sector) { byte buffer[18]; byte blockAddr; - isSectorTrailer = true; String strPage; + if (!authenticate_mifare_classic(firstBlock)) return false; + for (int8_t blockOffset = 0; blockOffset < no_of_blocks; blockOffset++) { strPage = ""; blockAddr = firstBlock + blockOffset; - if (isSectorTrailer) { - success = nfc.mifareclassic_AuthenticateBlock(uid.uidByte, uid.size, firstBlock, 0, key); - if (!success) { - return false; - } - } - success = nfc.mifareclassic_ReadDataBlock(blockAddr, buffer); - if (!success) { - return false; - } + + if (!nfc.mifareclassic_ReadDataBlock(blockAddr, buffer)) return false; + for (byte index = 0; index < 16; index++) { strPage += buffer[index] < 0x10 ? F(" 0") : F(" "); strPage += String(buffer[index], HEX); } - if (isSectorTrailer) { - c1 = buffer[7] >> 4; - c2 = buffer[8] & 0xF; - c3 = buffer[8] >> 4; - c1_ = buffer[6] & 0xF; - c2_ = buffer[6] >> 4; - c3_ = buffer[7] & 0xF; - invertedError = (c1 != (~c1_ & 0xF)) || (c2 != (~c2_ & 0xF)) || (c3 != (~c3_ & 0xF)); - g[0] = ((c1 & 1) << 2) | ((c2 & 1) << 1) | ((c3 & 1) << 0); - g[1] = ((c1 & 2) << 1) | ((c2 & 2) << 0) | ((c3 & 2) >> 1); - g[2] = ((c1 & 4) << 0) | ((c2 & 4) >> 1) | ((c3 & 4) >> 2); - g[3] = ((c1 & 8) >> 1) | ((c2 & 8) >> 2) | ((c3 & 8) >> 3); - isSectorTrailer = false; - } - - if (no_of_blocks == 4) { - group = blockOffset; - firstInGroup = true; - } - else { - group = blockOffset / 5; - firstInGroup = (group == 3) || (group != (blockOffset + 1) / 5); - } strPage.trim(); strPage.toUpperCase(); @@ -372,6 +334,49 @@ bool PN532::read_mifare_classic_data_sector(uint8_t *key, byte sector) { return true; } +bool PN532::authenticate_mifare_classic(byte block) { + uint8_t successA = 0; + uint8_t successB = 0; + + uint8_t keys[][6] = { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, + { 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5 }, + { 0x4D, 0x3A, 0x99, 0xC3, 0x51, 0xDD }, + { 0x1A, 0x98, 0x2C, 0x7E, 0x45, 0x9A }, + { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, + { 0x71, 0x4C, 0x5C, 0x88, 0x6E, 0x97 }, + { 0x58, 0x7E, 0xE5, 0xF9, 0x35, 0x0F }, + { 0xA0, 0x47, 0x8C, 0xC3, 0x90, 0x91 }, + { 0x53, 0x3C, 0xB6, 0xC7, 0x23, 0xF6 }, + { 0x8F, 0xD0, 0xA4, 0xF2, 0x56, 0xE9 }, + { 0xA6, 0x45, 0x98, 0xA7, 0x74, 0x78 }, + { 0x26, 0x94, 0x0B, 0x21, 0xFF, 0x5D }, + { 0xFC, 0x00, 0x01, 0x87, 0x78, 0xF7 }, + { 0x00, 0x00, 0x0F, 0xFE, 0x24, 0x88 } + }; + + for (auto key : keys) { + successA = nfc.mifareclassic_AuthenticateBlock(uid.uidByte, uid.size, block, 0, key); + if (successA) break; + + if (!nfc.startPassiveTargetIDDetection() || !nfc.readDetectedPassiveTargetID()) { + return false; + } + } + + for (auto key : keys) { + successB = nfc.mifareclassic_AuthenticateBlock(uid.uidByte, uid.size, block, 1, key); + if (successB) break; + + if (!nfc.startPassiveTargetIDDetection() || !nfc.readDetectedPassiveTargetID()) { + return false; + } + } + + return (successA && successB); +} + bool PN532::read_mifare_ultralight_data_blocks() { uint8_t success; byte buffer[18]; @@ -478,11 +483,7 @@ bool PN532::write_mifare_classic_data_block(int block, String data) { buffer[i / 2] = strtoul(data.substring(i, i + 2).c_str(), NULL, 16); } - uint8_t key[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - - - uint8_t success = nfc.mifareclassic_AuthenticateBlock(uid.uidByte, uid.size, block, 0, key); - if (!success) return false; + if (!authenticate_mifare_classic(block)) return false; return nfc.mifareclassic_WriteDataBlock(block, buffer); } diff --git a/src/modules/rfid/PN532.h b/src/modules/rfid/PN532.h index 6ce216d7..81e6a58b 100644 --- a/src/modules/rfid/PN532.h +++ b/src/modules/rfid/PN532.h @@ -23,7 +23,7 @@ class PN532 : public RFIDInterface { // If using other device that uses, set -DPN532_IRQ=pin_num and -DPN532_RF_REST=pin_num to platformio.ini // of this particular device, should not be used in other devices on I2C mode #if defined(PN532_IRQ) && defined(PN532_RF_REST) - Adafruit_PN532 nfc = Adafruit_PN532(PN532_IRQ,PN532_RF_REST); + Adafruit_PN532 nfc = Adafruit_PN532(PN532_IRQ,PN532_RF_REST); #else Adafruit_PN532 nfc = Adafruit_PN532(); #endif @@ -64,8 +64,9 @@ class PN532 : public RFIDInterface { ///////////////////////////////////////////////////////////////////////////////////// String get_tag_type(); bool read_data_blocks(); - bool read_mifare_classic_data_blocks(uint8_t *key); - bool read_mifare_classic_data_sector(uint8_t *key, byte sector); + bool read_mifare_classic_data_blocks(); + bool read_mifare_classic_data_sector(byte sector); + bool authenticate_mifare_classic(byte block); bool read_mifare_ultralight_data_blocks(); int write_data_blocks(); diff --git a/src/modules/rfid/RFID2.cpp b/src/modules/rfid/RFID2.cpp index 2ef2aeca..98465d62 100644 --- a/src/modules/rfid/RFID2.cpp +++ b/src/modules/rfid/RFID2.cpp @@ -253,7 +253,6 @@ bool RFID2::read_data_blocks() { dataPages = 0; totalPages = 0; bool readSuccess = false; - MFRC522::MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); strAllPages = ""; @@ -261,7 +260,7 @@ bool RFID2::read_data_blocks() { case MFRC522::PICC_TYPE_MIFARE_MINI: case MFRC522::PICC_TYPE_MIFARE_1K: case MFRC522::PICC_TYPE_MIFARE_4K: - readSuccess = read_mifare_classic_data_blocks(piccType, &key); + readSuccess = read_mifare_classic_data_blocks(piccType); break; case MFRC522::PICC_TYPE_MIFARE_UL: @@ -278,7 +277,7 @@ bool RFID2::read_data_blocks() { return readSuccess; } -bool RFID2::read_mifare_classic_data_blocks(byte piccType, MFRC522::MIFARE_Key *key) { +bool RFID2::read_mifare_classic_data_blocks(byte piccType) { byte no_of_sectors = 0; bool sectorReadSuccess; @@ -304,7 +303,7 @@ bool RFID2::read_mifare_classic_data_blocks(byte piccType, MFRC522::MIFARE_Key * if (no_of_sectors) { for (int8_t i = 0; i < no_of_sectors; i++) { - sectorReadSuccess = read_mifare_classic_data_sector(key, i); + sectorReadSuccess = read_mifare_classic_data_sector(i); if (!sectorReadSuccess) break; } } @@ -313,17 +312,10 @@ bool RFID2::read_mifare_classic_data_blocks(byte piccType, MFRC522::MIFARE_Key * return sectorReadSuccess; } -bool RFID2::read_mifare_classic_data_sector(MFRC522::MIFARE_Key *key, byte sector) { +bool RFID2::read_mifare_classic_data_sector(byte sector) { byte status; byte firstBlock; byte no_of_blocks; - bool isSectorTrailer; - byte c1, c2, c3; - byte c1_, c2_, c3_; - bool invertedError; - byte g[4]; - byte group; - bool firstInGroup; if (sector < 32) { no_of_blocks = 4; @@ -340,50 +332,24 @@ bool RFID2::read_mifare_classic_data_sector(MFRC522::MIFARE_Key *key, byte secto byte byteCount; byte buffer[18]; byte blockAddr; - isSectorTrailer = true; String strPage; + if (!authenticate_mifare_classic(firstBlock)) return false; + for (int8_t blockOffset = 0; blockOffset < no_of_blocks; blockOffset++) { strPage = ""; blockAddr = firstBlock + blockOffset; - if (isSectorTrailer) { - status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, firstBlock, key, &mfrc522.uid); - if (status != MFRC522::STATUS_OK) { - return false; - } - } byteCount = sizeof(buffer); + status = mfrc522.MIFARE_Read(blockAddr, buffer, &byteCount); if (status != MFRC522::STATUS_OK) { return false; } + for (byte index = 0; index < 16; index++) { strPage += buffer[index] < 0x10 ? F(" 0") : F(" "); strPage += String(buffer[index], HEX); } - if (isSectorTrailer) { - c1 = buffer[7] >> 4; - c2 = buffer[8] & 0xF; - c3 = buffer[8] >> 4; - c1_ = buffer[6] & 0xF; - c2_ = buffer[6] >> 4; - c3_ = buffer[7] & 0xF; - invertedError = (c1 != (~c1_ & 0xF)) || (c2 != (~c2_ & 0xF)) || (c3 != (~c3_ & 0xF)); - g[0] = ((c1 & 1) << 2) | ((c2 & 1) << 1) | ((c3 & 1) << 0); - g[1] = ((c1 & 2) << 1) | ((c2 & 2) << 0) | ((c3 & 2) >> 1); - g[2] = ((c1 & 4) << 0) | ((c2 & 4) >> 1) | ((c3 & 4) >> 2); - g[3] = ((c1 & 8) >> 1) | ((c2 & 8) >> 2) | ((c3 & 8) >> 3); - isSectorTrailer = false; - } - - if (no_of_blocks == 4) { - group = blockOffset; - firstInGroup = true; - } - else { - group = blockOffset / 5; - firstInGroup = (group == 3) || (group != (blockOffset + 1) / 5); - } strPage.trim(); strPage.toUpperCase(); @@ -395,6 +361,49 @@ bool RFID2::read_mifare_classic_data_sector(MFRC522::MIFARE_Key *key, byte secto return true; } +bool RFID2::authenticate_mifare_classic(byte block) { + byte statusA = 0; + byte statusB = 0; + + MFRC522::MIFARE_Key keys[][6] = { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, + { 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5 }, + { 0x4D, 0x3A, 0x99, 0xC3, 0x51, 0xDD }, + { 0x1A, 0x98, 0x2C, 0x7E, 0x45, 0x9A }, + { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, + { 0x71, 0x4C, 0x5C, 0x88, 0x6E, 0x97 }, + { 0x58, 0x7E, 0xE5, 0xF9, 0x35, 0x0F }, + { 0xA0, 0x47, 0x8C, 0xC3, 0x90, 0x91 }, + { 0x53, 0x3C, 0xB6, 0xC7, 0x23, 0xF6 }, + { 0x8F, 0xD0, 0xA4, 0xF2, 0x56, 0xE9 }, + { 0xA6, 0x45, 0x98, 0xA7, 0x74, 0x78 }, + { 0x26, 0x94, 0x0B, 0x21, 0xFF, 0x5D }, + { 0xFC, 0x00, 0x01, 0x87, 0x78, 0xF7 }, + { 0x00, 0x00, 0x0F, 0xFE, 0x24, 0x88 } + }; + + for (auto key : keys) { + statusA = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, key, &mfrc522.uid); + if (statusA == MFRC522::STATUS_OK) break; + + if (!PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) { + return false; + } + } + + for (auto key : keys) { + statusB = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, block, key, &mfrc522.uid); + if (statusB == MFRC522::STATUS_OK) break; + + if (!PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) { + return false; + } + } + + return (statusA == MFRC522::STATUS_OK && statusB == MFRC522::STATUS_OK); +} + bool RFID2::read_mifare_ultralight_data_blocks() { byte status; byte byteCount; @@ -501,12 +510,9 @@ bool RFID2::write_mifare_classic_data_block(int block, String data) { buffer[i / 2] = strtoul(data.substring(i, i + 2).c_str(), NULL, 16); } - MFRC522::MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - - byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid)); - if (status != MFRC522::STATUS_OK) return false; + if (!authenticate_mifare_classic(block)) return false; - status = mfrc522.MIFARE_Write((byte)block, buffer, size); + byte status = mfrc522.MIFARE_Write((byte)block, buffer, size); if (status != MFRC522::STATUS_OK) return false; return true; diff --git a/src/modules/rfid/RFID2.h b/src/modules/rfid/RFID2.h index 95be4ec6..04057abc 100644 --- a/src/modules/rfid/RFID2.h +++ b/src/modules/rfid/RFID2.h @@ -50,8 +50,9 @@ class RFID2 : public RFIDInterface { String get_tag_type(); bool read_data_blocks(); - bool read_mifare_classic_data_blocks(byte piccType, MFRC522::MIFARE_Key *key); - bool read_mifare_classic_data_sector(MFRC522::MIFARE_Key *key, byte sector); + bool read_mifare_classic_data_blocks(byte piccType); + bool read_mifare_classic_data_sector(byte sector); + bool authenticate_mifare_classic(byte block); bool read_mifare_ultralight_data_blocks(); int write_data_blocks(); diff --git a/src/modules/rfid/tag_o_matic.cpp b/src/modules/rfid/tag_o_matic.cpp index dbd50a1c..c3f1a8b6 100644 --- a/src/modules/rfid/tag_o_matic.cpp +++ b/src/modules/rfid/tag_o_matic.cpp @@ -115,16 +115,16 @@ void TagOMatic::loop() { void TagOMatic::select_state() { options = {}; if (_read_uid) { - options.push_back({"Clone UID", [=]() { set_state(CLONE_MODE); }}); - options.push_back({"Custom UID", [=]() { set_state(CUSTOM_UID_MODE); }}); - options.push_back({"Write data", [=]() { set_state(WRITE_MODE); }}); - options.push_back({"Save file", [=]() { set_state(SAVE_MODE); }}); + options.emplace_back("Clone UID", [=]() { set_state(CLONE_MODE); }); + options.emplace_back("Custom UID", [=]() { set_state(CUSTOM_UID_MODE); }); + options.emplace_back("Write data", [=]() { set_state(WRITE_MODE); }); + options.emplace_back("Save file", [=]() { set_state(SAVE_MODE); }); } - options.push_back({"Read tag", [=]() { set_state(READ_MODE); }}); - options.push_back({"Scan tags", [=]() { set_state(SCAN_MODE); }}); - options.push_back({"Load file", [=]() { set_state(LOAD_MODE); }}); - options.push_back({"Write NDEF", [=]() { set_state(WRITE_NDEF_MODE); }}); - options.push_back({"Erase tag", [=]() { set_state(ERASE_MODE); }}); + options.emplace_back("Read tag", [=]() { set_state(READ_MODE); }); + options.emplace_back("Scan tags", [=]() { set_state(SCAN_MODE); }); + options.emplace_back("Load file", [=]() { set_state(LOAD_MODE); }); + options.emplace_back("Write NDEF", [=]() { set_state(WRITE_NDEF_MODE); }); + options.emplace_back("Erase tag", [=]() { set_state(ERASE_MODE); }); loopOptions(options); } From 740cbc828b99af2cb99975ec19ae5008159e19a4 Mon Sep 17 00:00:00 2001 From: Rennan Cockles Date: Thu, 9 Jan 2025 13:34:02 -0300 Subject: [PATCH 4/6] extend mifare keys from bruce.conf --- src/core/config.cpp | 17 +++++++++++++++++ src/core/config.h | 3 +++ src/modules/rfid/PN532.cpp | 34 ++++++++++++++++++++++++++++++++++ src/modules/rfid/RFID2.cpp | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/src/core/config.cpp b/src/core/config.cpp index 686c5a0c..34d361b7 100644 --- a/src/core/config.cpp +++ b/src/core/config.cpp @@ -45,6 +45,9 @@ JsonDocument BruceConfig::toJson() const { setting["rfidModule"] = rfidModule; + JsonArray _mifareKeys = setting.createNestedArray("mifareKeys"); + for (auto key : mifareKeys) _mifareKeys.add(key); + setting["gpsBaudrate"] = gpsBaudrate; setting["startupApp"] = startupApp; @@ -134,6 +137,11 @@ void BruceConfig::fromFile() { if(!setting["rfScanRange"].isNull()) { rfScanRange = setting["rfScanRange"].as(); } else { count++; log_e("Fail"); } if(!setting["rfidModule"].isNull()) { rfidModule = setting["rfidModule"].as(); } else { count++; log_e("Fail"); } + if(!setting["mifareKeys"].isNull()) { + mifareKeys.clear(); + JsonArray _mifareKeys = setting["mifareKeys"].as(); + for (JsonVariant key : _mifareKeys) mifareKeys.insert(key.as()); + } else { count++; log_e("Fail"); } if(!setting["gpsBaudrate"].isNull()) { gpsBaudrate = setting["gpsBaudrate"].as(); } else { count++; log_e("Fail"); } @@ -205,6 +213,7 @@ void BruceConfig::validateConfig() { validateRfScanRangeValue(); validateRfModuleValue(); validateRfidModuleValue(); + validateMifareKeysItems(); validateGpsBaudrateValue(); validateDevModeValue(); } @@ -432,6 +441,14 @@ void BruceConfig::validateRfidModuleValue() { } +void BruceConfig::validateMifareKeysItems() { + for (auto key = mifareKeys.begin(); key != mifareKeys.end();) { + if (key->length() != 12) key = mifareKeys.erase(key); + else ++key; + } +} + + void BruceConfig::setGpsBaudrate(int value) { gpsBaudrate = value; validateGpsBaudrateValue(); diff --git a/src/core/config.h b/src/core/config.h index 0c309c13..3c67c7f4 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -6,6 +6,7 @@ #include #include #include +#include #define DEFAULT_PRICOLOR 0xA80F @@ -74,6 +75,7 @@ class BruceConfig { // RFID int rfidModule = M5_RFID2_MODULE; + std::set mifareKeys = {}; // GPS int gpsBaudrate = 9600; @@ -155,6 +157,7 @@ class BruceConfig { // RFID void setRfidModule(RFIDModules value); void validateRfidModuleValue(); + void validateMifareKeysItems(); // GPS void setGpsBaudrate(int value); diff --git a/src/modules/rfid/PN532.cpp b/src/modules/rfid/PN532.cpp index aa9b7271..086e994f 100644 --- a/src/modules/rfid/PN532.cpp +++ b/src/modules/rfid/PN532.cpp @@ -365,6 +365,23 @@ bool PN532::authenticate_mifare_classic(byte block) { } } + if (!successA) { + uint8_t keyA[6]; + + for (const auto& mifKey : bruceConfig.mifareKeys) { + for (size_t i = 0; i < mifKey.length(); i += 2) { + keyA[i/2] = strtoul(mifKey.substring(i, i + 2).c_str(), NULL, 16); + } + + successA = nfc.mifareclassic_AuthenticateBlock(uid.uidByte, uid.size, block, 0, keyA); + if (successA) break; + + if (!nfc.startPassiveTargetIDDetection() || !nfc.readDetectedPassiveTargetID()) { + return false; + } + } + } + for (auto key : keys) { successB = nfc.mifareclassic_AuthenticateBlock(uid.uidByte, uid.size, block, 1, key); if (successB) break; @@ -374,6 +391,23 @@ bool PN532::authenticate_mifare_classic(byte block) { } } + if (!successB) { + uint8_t keyB[6]; + + for (const auto& mifKey : bruceConfig.mifareKeys) { + for (size_t i = 0; i < mifKey.length(); i += 2) { + keyB[i/2] = strtoul(mifKey.substring(i, i + 2).c_str(), NULL, 16); + } + + successB = nfc.mifareclassic_AuthenticateBlock(uid.uidByte, uid.size, block, 1, keyB); + if (successB) break; + + if (!nfc.startPassiveTargetIDDetection() || !nfc.readDetectedPassiveTargetID()) { + return false; + } + } + } + return (successA && successB); } diff --git a/src/modules/rfid/RFID2.cpp b/src/modules/rfid/RFID2.cpp index 98465d62..d6caa65f 100644 --- a/src/modules/rfid/RFID2.cpp +++ b/src/modules/rfid/RFID2.cpp @@ -392,6 +392,23 @@ bool RFID2::authenticate_mifare_classic(byte block) { } } + if (statusA != MFRC522::STATUS_OK) { + MFRC522::MIFARE_Key keyA; + + for (const auto& mifKey : bruceConfig.mifareKeys) { + for (size_t i = 0; i < mifKey.length(); i += 2) { + keyA.keyByte[i/2] = strtoul(mifKey.substring(i, i + 2).c_str(), NULL, 16); + } + + statusA = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &keyA, &mfrc522.uid); + if (statusA == MFRC522::STATUS_OK) break; + + if (!PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) { + return false; + } + } + } + for (auto key : keys) { statusB = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, block, key, &mfrc522.uid); if (statusB == MFRC522::STATUS_OK) break; @@ -401,6 +418,23 @@ bool RFID2::authenticate_mifare_classic(byte block) { } } + if (statusB != MFRC522::STATUS_OK) { + MFRC522::MIFARE_Key keyB; + + for (const auto& mifKey : bruceConfig.mifareKeys) { + for (size_t i = 0; i < mifKey.length(); i += 2) { + keyB.keyByte[i/2] = strtoul(mifKey.substring(i, i + 2).c_str(), NULL, 16); + } + + statusB = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &keyB, &mfrc522.uid); + if (statusB == MFRC522::STATUS_OK) break; + + if (!PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) { + return false; + } + } + } + return (statusA == MFRC522::STATUS_OK && statusB == MFRC522::STATUS_OK); } From c4b7e01fdea71f66942c7295372ab9bcac27313d Mon Sep 17 00:00:00 2001 From: Rennan Cockles Date: Thu, 9 Jan 2025 14:28:30 -0300 Subject: [PATCH 5/6] centralize keys into RFIDInterface --- src/modules/rfid/PN532.cpp | 18 ------------------ src/modules/rfid/RFID2.cpp | 31 ++++++++----------------------- src/modules/rfid/RFIDInterface.h | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/modules/rfid/PN532.cpp b/src/modules/rfid/PN532.cpp index 086e994f..c58412b1 100644 --- a/src/modules/rfid/PN532.cpp +++ b/src/modules/rfid/PN532.cpp @@ -338,24 +338,6 @@ bool PN532::authenticate_mifare_classic(byte block) { uint8_t successA = 0; uint8_t successB = 0; - uint8_t keys[][6] = { - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, - { 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5 }, - { 0x4D, 0x3A, 0x99, 0xC3, 0x51, 0xDD }, - { 0x1A, 0x98, 0x2C, 0x7E, 0x45, 0x9A }, - { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, - { 0x71, 0x4C, 0x5C, 0x88, 0x6E, 0x97 }, - { 0x58, 0x7E, 0xE5, 0xF9, 0x35, 0x0F }, - { 0xA0, 0x47, 0x8C, 0xC3, 0x90, 0x91 }, - { 0x53, 0x3C, 0xB6, 0xC7, 0x23, 0xF6 }, - { 0x8F, 0xD0, 0xA4, 0xF2, 0x56, 0xE9 }, - { 0xA6, 0x45, 0x98, 0xA7, 0x74, 0x78 }, - { 0x26, 0x94, 0x0B, 0x21, 0xFF, 0x5D }, - { 0xFC, 0x00, 0x01, 0x87, 0x78, 0xF7 }, - { 0x00, 0x00, 0x0F, 0xFE, 0x24, 0x88 } - }; - for (auto key : keys) { successA = nfc.mifareclassic_AuthenticateBlock(uid.uidByte, uid.size, block, 0, key); if (successA) break; diff --git a/src/modules/rfid/RFID2.cpp b/src/modules/rfid/RFID2.cpp index d6caa65f..cd9047ae 100644 --- a/src/modules/rfid/RFID2.cpp +++ b/src/modules/rfid/RFID2.cpp @@ -365,26 +365,13 @@ bool RFID2::authenticate_mifare_classic(byte block) { byte statusA = 0; byte statusB = 0; - MFRC522::MIFARE_Key keys[][6] = { - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, - { 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5 }, - { 0x4D, 0x3A, 0x99, 0xC3, 0x51, 0xDD }, - { 0x1A, 0x98, 0x2C, 0x7E, 0x45, 0x9A }, - { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, - { 0x71, 0x4C, 0x5C, 0x88, 0x6E, 0x97 }, - { 0x58, 0x7E, 0xE5, 0xF9, 0x35, 0x0F }, - { 0xA0, 0x47, 0x8C, 0xC3, 0x90, 0x91 }, - { 0x53, 0x3C, 0xB6, 0xC7, 0x23, 0xF6 }, - { 0x8F, 0xD0, 0xA4, 0xF2, 0x56, 0xE9 }, - { 0xA6, 0x45, 0x98, 0xA7, 0x74, 0x78 }, - { 0x26, 0x94, 0x0B, 0x21, 0xFF, 0x5D }, - { 0xFC, 0x00, 0x01, 0x87, 0x78, 0xF7 }, - { 0x00, 0x00, 0x0F, 0xFE, 0x24, 0x88 } - }; + MFRC522::MIFARE_Key keyA; + MFRC522::MIFARE_Key keyB; for (auto key : keys) { - statusA = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, key, &mfrc522.uid); + memcpy(keyA.keyByte, key, 6); + + statusA = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &keyA, &mfrc522.uid); if (statusA == MFRC522::STATUS_OK) break; if (!PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) { @@ -393,8 +380,6 @@ bool RFID2::authenticate_mifare_classic(byte block) { } if (statusA != MFRC522::STATUS_OK) { - MFRC522::MIFARE_Key keyA; - for (const auto& mifKey : bruceConfig.mifareKeys) { for (size_t i = 0; i < mifKey.length(); i += 2) { keyA.keyByte[i/2] = strtoul(mifKey.substring(i, i + 2).c_str(), NULL, 16); @@ -410,7 +395,9 @@ bool RFID2::authenticate_mifare_classic(byte block) { } for (auto key : keys) { - statusB = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, block, key, &mfrc522.uid); + memcpy(keyB.keyByte, key, 6); + + statusB = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, block, &keyB, &mfrc522.uid); if (statusB == MFRC522::STATUS_OK) break; if (!PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) { @@ -419,8 +406,6 @@ bool RFID2::authenticate_mifare_classic(byte block) { } if (statusB != MFRC522::STATUS_OK) { - MFRC522::MIFARE_Key keyB; - for (const auto& mifKey : bruceConfig.mifareKeys) { for (size_t i = 0; i < mifKey.length(); i += 2) { keyB.keyByte[i/2] = strtoul(mifKey.substring(i, i + 2).c_str(), NULL, 16); diff --git a/src/modules/rfid/RFIDInterface.h b/src/modules/rfid/RFIDInterface.h index 050b912f..b3acf601 100644 --- a/src/modules/rfid/RFIDInterface.h +++ b/src/modules/rfid/RFIDInterface.h @@ -54,6 +54,24 @@ class RFIDInterface { NDEF_URI = 0x55 }; + uint8_t keys[15][6] = { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, + { 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5 }, + { 0x4D, 0x3A, 0x99, 0xC3, 0x51, 0xDD }, + { 0x1A, 0x98, 0x2C, 0x7E, 0x45, 0x9A }, + { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, + { 0x71, 0x4C, 0x5C, 0x88, 0x6E, 0x97 }, + { 0x58, 0x7E, 0xE5, 0xF9, 0x35, 0x0F }, + { 0xA0, 0x47, 0x8C, 0xC3, 0x90, 0x91 }, + { 0x53, 0x3C, 0xB6, 0xC7, 0x23, 0xF6 }, + { 0x8F, 0xD0, 0xA4, 0xF2, 0x56, 0xE9 }, + { 0xA6, 0x45, 0x98, 0xA7, 0x74, 0x78 }, + { 0x26, 0x94, 0x0B, 0x21, 0xFF, 0x5D }, + { 0xFC, 0x00, 0x01, 0x87, 0x78, 0xF7 }, + { 0x00, 0x00, 0x0F, 0xFE, 0x24, 0x88 } + }; + Uid uid; PrintableUID printableUID; From 29c841fac1768a5bb7b0e2cb43240863efd61a40 Mon Sep 17 00:00:00 2001 From: Rennan Cockles Date: Thu, 9 Jan 2025 14:29:25 -0300 Subject: [PATCH 6/6] rfid config menu to add mifare keys --- src/core/config.cpp | 8 ++++++++ src/core/config.h | 1 + src/core/menu_items/RFIDMenu.cpp | 1 + src/core/settings.cpp | 15 ++++++++++++--- src/core/settings.h | 2 ++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/core/config.cpp b/src/core/config.cpp index 34d361b7..211826be 100644 --- a/src/core/config.cpp +++ b/src/core/config.cpp @@ -441,6 +441,14 @@ void BruceConfig::validateRfidModuleValue() { } +void BruceConfig::addMifareKey(String value) { + if (value.length() != 12) return; + mifareKeys.insert(value); + validateMifareKeysItems(); + saveFile(); +} + + void BruceConfig::validateMifareKeysItems() { for (auto key = mifareKeys.begin(); key != mifareKeys.end();) { if (key->length() != 12) key = mifareKeys.erase(key); diff --git a/src/core/config.h b/src/core/config.h index 3c67c7f4..b3a2a5f3 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -157,6 +157,7 @@ class BruceConfig { // RFID void setRfidModule(RFIDModules value); void validateRfidModuleValue(); + void addMifareKey(String value); void validateMifareKeysItems(); // GPS diff --git a/src/core/menu_items/RFIDMenu.cpp b/src/core/menu_items/RFIDMenu.cpp index 6d20ed72..cd45fe00 100644 --- a/src/core/menu_items/RFIDMenu.cpp +++ b/src/core/menu_items/RFIDMenu.cpp @@ -35,6 +35,7 @@ void RFIDMenu::optionsMenu() { void RFIDMenu::configMenu() { options = { {"RFID Module", [=]() { setRFIDModuleMenu(); }}, + {"Add MIF Key", [=]() { addMifareKeyMenu(); }}, {"Back", [=]() { optionsMenu(); }}, }; diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 7be541f7..b633be97 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -81,14 +81,14 @@ int gsetRotation(bool set){ if(result & 0b01) { // if 1 or 3 tftWidth=TFT_HEIGHT; - #if defined(HAS_TOUCH) + #if defined(HAS_TOUCH) tftHeight=TFT_WIDTH - 20; - #else + #else tftHeight=TFT_WIDTH; #endif } else { // if 2 or 0 tftWidth=TFT_WIDTH; - #if defined(HAS_TOUCH) + #if defined(HAS_TOUCH) tftHeight=TFT_HEIGHT-20; #else tftHeight=TFT_HEIGHT; @@ -289,6 +289,15 @@ void setRFIDModuleMenu() { loopOptions(options, bruceConfig.rfidModule); } +/********************************************************************* +** Function: addMifareKeyMenu +** Handles Menu to add MIFARE keys into config list +**********************************************************************/ +void addMifareKeyMenu() { + String key = keyboard("", 12, "MIFARE key"); + bruceConfig.addMifareKey(key); +} + /********************************************************************* ** Function: setClock diff --git a/src/core/settings.h b/src/core/settings.h index c285ee57..9bc6a280 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -21,6 +21,8 @@ void setRFFreqMenu(); void setRFIDModuleMenu(); +void addMifareKeyMenu(); + void setSleepMode(); void setDimmerTimeMenu();