diff --git a/Software/src/NFC.cpp b/Software/src/NFC.cpp index 9651c63..10acdfa 100644 --- a/Software/src/NFC.cpp +++ b/Software/src/NFC.cpp @@ -3,6 +3,7 @@ #include #include "helpers.h" #include +#include NFC::NFC(int pin_sda, int pin_scl) { @@ -184,4 +185,48 @@ bool NFC::disconnectCard() bool NFC::testCard() { return true; +} + +uint8_t NFC::Transceive(uint8_t *command, uint8_t command_len, uint8_t *response, uint8_t *response_len) +{ + // Check if command length exceeds the maximum allowed (command_len + 2 <= 255) + if (command_len > 253) + { + return 0x01; // General error (no room for the command) + } + + // Construct the request buffer with PCB and CID + uint8_t request_buffer[command_len + 2]; // PCB + CID + command data + request_buffer[0] = pcb; // Protocol Control Byte + request_buffer[1] = cid; // Card Identifier + memcpy(&request_buffer[2], command, command_len); + + // Toggle PCB as per ISO-DEP protocol + pcb = (pcb == 0x0A) ? 0x0B : 0x0A; + + // Prepare response buffer + uint8_t response_buffer[128]; // Adjust buffer size as needed + // Clamp the size to 255 because inDataExchange expects a uint8_t + uint8_t response_length = (sizeof(response_buffer) > 255) ? 255 : sizeof(response_buffer); + + // Transceive data using Adafruit's inDataExchange + uint8_t status = rfid->inDataExchange(request_buffer, command_len + 2, response_buffer, &response_length); + + // Check if the operation was successful + if (status != 0x00) + { // 0x00 is PN532_STATUS_OK + return status; // Return the Adafruit_PN532 error code + } + + // Check if response contains at least PCB and CID + if (response_length < 2) + { + return 0x01; // Invalid response + } + + // Extract the data part (excluding PCB and CID) + *response_len = response_length - 2; + memcpy(response, response_buffer + 2, *response_len); + + return 0x00; // Success (PN532_STATUS_OK) } \ No newline at end of file diff --git a/Software/src/NFC.h b/Software/src/NFC.h index 5482807..ae26e4d 100644 --- a/Software/src/NFC.h +++ b/Software/src/NFC.h @@ -55,6 +55,8 @@ public: // Returns the UID of the detected card as a hexadecimal String. String getUID() const; + + uint8_t Transceive(uint8_t *command, uint8_t command_len, uint8_t *response, uint8_t *response_len); }; #endif // NFC_H diff --git a/Software/src/OTAProxy.cpp b/Software/src/OTAProxy.cpp index 4d651f8..59b26de 100644 --- a/Software/src/OTAProxy.cpp +++ b/Software/src/OTAProxy.cpp @@ -2,6 +2,7 @@ #include "NFC.h" #include #include +#include "helpers.h" OTAProxy::OTAProxy(PubSubClient *mqttClient, NFC *nfc, int id) { @@ -35,53 +36,70 @@ void OTAProxy::startOTA() void OTAProxy::continueOTA(char *topic, byte *payload, unsigned int length) { // Create topic strings with sufficient buffer sizes - char topic_requestOTA[32]; + char topic_requestOTA[] = "fabreader/00000/requestOTA"; sprintf(topic_requestOTA, "fabreader/%05d/requestOTA", id); - char topic_responseOTA[32]; + char topic_responseOTA[] = "fabreader/00000/responseOTA"; sprintf(topic_responseOTA, "fabreader/%05d/responseOTA", id); - char topic_stopOTA[32]; + char topic_stopOTA[] = "fabreader/00000/stopOTA"; sprintf(topic_stopOTA, "fabreader/%05d/stopOTA", id); - char topic_restartOTA[32]; + char topic_restartOTA[] = "fabreader/00000/restartOTA"; sprintf(topic_restartOTA, "fabreader/%05d/restartOTA", id); if (!strcmp(topic, topic_requestOTA)) { - Log.info("Request OTA"); - + Log.trace("Request OTA"); byte response[APDU_BUFFER_SIZE] = {0}; + byte response_len; - // Maximum value for a uint8_t is 255. - uint8_t response_len = 255; // Use 255 even if APDU_BUFFER_SIZE is 256 + uint8_t status; - // Cast length (unsigned int) to uint8_t, assuming it fits within 255 bytes. - uint8_t sendLength = (uint8_t)length; + Log.trace("Run Transceive"); - Log.trace(F("Run Transceive")); - int status = nfc->rfid->inDataExchange(payload, sendLength, response, &response_len); - Log.trace(F("PICC_Transceive: 0x%02x"), status); + Log.trace("Payload length: %d", length); + Log.trace("Payload: %X", payload); - if (status < 0) + status = nfc->Transceive(payload, length, response, &response_len); + Serial.printf("PICC_Tranceive: 0x%02x\n", status); + + if (status != 0x00) { cancelOTA(); return; } - mqtt->publish(topic_responseOTA, response, response_len); - Log.info("Response OTA"); + Log.trace("Response length: %d", response_len); + Log.trace("Response: %X", response); + + printbytes(response, response_len); + + bool mqttResult = mqtt->publish(topic_responseOTA, response, response_len); + + if (!mqttResult) + { + Log.error("MQTT publish failed"); + cancelOTA(); + return; + } + + Log.trace("Response OTA"); } else if (!strcmp(topic, topic_stopOTA)) { - Log.info("Stop OTA"); + Log.trace("Stop OTA"); nfc->disconnectCard(); activeOTA = false; } - // else if (!strcmp(topic, topic_restartOTA)) + // else if(!strcmp(topic, topic_restartOTA)) // { - // Log.info("Restart OTA"); // Updated if uncommented - // // Add your PN532-specific card deselection logic here if needed. + // Log.trace("Restart OTA"); + // while(!(nfc->deselectCard())); + // // if(nfc->hasNewCard()) + // // { + // // startOTA(); + // // } // } } diff --git a/Software/src/main.cpp b/Software/src/main.cpp index aa6b4d8..733c193 100644 --- a/Software/src/main.cpp +++ b/Software/src/main.cpp @@ -20,7 +20,7 @@ NFC *nfc; OTAProxy *ota; Display *display; -unsigned long otatimeout = 3000; +unsigned long otatimeout = 6000; unsigned long lastotatime; void setup_wifi() @@ -101,11 +101,17 @@ void callback(char *topic, byte *payload, unsigned int length) display->updateByMQTT(topic, payload, length); } +void printSuffix(Print *_logOutput, int logLevel) +{ + _logOutput->print("\n"); +} + void setup() { Serial.begin(115200); Log.begin(LOG_LEVEL_VERBOSE, &Serial); // Initialize ArduinoLog + Log.setSuffix(printSuffix); // Optional: add a timestamp to each log entry. // Log.begin(LOG_LEVEL_VERBOSE, &Serial, true); @@ -143,6 +149,7 @@ void loop() { reconnect(); } + mqtt->loop(); if (!ota->hasActiveOTA())