More work on authentification

This commit is contained in:
André Fiedler 2025-02-20 17:18:35 +01:00
parent 3e4e76e634
commit 1e949892df
4 changed files with 93 additions and 21 deletions

View File

@ -3,6 +3,7 @@
#include <PubSubClient.h> #include <PubSubClient.h>
#include "helpers.h" #include "helpers.h"
#include <ArduinoLog.h> #include <ArduinoLog.h>
#include <Adafruit_PN532.h>
NFC::NFC(int pin_sda, int pin_scl) NFC::NFC(int pin_sda, int pin_scl)
{ {
@ -185,3 +186,47 @@ bool NFC::testCard()
{ {
return true; 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)
}

View File

@ -55,6 +55,8 @@ public:
// Returns the UID of the detected card as a hexadecimal String. // Returns the UID of the detected card as a hexadecimal String.
String getUID() const; String getUID() const;
uint8_t Transceive(uint8_t *command, uint8_t command_len, uint8_t *response, uint8_t *response_len);
}; };
#endif // NFC_H #endif // NFC_H

View File

@ -2,6 +2,7 @@
#include "NFC.h" #include "NFC.h"
#include <PubSubClient.h> #include <PubSubClient.h>
#include <ArduinoLog.h> #include <ArduinoLog.h>
#include "helpers.h"
OTAProxy::OTAProxy(PubSubClient *mqttClient, NFC *nfc, int id) 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) void OTAProxy::continueOTA(char *topic, byte *payload, unsigned int length)
{ {
// Create topic strings with sufficient buffer sizes // Create topic strings with sufficient buffer sizes
char topic_requestOTA[32]; char topic_requestOTA[] = "fabreader/00000/requestOTA";
sprintf(topic_requestOTA, "fabreader/%05d/requestOTA", id); sprintf(topic_requestOTA, "fabreader/%05d/requestOTA", id);
char topic_responseOTA[32]; char topic_responseOTA[] = "fabreader/00000/responseOTA";
sprintf(topic_responseOTA, "fabreader/%05d/responseOTA", id); sprintf(topic_responseOTA, "fabreader/%05d/responseOTA", id);
char topic_stopOTA[32]; char topic_stopOTA[] = "fabreader/00000/stopOTA";
sprintf(topic_stopOTA, "fabreader/%05d/stopOTA", id); sprintf(topic_stopOTA, "fabreader/%05d/stopOTA", id);
char topic_restartOTA[32]; char topic_restartOTA[] = "fabreader/00000/restartOTA";
sprintf(topic_restartOTA, "fabreader/%05d/restartOTA", id); sprintf(topic_restartOTA, "fabreader/%05d/restartOTA", id);
if (!strcmp(topic, topic_requestOTA)) if (!strcmp(topic, topic_requestOTA))
{ {
Log.info("Request OTA"); Log.trace("Request OTA");
byte response[APDU_BUFFER_SIZE] = {0}; byte response[APDU_BUFFER_SIZE] = {0};
byte response_len;
// Maximum value for a uint8_t is 255. uint8_t status;
uint8_t response_len = 255; // Use 255 even if APDU_BUFFER_SIZE is 256
// Cast length (unsigned int) to uint8_t, assuming it fits within 255 bytes. Log.trace("Run Transceive");
uint8_t sendLength = (uint8_t)length;
Log.trace(F("Run Transceive")); Log.trace("Payload length: %d", length);
int status = nfc->rfid->inDataExchange(payload, sendLength, response, &response_len); Log.trace("Payload: %X", payload);
Log.trace(F("PICC_Transceive: 0x%02x"), status);
if (status < 0) status = nfc->Transceive(payload, length, response, &response_len);
Serial.printf("PICC_Tranceive: 0x%02x\n", status);
if (status != 0x00)
{ {
cancelOTA(); cancelOTA();
return; return;
} }
mqtt->publish(topic_responseOTA, response, response_len); Log.trace("Response length: %d", response_len);
Log.info("Response OTA"); 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)) else if (!strcmp(topic, topic_stopOTA))
{ {
Log.info("Stop OTA"); Log.trace("Stop OTA");
nfc->disconnectCard(); nfc->disconnectCard();
activeOTA = false; activeOTA = false;
} }
// else if (!strcmp(topic, topic_restartOTA)) // else if(!strcmp(topic, topic_restartOTA))
// { // {
// Log.info("Restart OTA"); // Updated if uncommented // Log.trace("Restart OTA");
// // Add your PN532-specific card deselection logic here if needed. // while(!(nfc->deselectCard()));
// // if(nfc->hasNewCard())
// // {
// // startOTA();
// // }
// } // }
} }

View File

@ -20,7 +20,7 @@ NFC *nfc;
OTAProxy *ota; OTAProxy *ota;
Display *display; Display *display;
unsigned long otatimeout = 3000; unsigned long otatimeout = 6000;
unsigned long lastotatime; unsigned long lastotatime;
void setup_wifi() void setup_wifi()
@ -101,11 +101,17 @@ void callback(char *topic, byte *payload, unsigned int length)
display->updateByMQTT(topic, payload, length); display->updateByMQTT(topic, payload, length);
} }
void printSuffix(Print *_logOutput, int logLevel)
{
_logOutput->print("\n");
}
void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Log.begin(LOG_LEVEL_VERBOSE, &Serial); // Initialize ArduinoLog Log.begin(LOG_LEVEL_VERBOSE, &Serial); // Initialize ArduinoLog
Log.setSuffix(printSuffix);
// Optional: add a timestamp to each log entry. // Optional: add a timestamp to each log entry.
// Log.begin(LOG_LEVEL_VERBOSE, &Serial, true); // Log.begin(LOG_LEVEL_VERBOSE, &Serial, true);
@ -143,6 +149,7 @@ void loop()
{ {
reconnect(); reconnect();
} }
mqtt->loop(); mqtt->loop();
if (!ota->hasActiveOTA()) if (!ota->hasActiveOTA())