mirror of https://github.com/arendst/Tasmota.git
Refactor PN532 Rfid reader
- Refactor PN532 Rfid reader - Add UID to GUI
This commit is contained in:
parent
519a028477
commit
bf1b6dae31
|
@ -55,20 +55,20 @@ TasmotaSerial *PN532_Serial;
|
|||
#define MIFARE_CMD_AUTH_B 0x61
|
||||
#define MIFARE_CMD_WRITE 0xA0
|
||||
|
||||
uint8_t pn532_model = 0; // Used to maintain detection flag
|
||||
uint8_t pn532_command = 0; // Used to carry command code between functions
|
||||
uint8_t pn532_scantimer = 0; // Used to prevent multiple successful reads within 2 second window
|
||||
|
||||
uint8_t pn532_packetbuffer[64]; // Global buffer used to store packet
|
||||
|
||||
struct PN532 {
|
||||
char uids[21]; // Number of bytes in the UID. 4, 7 or 10
|
||||
uint8_t packetbuffer[64]; // Global buffer used to store packet
|
||||
uint8_t command = 0; // Carry command code between functions
|
||||
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
|
||||
bool present = false; // Maintain detection flag
|
||||
#ifdef USE_PN532_DATA_FUNCTION
|
||||
uint8_t pn532_function = 0;
|
||||
uint8_t pn532_newdata[16];
|
||||
uint8_t pn532_newdata_len = 0;
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
uint8_t newdata[16];
|
||||
uint8_t function = 0;
|
||||
uint8_t newdata_len = 0;
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
} Pn532;
|
||||
|
||||
void PN532_Init(void)
|
||||
{
|
||||
void PN532_Init(void) {
|
||||
if (PinUsed(GPIO_PN532_RXD) && PinUsed(GPIO_PN532_TXD)) {
|
||||
PN532_Serial = new TasmotaSerial(Pin(GPIO_PN532_RXD), Pin(GPIO_PN532_TXD), 1);
|
||||
if (PN532_Serial->begin(115200)) {
|
||||
|
@ -76,17 +76,18 @@ void PN532_Init(void)
|
|||
PN532_wakeup();
|
||||
uint32_t ver = PN532_getFirmwareVersion();
|
||||
if (ver) {
|
||||
uint8_t empty_uid[4] = { 0 };
|
||||
ToHex_P((unsigned char*)empty_uid, sizeof(empty_uid), Pn532.uids, sizeof(Pn532.uids));
|
||||
PN532_setPassiveActivationRetries(0xFF);
|
||||
PN532_SAMConfig();
|
||||
pn532_model = 1;
|
||||
AddLog_P(LOG_LEVEL_INFO,"NFC: PN532 NFC Reader detected (V%u.%u)",(ver>>16) & 0xFF, (ver>>8) & 0xFF);
|
||||
AddLog_P(LOG_LEVEL_INFO,"NFC: PN532 NFC Reader detected v%u.%u",(ver>>16) & 0xFF, (ver>>8) & 0xFF);
|
||||
Pn532.present = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int8_t PN532_receive(uint8_t *buf, int len, uint16_t timeout)
|
||||
{
|
||||
int8_t PN532_receive(uint8_t *buf, int len, uint16_t timeout) {
|
||||
int read_bytes = 0;
|
||||
int ret;
|
||||
unsigned long start_millis;
|
||||
|
@ -112,8 +113,7 @@ int8_t PN532_receive(uint8_t *buf, int len, uint16_t timeout)
|
|||
return read_bytes;
|
||||
}
|
||||
|
||||
int8_t PN532_readAckFrame(void)
|
||||
{
|
||||
int8_t PN532_readAckFrame(void) {
|
||||
const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
|
||||
uint8_t ackBuf[sizeof(PN532_ACK)];
|
||||
|
||||
|
@ -127,12 +127,11 @@ int8_t PN532_readAckFrame(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int8_t PN532_writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0)
|
||||
{
|
||||
int8_t PN532_writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body = 0, uint8_t blen = 0) {
|
||||
// Clear the serial buffer just in case
|
||||
PN532_Serial->flush();
|
||||
|
||||
pn532_command = header[0];
|
||||
Pn532.command = header[0];
|
||||
PN532_Serial->write((uint8_t)PN532_PREAMBLE);
|
||||
PN532_Serial->write((uint8_t)PN532_STARTCODE1);
|
||||
PN532_Serial->write(PN532_STARTCODE2);
|
||||
|
@ -161,8 +160,7 @@ int8_t PN532_writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *bo
|
|||
return PN532_readAckFrame();
|
||||
}
|
||||
|
||||
int16_t PN532_readResponse(uint8_t buf[], uint8_t len, uint16_t timeout = 50)
|
||||
{
|
||||
int16_t PN532_readResponse(uint8_t buf[], uint8_t len, uint16_t timeout = 50) {
|
||||
uint8_t tmp[3];
|
||||
|
||||
// Read preamble and start code
|
||||
|
@ -183,12 +181,12 @@ int16_t PN532_readResponse(uint8_t buf[], uint8_t len, uint16_t timeout = 50)
|
|||
return PN532_INVALID_FRAME;
|
||||
}
|
||||
length[0] -= 2;
|
||||
if (length[0] > len) { // If this happens, then pn532_packetbuffer is not large enough
|
||||
if (length[0] > len) { // If this happens, then Pn532.packetbuffer is not large enough
|
||||
return PN532_NO_SPACE;
|
||||
}
|
||||
|
||||
// Get the command byte
|
||||
uint8_t cmd = pn532_command + 1;
|
||||
uint8_t cmd = Pn532.command + 1;
|
||||
if (PN532_receive(tmp, 2, timeout) <= 0) { // Time out while receiving
|
||||
return PN532_TIMEOUT;
|
||||
}
|
||||
|
@ -216,35 +214,33 @@ int16_t PN532_readResponse(uint8_t buf[], uint8_t len, uint16_t timeout = 50)
|
|||
return length[0];
|
||||
}
|
||||
|
||||
uint32_t PN532_getFirmwareVersion(void)
|
||||
{
|
||||
uint32_t PN532_getFirmwareVersion(void) {
|
||||
uint32_t response;
|
||||
|
||||
pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
|
||||
Pn532.packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
|
||||
|
||||
if (PN532_writeCommand(pn532_packetbuffer, 1)) {
|
||||
if (PN532_writeCommand(Pn532.packetbuffer, 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read data packet
|
||||
int16_t status = PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer));
|
||||
int16_t status = PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
|
||||
if (0 > status) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
response = pn532_packetbuffer[0];
|
||||
response = Pn532.packetbuffer[0];
|
||||
response <<= 8;
|
||||
response |= pn532_packetbuffer[1];
|
||||
response |= Pn532.packetbuffer[1];
|
||||
response <<= 8;
|
||||
response |= pn532_packetbuffer[2];
|
||||
response |= Pn532.packetbuffer[2];
|
||||
response <<= 8;
|
||||
response |= pn532_packetbuffer[3];
|
||||
response |= Pn532.packetbuffer[3];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void PN532_wakeup(void)
|
||||
{
|
||||
void PN532_wakeup(void) {
|
||||
uint8_t wakeup[5] = {0x55, 0x55, 0, 0, 0 };
|
||||
PN532_Serial->write(wakeup,sizeof(wakeup));
|
||||
|
||||
|
@ -252,16 +248,15 @@ void PN532_wakeup(void)
|
|||
PN532_Serial->flush();
|
||||
}
|
||||
|
||||
bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout = 50)
|
||||
{
|
||||
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
|
||||
pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
|
||||
pn532_packetbuffer[2] = cardbaudrate;
|
||||
if (PN532_writeCommand(pn532_packetbuffer, 3)) {
|
||||
bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout = 50) {
|
||||
Pn532.packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
|
||||
Pn532.packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
|
||||
Pn532.packetbuffer[2] = cardbaudrate;
|
||||
if (PN532_writeCommand(Pn532.packetbuffer, 3)) {
|
||||
return 0x0; // command failed
|
||||
}
|
||||
// read data packet
|
||||
if (PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) {
|
||||
if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer), timeout) < 0) {
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
|
@ -274,256 +269,240 @@ bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidL
|
|||
b6..NFCIDLen NFCID
|
||||
*/
|
||||
|
||||
if (pn532_packetbuffer[0] != 1) {
|
||||
if (Pn532.packetbuffer[0] != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t sens_res = pn532_packetbuffer[2];
|
||||
uint16_t sens_res = Pn532.packetbuffer[2];
|
||||
sens_res <<= 8;
|
||||
sens_res |= pn532_packetbuffer[3];
|
||||
sens_res |= Pn532.packetbuffer[3];
|
||||
|
||||
/* Card appears to be Mifare Classic */
|
||||
*uidLength = pn532_packetbuffer[5];
|
||||
*uidLength = Pn532.packetbuffer[5];
|
||||
|
||||
for (uint32_t i = 0; i < pn532_packetbuffer[5]; i++) {
|
||||
uid[i] = pn532_packetbuffer[6 + i];
|
||||
for (uint32_t i = 0; i < Pn532.packetbuffer[5]; i++) {
|
||||
uid[i] = Pn532.packetbuffer[6 + i];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool PN532_setPassiveActivationRetries(uint8_t maxRetries)
|
||||
{
|
||||
pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
|
||||
pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
|
||||
pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
|
||||
pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01)
|
||||
pn532_packetbuffer[4] = maxRetries;
|
||||
if (PN532_writeCommand(pn532_packetbuffer, 5)) {
|
||||
bool PN532_setPassiveActivationRetries(uint8_t maxRetries) {
|
||||
Pn532.packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
|
||||
Pn532.packetbuffer[1] = 5; // Config item 5 (MaxRetries)
|
||||
Pn532.packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
|
||||
Pn532.packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01)
|
||||
Pn532.packetbuffer[4] = maxRetries;
|
||||
if (PN532_writeCommand(Pn532.packetbuffer, 5)) {
|
||||
return 0; // no ACK
|
||||
}
|
||||
return (0 < PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
|
||||
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
|
||||
}
|
||||
|
||||
bool PN532_SAMConfig(void)
|
||||
{
|
||||
pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
|
||||
pn532_packetbuffer[1] = 0x01; // normal mode
|
||||
pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
|
||||
pn532_packetbuffer[3] = 0x00; // we don't need the external IRQ pin
|
||||
if (PN532_writeCommand(pn532_packetbuffer, 4)) {
|
||||
bool PN532_SAMConfig(void) {
|
||||
Pn532.packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
|
||||
Pn532.packetbuffer[1] = 0x01; // normal mode
|
||||
Pn532.packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
|
||||
Pn532.packetbuffer[3] = 0x00; // we don't need the external IRQ pin
|
||||
if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
|
||||
return false;
|
||||
}
|
||||
return (0 < PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
|
||||
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
|
||||
}
|
||||
|
||||
#ifdef USE_PN532_DATA_FUNCTION
|
||||
|
||||
uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t _key[6];
|
||||
uint8_t _uid[7];
|
||||
uint8_t _uidLen;
|
||||
uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
|
||||
uint8_t i;
|
||||
uint8_t _key[6];
|
||||
uint8_t _uid[7];
|
||||
uint8_t _uidLen;
|
||||
|
||||
// Hang on to the key and uid data
|
||||
memcpy(&_key, keyData, 6);
|
||||
memcpy(&_uid, uid, uidLen);
|
||||
_uidLen = uidLen;
|
||||
// Hang on to the key and uid data
|
||||
memcpy(&_key, keyData, 6);
|
||||
memcpy(&_uid, uid, uidLen);
|
||||
_uidLen = uidLen;
|
||||
|
||||
// Prepare the authentication command //
|
||||
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
|
||||
pn532_packetbuffer[1] = 1; /* Max card numbers */
|
||||
pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
|
||||
pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
|
||||
memcpy(&pn532_packetbuffer[4], &_key, 6);
|
||||
for (i = 0; i < _uidLen; i++) {
|
||||
pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */
|
||||
}
|
||||
// Prepare the authentication command //
|
||||
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
|
||||
Pn532.packetbuffer[1] = 1; /* Max card numbers */
|
||||
Pn532.packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
|
||||
Pn532.packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
|
||||
memcpy(&Pn532.packetbuffer[4], &_key, 6);
|
||||
for (i = 0; i < _uidLen; i++) {
|
||||
Pn532.packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */
|
||||
}
|
||||
|
||||
if (PN532_writeCommand(pn532_packetbuffer, 10 + _uidLen)) { return 0; }
|
||||
if (PN532_writeCommand(Pn532.packetbuffer, 10 + _uidLen)) { return 0; }
|
||||
|
||||
// Read the response packet
|
||||
PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer));
|
||||
// Read the response packet
|
||||
PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
|
||||
|
||||
// Check if the response is valid and we are authenticated???
|
||||
// for an auth success it should be bytes 5-7: 0xD5 0x41 0x00
|
||||
// Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good
|
||||
if (pn532_packetbuffer[0] != 0x00) {
|
||||
// Authentification failed
|
||||
return 0;
|
||||
}
|
||||
// Check if the response is valid and we are authenticated???
|
||||
// for an auth success it should be bytes 5-7: 0xD5 0x41 0x00
|
||||
// Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good
|
||||
if (Pn532.packetbuffer[0] != 0x00) {
|
||||
// Authentification failed
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data)
|
||||
{
|
||||
/* Prepare the command */
|
||||
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
||||
pn532_packetbuffer[1] = 1; /* Card number */
|
||||
pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
|
||||
pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
|
||||
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
|
||||
/* Prepare the command */
|
||||
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
||||
Pn532.packetbuffer[1] = 1; /* Card number */
|
||||
Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
|
||||
Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
|
||||
|
||||
/* Send the command */
|
||||
if (PN532_writeCommand(pn532_packetbuffer, 4)) {
|
||||
return 0;
|
||||
}
|
||||
/* Send the command */
|
||||
if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read the response packet */
|
||||
PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer));
|
||||
/* Read the response packet */
|
||||
PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
|
||||
|
||||
/* If byte 8 isn't 0x00 we probably have an error */
|
||||
if (pn532_packetbuffer[0] != 0x00) {
|
||||
return 0;
|
||||
}
|
||||
/* If byte 8 isn't 0x00 we probably have an error */
|
||||
if (Pn532.packetbuffer[0] != 0x00) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy the 16 data bytes to the output buffer */
|
||||
/* Block content starts at byte 9 of a valid response */
|
||||
memcpy (data, &pn532_packetbuffer[1], 16);
|
||||
/* Copy the 16 data bytes to the output buffer */
|
||||
/* Block content starts at byte 9 of a valid response */
|
||||
memcpy (data, &Pn532.packetbuffer[1], 16);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data)
|
||||
{
|
||||
/* Prepare the first command */
|
||||
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
||||
pn532_packetbuffer[1] = 1; /* Card number */
|
||||
pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
|
||||
pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
|
||||
memcpy(&pn532_packetbuffer[4], data, 16); /* Data Payload */
|
||||
uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
|
||||
/* Prepare the first command */
|
||||
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
|
||||
Pn532.packetbuffer[1] = 1; /* Card number */
|
||||
Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
|
||||
Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
|
||||
memcpy(&Pn532.packetbuffer[4], data, 16); /* Data Payload */
|
||||
|
||||
/* Send the command */
|
||||
if (PN532_writeCommand(pn532_packetbuffer, 20)) {
|
||||
return 0;
|
||||
}
|
||||
/* Send the command */
|
||||
if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read the response packet */
|
||||
return (0 < PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
|
||||
/* Read the response packet */
|
||||
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
|
||||
}
|
||||
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
|
||||
void PN532_ScanForTag(void)
|
||||
{
|
||||
if (!pn532_model) { return; }
|
||||
void PN532_ScanForTag(void) {
|
||||
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t uid_len = 0;
|
||||
uint8_t card_data[16];
|
||||
bool erase_success = false;
|
||||
bool set_success = false;
|
||||
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uid_len)) {
|
||||
char uids[15];
|
||||
|
||||
ToHex_P((unsigned char*)uid, uid_len, Pn532.uids, sizeof(Pn532.uids));
|
||||
|
||||
#ifdef USE_PN532_DATA_FUNCTION
|
||||
char card_datas[34];
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
|
||||
ToHex_P((unsigned char*)uid, uid_len, uids, sizeof(uids));
|
||||
|
||||
#ifdef USE_PN532_DATA_FUNCTION
|
||||
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
|
||||
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
|
||||
if (mifareclassic_ReadDataBlock(1, card_data)) {
|
||||
bool erase_success = false;
|
||||
bool set_success = false;
|
||||
char card_datas[34];
|
||||
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
|
||||
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
|
||||
uint8_t card_data[16];
|
||||
if (mifareclassic_ReadDataBlock(1, card_data)) {
|
||||
#ifdef USE_PN532_DATA_RAW
|
||||
memcpy(&card_datas,&card_data,sizeof(card_data));
|
||||
memcpy(&card_datas,&card_data,sizeof(card_data));
|
||||
#else
|
||||
for (uint32_t i = 0;i < sizeof(card_data);i++) {
|
||||
if ((isalpha(card_data[i])) || ((isdigit(card_data[i])))) {
|
||||
card_datas[i] = char(card_data[i]);
|
||||
} else {
|
||||
card_datas[i] = '\0';
|
||||
}
|
||||
}
|
||||
#endif // USE_PN532_DATA_RAW
|
||||
}
|
||||
if (pn532_function == 1) { // erase block 1 of card
|
||||
for (uint32_t i = 0;i<16;i++) {
|
||||
card_data[i] = 0x00;
|
||||
}
|
||||
if (mifareclassic_WriteDataBlock(1, card_data)) {
|
||||
erase_success = true;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
|
||||
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
|
||||
for (uint32_t i = 0;i < sizeof(card_data);i++) {
|
||||
if ((isalpha(card_data[i])) || ((isdigit(card_data[i])))) {
|
||||
card_datas[i] = char(card_data[i]);
|
||||
} else {
|
||||
card_datas[i] = '\0';
|
||||
}
|
||||
}
|
||||
if (pn532_function == 2) {
|
||||
#endif // USE_PN532_DATA_RAW
|
||||
}
|
||||
if (Pn532.function == 1) { // erase block 1 of card
|
||||
for (uint32_t i = 0;i<16;i++) {
|
||||
card_data[i] = 0x00;
|
||||
}
|
||||
if (mifareclassic_WriteDataBlock(1, card_data)) {
|
||||
erase_success = true;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
|
||||
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
|
||||
}
|
||||
}
|
||||
if (Pn532.function == 2) {
|
||||
#ifdef USE_PN532_DATA_RAW
|
||||
memcpy(&card_data,&pn532_newdata,sizeof(card_data));
|
||||
memcpy(&card_data,&Pn532.newdata,sizeof(card_data));
|
||||
if (mifareclassic_WriteDataBlock(1, card_data)) {
|
||||
set_success = true;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
|
||||
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
|
||||
}
|
||||
#else
|
||||
bool IsAlphaNumeric = true;
|
||||
for (uint32_t i = 0;i < Pn532.newdata_len;i++) {
|
||||
if ((!isalpha(Pn532.newdata[i])) && (!isdigit(Pn532.newdata[i]))) {
|
||||
IsAlphaNumeric = false;
|
||||
}
|
||||
}
|
||||
if (IsAlphaNumeric) {
|
||||
memcpy(&card_data,&Pn532.newdata,Pn532.newdata_len);
|
||||
card_data[Pn532.newdata_len] = '\0'; // Enforce null termination
|
||||
if (mifareclassic_WriteDataBlock(1, card_data)) {
|
||||
set_success = true;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
|
||||
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
|
||||
}
|
||||
#else
|
||||
bool IsAlphaNumeric = true;
|
||||
for (uint32_t i = 0;i < pn532_newdata_len;i++) {
|
||||
if ((!isalpha(pn532_newdata[i])) && (!isdigit(pn532_newdata[i]))) {
|
||||
IsAlphaNumeric = false;
|
||||
}
|
||||
}
|
||||
if (IsAlphaNumeric) {
|
||||
memcpy(&card_data,&pn532_newdata,pn532_newdata_len);
|
||||
card_data[pn532_newdata_len] = '\0'; // Enforce null termination
|
||||
if (mifareclassic_WriteDataBlock(1, card_data)) {
|
||||
set_success = true;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
|
||||
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
|
||||
}
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data must be alphanumeric"));
|
||||
}
|
||||
#endif // USE_PN532_DATA_RAW
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data must be alphanumeric"));
|
||||
}
|
||||
} else {
|
||||
sprintf(card_datas,"AUTHFAIL");
|
||||
#endif // USE_PN532_DATA_RAW
|
||||
}
|
||||
} else {
|
||||
sprintf_P(card_datas, PSTR("AUTHFAIL"));
|
||||
}
|
||||
switch (pn532_function) {
|
||||
case 0x01:
|
||||
if (!erase_success) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode"));
|
||||
}
|
||||
break;
|
||||
case 0x02:
|
||||
if (!set_success) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Write failed - exiting set mode"));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pn532_function = 0;
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
|
||||
#ifdef USE_PN532_DATA_FUNCTION
|
||||
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\", \"" D_JSON_DATA "\":\"%s\"}}"), uids, card_datas);
|
||||
}
|
||||
switch (Pn532.function) {
|
||||
case 0x01:
|
||||
if (!erase_success) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode"));
|
||||
}
|
||||
break;
|
||||
case 0x02:
|
||||
if (!set_success) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Write failed - exiting set mode"));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Pn532.function = 0;
|
||||
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\"}}"), Pn532.uids, card_datas);
|
||||
#else
|
||||
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), uids);
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
|
||||
MqttPublishTeleSensor();
|
||||
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids);
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
MqttPublishTeleSensor();
|
||||
|
||||
#ifdef USE_PN532_CAUSE_EVENTS
|
||||
|
||||
char command[71];
|
||||
// No more need as function MqttPublishTeleSensor() also triggers rules
|
||||
char command[71];
|
||||
#ifdef USE_PN532_DATA_FUNCTION
|
||||
sprintf(command,"backlog event PN532_UID=%s;event PN532_DATA=%s",uids,card_datas);
|
||||
sprintf(command,"backlog event PN532_UID=%s;event PN532_DATA=%s", Pn532.uids, card_datas);
|
||||
#else
|
||||
sprintf(command,"event PN532_UID=%s",uids);
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
ExecuteCommand(command, SRC_RULE);
|
||||
#endif // USE_PN532_CAUSE_EVENTS
|
||||
sprintf(command,"event PN532_UID=%s", Pn532.uids);
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
ExecuteCommand(command, SRC_RULE);
|
||||
#endif // USE_PN532_CAUSE_EVENTS
|
||||
|
||||
pn532_scantimer = 7; // Ignore tags found for two seconds
|
||||
Pn532.scantimer = 7; // Ignore tags found for two seconds
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_PN532_DATA_FUNCTION
|
||||
|
||||
bool PN532_Command(void)
|
||||
{
|
||||
bool PN532_Command(void) {
|
||||
bool serviced = true;
|
||||
uint8_t paramcount = 0;
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
|
@ -540,7 +519,7 @@ bool PN532_Command(void)
|
|||
}
|
||||
UpperCase(XdrvMailbox.data,XdrvMailbox.data);
|
||||
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"E")) {
|
||||
pn532_function = 1; // Block 1 of next card/tag will be reset to 0x00...
|
||||
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased"));
|
||||
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"E\"}}"));
|
||||
return serviced;
|
||||
|
@ -552,12 +531,12 @@ bool PN532_Command(void)
|
|||
return serviced;
|
||||
}
|
||||
sprintf(sub_string_tmp,subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
pn532_newdata_len = strlen(sub_string_tmp);
|
||||
if (pn532_newdata_len > 15) { pn532_newdata_len = 15; }
|
||||
memcpy(&pn532_newdata,&sub_string_tmp,pn532_newdata_len);
|
||||
pn532_newdata[pn532_newdata_len] = 0x00; // Null terminate the string
|
||||
pn532_function = 2;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), pn532_newdata);
|
||||
Pn532.newdata_len = strlen(sub_string_tmp);
|
||||
if (Pn532.newdata_len > 15) { Pn532.newdata_len = 15; }
|
||||
memcpy(&Pn532.newdata,&sub_string_tmp,Pn532.newdata_len);
|
||||
Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string
|
||||
Pn532.function = 2;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), Pn532.newdata);
|
||||
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
|
||||
return serviced;
|
||||
}
|
||||
|
@ -565,39 +544,48 @@ bool PN532_Command(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
|
||||
bool Xsns40(uint8_t function)
|
||||
{
|
||||
#ifdef USE_WEBSERVER
|
||||
void PN532_Show(void) {
|
||||
WSContentSend_PD(PSTR("{s}PN532 UID{m}%s {e}"), Pn532.uids);
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xsns40(uint8_t function) {
|
||||
bool result = false;
|
||||
|
||||
switch (function) {
|
||||
case FUNC_INIT:
|
||||
PN532_Init();
|
||||
result = true;
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
break;
|
||||
case FUNC_EVERY_100_MSECOND:
|
||||
break;
|
||||
case FUNC_EVERY_250_MSECOND:
|
||||
if (pn532_scantimer > 0) {
|
||||
pn532_scantimer--;
|
||||
} else {
|
||||
PN532_ScanForTag();
|
||||
}
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
break;
|
||||
if (FUNC_INIT == function) {
|
||||
PN532_Init();
|
||||
}
|
||||
else if (Pn532.present) {
|
||||
switch (function) {
|
||||
case FUNC_EVERY_250_MSECOND:
|
||||
if (Pn532.scantimer > 0) {
|
||||
Pn532.scantimer--;
|
||||
} else {
|
||||
PN532_ScanForTag();
|
||||
}
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_SENSOR:
|
||||
PN532_Show();
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
#ifdef USE_PN532_DATA_FUNCTION
|
||||
case FUNC_COMMAND_SENSOR:
|
||||
if (XSNS_40 == XdrvMailbox.index) {
|
||||
result = PN532_Command();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case FUNC_COMMAND_SENSOR:
|
||||
if (XSNS_40 == XdrvMailbox.index) {
|
||||
result = PN532_Command();
|
||||
}
|
||||
break;
|
||||
#endif // USE_PN532_DATA_FUNCTION
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_PN532_HSU
|
||||
#endif // USE_PN532_HSU
|
||||
|
|
|
@ -51,11 +51,11 @@ void RC522ScanForTag(void) {
|
|||
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. And if present, select one.
|
||||
if (!Mfrc522->PICC_IsNewCardPresent() || !Mfrc522->PICC_ReadCardSerial()) { return; }
|
||||
|
||||
MFRC522::PICC_Type piccType = Mfrc522->PICC_GetType(Mfrc522->uid.sak);
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("MFR: Type %s"), Mfrc522->PICC_GetTypeName(piccType));
|
||||
|
||||
ToHex_P((unsigned char*)Mfrc522->uid.uidByte, Mfrc522->uid.size, Rc522.uids, sizeof(Rc522.uids));
|
||||
|
||||
MFRC522::PICC_Type piccType = Mfrc522->PICC_GetType(Mfrc522->uid.sak);
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("MFR: UID %s, Type %s"), Rc522.uids, Mfrc522->PICC_GetTypeName(piccType));
|
||||
|
||||
#ifdef USE_RC522_DATA_FUNCTION
|
||||
bool didit = false;
|
||||
if ( piccType == MFRC522::PICC_TYPE_MIFARE_MINI
|
||||
|
@ -82,15 +82,15 @@ void RC522ScanForTag(void) {
|
|||
}
|
||||
}
|
||||
didit = true;
|
||||
ResponseTime_P(PSTR(",\"MFRC522\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\"}}"), Rc522.uids, card_datas);
|
||||
ResponseTime_P(PSTR(",\"RC522\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\"}}"), Rc522.uids, card_datas);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!didit) {
|
||||
ResponseTime_P(PSTR(",\"MFRC522\":{\"UID\":\"%s\"}}"), Rc522.uids);
|
||||
ResponseTime_P(PSTR(",\"RC522\":{\"UID\":\"%s\"}}"), Rc522.uids);
|
||||
}
|
||||
#else
|
||||
ResponseTime_P(PSTR(",\"MFRC522\":{\"UID\":\"%s\"}}"), Rc522.uids);
|
||||
ResponseTime_P(PSTR(",\"RC522\":{\"UID\":\"%s\"}}"), Rc522.uids);
|
||||
#endif
|
||||
MqttPublishTeleSensor();
|
||||
|
||||
|
@ -114,9 +114,9 @@ void RC522Init(void) {
|
|||
case 0x88: strcpy_P(ver, PSTR("clone")); break;
|
||||
case 0x00: case 0xFF: strcpy_P(ver, PSTR("fail")); break;
|
||||
}
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("MFR: MFRC522 Rfid reader %s"), ver);
|
||||
uint8_t empty_uid[4] = { 0 };
|
||||
ToHex_P((unsigned char*)empty_uid, sizeof(empty_uid), Rc522.uids, sizeof(Rc522.uids));
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("MFR: RC522 Rfid Reader detected %s"), ver);
|
||||
Rc522.present = true;
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ void RC522Init(void) {
|
|||
|
||||
#ifdef USE_WEBSERVER
|
||||
void RC522Show(void) {
|
||||
WSContentSend_PD(PSTR("{s}MFRC522 UID{m}%s {e}"), Rc522.uids);
|
||||
WSContentSend_PD(PSTR("{s}RC522 UID{m}%s {e}"), Rc522.uids);
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
|
@ -132,8 +132,7 @@ void RC522Show(void) {
|
|||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xsns80(uint8_t function)
|
||||
{
|
||||
bool Xsns80(uint8_t function) {
|
||||
bool result = false;
|
||||
|
||||
if (FUNC_INIT == function) {
|
||||
|
|
Loading…
Reference in New Issue