diff --git a/tasmota/xsns_40_pn532.ino b/tasmota/xsns_40_pn532.ino index 2a2daee54..535f6cf07 100644 --- a/tasmota/xsns_40_pn532.ino +++ b/tasmota/xsns_40_pn532.ino @@ -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 diff --git a/tasmota/xsns_80_mfrc522.ino b/tasmota/xsns_80_mfrc522.ino index 1356a343a..01b944b28 100644 --- a/tasmota/xsns_80_mfrc522.ino +++ b/tasmota/xsns_80_mfrc522.ino @@ -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) {