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

View File

@ -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

View File

@ -2,6 +2,7 @@
#include "NFC.h"
#include <PubSubClient.h>
#include <ArduinoLog.h>
#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();
// // }
// }
}

View File

@ -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())