diff --git a/include/RFID.h b/include/RFID.h index 168eca4..66a42f8 100644 --- a/include/RFID.h +++ b/include/RFID.h @@ -15,6 +15,7 @@ #include #include +#include "Com.h" #include "IDs.h" #include "Pinout.h" @@ -50,6 +51,21 @@ public: * @return 0 if no change, ID if new tag detected, ID & sign bit if the tag left. */ int8_t checkTags(); + + /*** + * Populate an already allocated array of sufficient size to fit + * maxTags number of TagInfoRecords. + * @param tagData Pointer to an array of size maxTags*sizeof(Com::TagInfoRecord) + * @return Number of tags actually put in the array. + */ + uint8_t gatherTagInfo(Com::TagInfoRecord* tagData); + + /*** + * Change the ID stored in a tag so that it matches tagToProgram. + * @param tagToProgram Pointer to an existing struct with the data to program. + * @return True if the programming succeeded. + */ + bool programTag(Com::TagInfoRecord* tagToProgram); private: static const byte tagIdBlock = 0x11; /* Used for "encrypted" communication with the tags. */ diff --git a/src/RFID.cpp b/src/RFID.cpp index 7df626d..03b40d5 100644 --- a/src/RFID.cpp +++ b/src/RFID.cpp @@ -4,6 +4,9 @@ #include "RFID.h" +static_assert(RFID::maxTags * sizeof(Com::TagInfoRecord) <= 62, + "RFID::maxTags too high, protocol cannot support it.\n"); + MFRC522Constants::MIFARE_Key RFID::defaultKey = {0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; int RFID::currentActiveTags = 0; @@ -68,6 +71,38 @@ int8_t RFID::checkTags() { return newTag->tag_ID; } +uint8_t RFID::gatherTagInfo(Com::TagInfoRecord *tagData) { + int tagCount = 0; + for (uidNode* node = activeTags; node; node = node->next) { + // The protocol does not support UIDs other than 4 bytes, so assume it + // is the case here directly. + tagData[tagCount].uid = *(uint32_t*)(node->uid.uidByte); + tagData[tagCount].figId = node->tag_ID; + tagCount++; + } + return tagCount; +} + +bool RFID::programTag(Com::TagInfoRecord *tagToProgram) { + + byte comSize = sizeof(comData); + + mfrc.uid.size = 4; + *(uint32_t*)(mfrc.uid.uidByte) = tagToProgram->uid; + mfrc.PICC_WakeupA(comData, &comSize); + if (mfrc.PICC_Select(&mfrc.uid, mfrc.uid.size) != MFRC522Constants::STATUS_OK) { + Serial.println("Failed to wakeup for programming. Is tag still there ?\n"); + mfrc.PICC_HaltA(); + return false; + } + + if (!writeBlock(mfrc.uid, tagIdBlock, tagToProgram->figId)) { + Serial.println("Failed to program tag."); + return false; + } + return true; +} + uidNode* RFID::addActiveTag(const MFRC522Constants::Uid &newTag) { if (!nextFreeTagSlot) { return nullptr;