From e7600ac83a0f05643dfa1df3343d7dd17af1812e Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Tue, 25 Oct 2022 20:16:23 +0300 Subject: [PATCH 01/17] Add support NTAG21x and NTAG20x cards. NTAG21x support password authentication --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 270 ++++++++++++++++-- 1 file changed, 247 insertions(+), 23 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index 03eba20c7..62615c9bc 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -16,6 +16,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) + #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) +// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram) #ifdef USE_PN532_HSU /*********************************************************************************************\ @@ -47,24 +50,48 @@ TasmotaSerial *PN532_Serial; #define PN532_COMMAND_SAMCONFIGURATION 0x14 #define PN532_COMMAND_RFCONFIGURATION 0x32 #define PN532_COMMAND_INDATAEXCHANGE 0x40 +#define PN532_COMMAND_INCOMMUNICATETHRU 0x42 #define PN532_COMMAND_INLISTPASSIVETARGET 0x4A - +#define PN532_COMMAND_INRELEASE 0x52 +#define PN532_COMMAND_INSELECT 0x54 #define PN532_MIFARE_ISO14443A 0x00 #define MIFARE_CMD_READ 0x30 #define MIFARE_CMD_AUTH_A 0x60 #define MIFARE_CMD_AUTH_B 0x61 #define MIFARE_CMD_WRITE 0xA0 +#define NTAG21X_CMD_GET_VERSION 0x60 +#define NTAG21X_CMD_READ 0x30 +#define NTAG21X_CMD_FAST_READ 0x3A +#define NTAG21X_CMD_PWD_AUTH 0x1B + +const struct { + uint8_t version[6]; + uint8_t confPage; +} NTAG[] PROGMEM ={ + {.version={0x04, 0x02, 0x01, 0x00, 0x0f, 0x03},.confPage=0x29}, /* NTAG213 */ + {.version={0x04, 0x02, 0x01, 0x00, 0x11, 0x03},.confPage=0x83}, /* NTAG215 */ + {.version={0x04, 0x02, 0x01, 0x00, 0x13, 0x03},.confPage=0xe3}, /* NTAG216 */ + {.version={0x04, 0x05, 0x02, 0x02, 0x13, 0x03},.confPage=0xe3}, /* NT3H2111 */ + {.version={0x04, 0x05, 0x02, 0x02, 0x15, 0x03},.confPage=0xe3}, /* NT3H2211 */ +}; +#define NTAG_CNT (sizeof(NTAG)/7) // num records in NTAG array + 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 + uint16_t atqa; #ifdef USE_PN532_DATA_FUNCTION - uint8_t newdata[16]; + uint8_t newdata[33]; uint8_t function = 0; - uint8_t newdata_len = 0; +// uint8_t newdata_len = 0; + uint32_t pwd_auth=0x64636261; + uint16_t pwd_pack=0x6665; + uint32_t pwd_auth_new; + uint16_t pwd_pack_new; #endif // USE_PN532_DATA_FUNCTION } Pn532; @@ -273,9 +300,9 @@ bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidL return 0; } - uint16_t sens_res = Pn532.packetbuffer[2]; - sens_res <<= 8; - sens_res |= Pn532.packetbuffer[3]; + Pn532.atqa = Pn532.packetbuffer[2]; + Pn532.atqa <<= 8; + Pn532.atqa |= Pn532.packetbuffer[3]; /* Card appears to be Mifare Classic */ *uidLength = Pn532.packetbuffer[5]; @@ -310,6 +337,25 @@ bool PN532_SAMConfig(void) { return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))); } +void PN532_inRelease(void) { + Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE; + Pn532.packetbuffer[1] = 1; + if (PN532_writeCommand(Pn532.packetbuffer, 2)) { + return; + } + PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)); +} + +void PN532_inSelect(void) { + Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT; + Pn532.packetbuffer[1] = 1; + if (PN532_writeCommand(Pn532.packetbuffer, 2)) { + return ; + } + int16_t res = PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: Select %d %x"), res, Pn532.packetbuffer[0]); +} + #ifdef USE_PN532_DATA_FUNCTION uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) { @@ -393,19 +439,151 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))); } +uint8_t ntag21x_probe (void) { + uint8_t result=0; + + Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; + Pn532.packetbuffer[1] = NTAG21X_CMD_GET_VERSION; + + if (PN532_writeCommand(Pn532.packetbuffer, 2)) { + return result; + } + + if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))<9){ + return result; + } + +/* AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: NTAG Version %02x %02x %02x %02x %02x %02x %02x %02x %02x"), + Pn532.packetbuffer[0],Pn532.packetbuffer[1],Pn532.packetbuffer[2],Pn532.packetbuffer[3], + Pn532.packetbuffer[4],Pn532.packetbuffer[5],Pn532.packetbuffer[6],Pn532.packetbuffer[7], + Pn532.packetbuffer[8]); + */ + if (Pn532.packetbuffer[3] != 4) { // not NTAG type + return result; + } + + for (uint8_t i=0; i0) { + /* NTAG EV1 found*/ + str_pwd=PWD_NONE; + if (!ntag21x_read32(card_datas, sizeof(card_datas))) { + if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { + if (memcmp(uid, nuid, sizeof(uid))==0) { + if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;} + if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; + } + } + } + + } else { + if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { + if (memcmp(uid, nuid, sizeof(uid))==0) { + if (!ntag20x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; + } + } + } + } else 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)) { @@ -415,7 +593,7 @@ void PN532_ScanForTag(void) { 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])))) { + if (isprint(card_data[i])) { card_datas[i] = char(card_data[i]); } else { card_datas[i] = '\0'; @@ -424,11 +602,12 @@ void PN532_ScanForTag(void) { #endif // USE_PN532_DATA_RAW } if (Pn532.function == 1) { // erase block 1 of card +//TODO : Test for (uint32_t i = 0;i<16;i++) { card_data[i] = 0x00; } if (mifareclassic_WriteDataBlock(1, card_data)) { - erase_success = true; + success = true; AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success")); memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string } @@ -437,14 +616,14 @@ void PN532_ScanForTag(void) { #ifdef USE_PN532_DATA_RAW memcpy(&card_data,&Pn532.newdata,sizeof(card_data)); if (mifareclassic_WriteDataBlock(1, card_data)) { - set_success = true; + success = true; AddLog(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]))) { + if (!isprint(Pn532.newdata[i])) { IsAlphaNumeric = false; } } @@ -452,7 +631,7 @@ void PN532_ScanForTag(void) { 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; + success = true; AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful")); memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string } @@ -467,24 +646,35 @@ void PN532_ScanForTag(void) { } switch (Pn532.function) { case 0x01: - if (!erase_success) { + if (!success) { AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode")); } break; case 0x02: - if (!set_success) { + if (!success) { AddLog(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); + ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\""), Pn532.uids, card_datas); + if (str_pwd == PWD_NONE) { + ResponseAppend_P(PSTR(",\"Auth\":\"None\"")); + } else + if (str_pwd == PWD_OK) { + ResponseAppend_P(PSTR(",\"Auth\":\"Ok\"")); + } else + if (str_pwd == PWD_NOK) { + ResponseAppend_P(PSTR(",\"Auth\":\"NOk\"")); + } + ResponseAppend_P(PSTR("}}")); #else ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids); #endif // USE_PN532_DATA_FUNCTION MqttPublishTeleSensor(); + PN532_inRelease(); Pn532.scantimer = 7; // Ignore tags found for two seconds } } @@ -501,19 +691,23 @@ bool PN532_Command(void) { return serviced; } char argument[XdrvMailbox.data_len]; +/* for (uint32_t ca=0;ca 1) { + } else + if (!strcmp(argument,"S")) { + if (ArgC() > 1) { if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') { serviced = false; return serviced; @@ -528,6 +722,36 @@ bool PN532_Command(void) { ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}")); return serviced; } + } else + if (!strncmp_P(argument,PSTR("AUTH"),4)) { + if (ArgC() > 1) { + Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0); + AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_auth); + ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"NTAG_PWD\"}}")); + } + if (ArgC() > 2) { + Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0); + AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_pack); + } + return true; + } else + if (!strncmp_P(argument,PSTR("SET_PWD"),7)) { + ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}")); + Pn532.pwd_auth_new=Pn532.pwd_auth; + Pn532.pwd_pack_new=Pn532.pwd_pack; + if (ArgC() > 1) { + Pn532.pwd_auth_new=strtoul(ArgV(argument,2),nullptr,0); + } + if (ArgC() > 2) { + Pn532.pwd_pack_new=strtoul(ArgV(argument,3),nullptr,0); + } + Pn532.function = 3; + return true; + } else + if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) { + ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}")); + Pn532.function = 4; + return true; } return false; } From b419e69759de4c0ccb8017fcdac1c741c6346241 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Tue, 25 Oct 2022 20:18:31 +0300 Subject: [PATCH 02/17] Defines --- tasmota/my_user_config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 51ea0d677..ddb3912a5 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -776,8 +776,8 @@ #define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max) // #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) -//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) -// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) +#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) + #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) // #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram) //#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8) //#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) From 5db8fcd0d051a44e62039956eec974c56f056ab5 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Tue, 25 Oct 2022 22:38:12 +0300 Subject: [PATCH 03/17] refactoring mifare classic --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 68 ++++++------------- 1 file changed, 20 insertions(+), 48 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index 62615c9bc..fe105f8ce 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -18,7 +18,6 @@ */ #define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) -// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram) #ifdef USE_PN532_HSU /*********************************************************************************************\ @@ -85,9 +84,9 @@ struct PN532 { bool present = false; // Maintain detection flag uint16_t atqa; #ifdef USE_PN532_DATA_FUNCTION - uint8_t newdata[33]; + uint8_t newdata[16]; uint8_t function = 0; -// uint8_t newdata_len = 0; + uint8_t newdata_len = 0; uint32_t pwd_auth=0x64636261; uint16_t pwd_pack=0x6665; uint32_t pwd_auth_new; @@ -587,58 +586,29 @@ void PN532_ScanForTag(void) { 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)); -#else - for (uint32_t i = 0;i < sizeof(card_data);i++) { - if (isprint(card_data[i])) { - card_datas[i] = char(card_data[i]); - } else { - card_datas[i] = '\0'; + if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) { + for (uint32_t i = 0;i < sizeof(card_datas);i++) { + if (!isprint(card_datas[i])) { + // do not output non-printable characters to the console + card_datas[i] = 0; } } -#endif // USE_PN532_DATA_RAW + } else { + card_datas[0] = 0; } if (Pn532.function == 1) { // erase block 1 of card -//TODO : Test - for (uint32_t i = 0;i<16;i++) { - card_data[i] = 0x00; - } - if (mifareclassic_WriteDataBlock(1, card_data)) { + memset(card_datas,0,sizeof(card_datas)); + if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) { success = true; AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success")); - memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string } - } + } else if (Pn532.function == 2) { -#ifdef USE_PN532_DATA_RAW - memcpy(&card_data,&Pn532.newdata,sizeof(card_data)); - if (mifareclassic_WriteDataBlock(1, card_data)) { + memcpy(&card_datas,&Pn532.newdata,sizeof(card_datas)); + if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) { success = true; AddLog(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 (!isprint(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)) { - success = true; - AddLog(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(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data must be alphanumeric")); - } -#endif // USE_PN532_DATA_RAW } } else { sprintf_P(card_datas, PSTR("AUTHFAIL")); @@ -713,10 +683,12 @@ bool PN532_Command(void) { return serviced; } ArgV(argument, 2); - Pn532.newdata_len = strlen(argument); - if (Pn532.newdata_len > 15) { Pn532.newdata_len = 15; } - memcpy(&Pn532.newdata,&argument,Pn532.newdata_len); - Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string +// Pn532.newdata_len = strlen(argument); +// if (Pn532.newdata_len > 15) { Pn532.newdata_len = 15; } +// memcpy(&Pn532.newdata,&argument,Pn532.newdata_len); +// Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string + strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata)); + Pn532.newdata[sizeof(Pn532.newdata)-1]=0; Pn532.function = 2; AddLog(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\"}}")); From 3e3dfa35d33db379267102de737fb30cab0df5c7 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Tue, 25 Oct 2022 23:14:27 +0300 Subject: [PATCH 04/17] refactoring mifare classic stage 2 --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index fe105f8ce..fee1302f8 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -86,7 +86,7 @@ struct PN532 { #ifdef USE_PN532_DATA_FUNCTION uint8_t newdata[16]; uint8_t function = 0; - uint8_t newdata_len = 0; +// uint8_t newdata_len = 0; uint32_t pwd_auth=0x64636261; uint16_t pwd_pack=0x6665; uint32_t pwd_auth_new; @@ -586,16 +586,6 @@ void PN532_ScanForTag(void) { 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, (uint8_t *)card_datas)) { - for (uint32_t i = 0;i < sizeof(card_datas);i++) { - if (!isprint(card_datas[i])) { - // do not output non-printable characters to the console - card_datas[i] = 0; - } - } - } else { - card_datas[0] = 0; - } if (Pn532.function == 1) { // erase block 1 of card memset(card_datas,0,sizeof(card_datas)); if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) { @@ -610,6 +600,16 @@ void PN532_ScanForTag(void) { AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful")); } } + if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) { + for (uint32_t i = 0;i < sizeof(card_datas);i++) { + if (!isprint(card_datas[i])) { + // do not output non-printable characters to the console + card_datas[i] = 0; + } + } + } else { + card_datas[0] = 0; + } } else { sprintf_P(card_datas, PSTR("AUTHFAIL")); } From b35479559db49acb94014bbcf3c55151561a1b5b Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Tue, 25 Oct 2022 23:15:58 +0300 Subject: [PATCH 05/17] Delete #define USE_PN532_DATA_RAW --- tasmota/my_user_config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index ddb3912a5..1838b9096 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -778,7 +778,6 @@ //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) #define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) -// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram) //#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8) //#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM) From 37df680a80720d6b6a2de45870cac171c91b2fc1 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Wed, 26 Oct 2022 00:15:04 +0300 Subject: [PATCH 06/17] Refactoring mifare classic, stage 3 --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index fee1302f8..50bb6e02a 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -82,11 +82,10 @@ struct PN532 { 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 - uint16_t atqa; #ifdef USE_PN532_DATA_FUNCTION - uint8_t newdata[16]; + uint16_t atqa; + uint8_t newdata[32]; uint8_t function = 0; -// uint8_t newdata_len = 0; uint32_t pwd_auth=0x64636261; uint16_t pwd_pack=0x6665; uint32_t pwd_auth_new; @@ -601,12 +600,13 @@ void PN532_ScanForTag(void) { } } if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) { - for (uint32_t i = 0;i < sizeof(card_datas);i++) { + for (uint32_t i = 0; i < 16;i++) { if (!isprint(card_datas[i])) { // do not output non-printable characters to the console card_datas[i] = 0; } } + card_datas[16] = 0; } else { card_datas[0] = 0; } @@ -661,13 +661,6 @@ bool PN532_Command(void) { return serviced; } char argument[XdrvMailbox.data_len]; -/* - for (uint32_t ca=0;ca 15) { Pn532.newdata_len = 15; } -// memcpy(&Pn532.newdata,&argument,Pn532.newdata_len); -// Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata)); - Pn532.newdata[sizeof(Pn532.newdata)-1]=0; + if (strlen(argument)>16) argument[16]=0; Pn532.function = 2; - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), Pn532.newdata); + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument); ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}")); return serviced; } From 0487cf9eaa5ea074c194078ca416c023a62356d7 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Wed, 26 Oct 2022 00:50:07 +0300 Subject: [PATCH 07/17] renamed the commands Sensor40, increased recording to 32 --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 75 ++++++++++--------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index 50bb6e02a..7e40e58d3 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -395,46 +395,51 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t 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) */ + for (uint8_t i = 0; i < 2; i++) { + 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 + i; /* 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)); + + /* 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[i<<4], &Pn532.packetbuffer[1], 16); } - - /* 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; - } - - /* 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; } 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 */ + for (uint8_t i = 0; i < 2; i++) { + 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 + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */ + memcpy(&Pn532.packetbuffer[4], &data[i<<4], 16); /* Data Payload */ /* Send the command */ - if (PN532_writeCommand(Pn532.packetbuffer, 20)) { - return 0; - } - + if (PN532_writeCommand(Pn532.packetbuffer, 20)) { + return 0; + } /* Read the response packet */ - return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))); + if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) { + return 0; + } + } + return 1; } uint8_t ntag21x_probe (void) { @@ -600,13 +605,13 @@ void PN532_ScanForTag(void) { } } if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) { - for (uint32_t i = 0; i < 16;i++) { + for (uint32_t i = 0; i < 32;i++) { if (!isprint(card_datas[i])) { // do not output non-printable characters to the console card_datas[i] = 0; } } - card_datas[16] = 0; + card_datas[32] = 0; } else { card_datas[0] = 0; } @@ -663,13 +668,13 @@ bool PN532_Command(void) { char argument[XdrvMailbox.data_len]; ArgV(argument, 1); UpperCase(argument,argument); - if (!strcmp(argument,"E")) { + if (!strncmp_P(argument,PSTR("ERASE"),5)) { Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00... AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased")); ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"E\"}}")); return serviced; } else - if (!strcmp(argument,"S")) { + if (!strncmp_P(argument,PSTR("WRITE"),5)) { if (ArgC() > 1) { if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') { serviced = false; @@ -677,7 +682,7 @@ bool PN532_Command(void) { } ArgV(argument, 2); strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata)); - if (strlen(argument)>16) argument[16]=0; + if (strlen(argument)>32) argument[32]=0; Pn532.function = 2; AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument); ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}")); From 9534838c19cb93f2ea6926058c5d431301088598 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Wed, 26 Oct 2022 00:56:44 +0300 Subject: [PATCH 08/17] renamed the commands Sensor40, increased recording to 32, stage 2 --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index 7e40e58d3..35bbfd5e6 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -671,7 +671,7 @@ bool PN532_Command(void) { if (!strncmp_P(argument,PSTR("ERASE"),5)) { Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00... AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased")); - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"E\"}}")); + ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}")); return serviced; } else if (!strncmp_P(argument,PSTR("WRITE"),5)) { @@ -685,7 +685,7 @@ bool PN532_Command(void) { if (strlen(argument)>32) argument[32]=0; Pn532.function = 2; AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument); - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}")); + ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}")); return serviced; } } else From 0887ec31f54e4ebc738cefd110d133f567c2996c Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Wed, 26 Oct 2022 01:29:10 +0300 Subject: [PATCH 09/17] Reduced 16 bytes --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index 35bbfd5e6..c6823d259 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -421,7 +421,7 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) { return 1; } -uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { +bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { /* Prepare the first command */ for (uint8_t i = 0; i < 2; i++) { Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; @@ -432,14 +432,14 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { /* Send the command */ if (PN532_writeCommand(Pn532.packetbuffer, 20)) { - return 0; + return false; } /* Read the response packet */ if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) { - return 0; + return false; } } - return 1; + return true; } uint8_t ntag21x_probe (void) { @@ -575,6 +575,12 @@ void PN532_ScanForTag(void) { if (memcmp(uid, nuid, sizeof(uid))==0) { if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;} if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; + if (Pn532.command == 1) { + /* Erase */ + } else + if (Pn532.command == 2) { + /* Write */ + } } } } @@ -587,20 +593,17 @@ void PN532_ScanForTag(void) { } } } else - if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information + if (uid_len == 4) { // Lets try to read blocks 1 & 2 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 (Pn532.function == 1) { // erase block 1 of card + if (Pn532.function == 1) { // erase blocks 1 & 2 of card memset(card_datas,0,sizeof(card_datas)); - if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) { - success = true; + if ((success=mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas))) { AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success")); } } else if (Pn532.function == 2) { - memcpy(&card_datas,&Pn532.newdata,sizeof(card_datas)); - if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) { - success = true; + if ((success=mifareclassic_WriteDataBlock(1, Pn532.newdata))) { AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful")); } } From 97230fe456ec1328cdca325b0e36c05a64a59118 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Wed, 26 Oct 2022 19:21:50 +0300 Subject: [PATCH 10/17] Removed the duplicated functionality --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 74 +++++-------------- 1 file changed, 18 insertions(+), 56 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index c6823d259..3e8224d7a 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -472,29 +472,6 @@ uint8_t ntag21x_probe (void) { return result; //Return configuration page address } -bool ntag21x_read32(char *out, uint8_t out_len) { - - if (out_len<33) return false; - - Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; - Pn532.packetbuffer[1] = NTAG21X_CMD_FAST_READ; - Pn532.packetbuffer[2] = 0x04; // first page - Pn532.packetbuffer[3] = 0x0b; // last page - if (PN532_writeCommand(Pn532.packetbuffer, 4)) { - return false; - } - if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<33){ - return false; - } - - if (Pn532.packetbuffer[0]!=0) { - return false; - } - memcpy(out,&Pn532.packetbuffer[1],out_len); - out[32]=0; - return true; -} - bool ntag21x_auth(void) { Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; Pn532.packetbuffer[1] = NTAG21X_CMD_PWD_AUTH; @@ -512,41 +489,26 @@ bool ntag21x_auth(void) { return memcmp(&Pn532.packetbuffer[1],&Pn532.pwd_pack,2)==0; } -bool ntag20x_read32(char *out, uint8_t out_len) { +bool ntag2xx_read32(char *out, uint8_t out_len) { if (out_len<33) return false; + for (uint8_t i = 0; i < 2; i++) { + Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; + Pn532.packetbuffer[1] = NTAG21X_CMD_READ; + Pn532.packetbuffer[2] = 0x04 << i; // first page - Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; - Pn532.packetbuffer[1] = NTAG21X_CMD_READ; - Pn532.packetbuffer[2] = 0x04; // first page - - if (PN532_writeCommand(Pn532.packetbuffer, 3)) { - return false; + if (PN532_writeCommand(Pn532.packetbuffer, 3)) { + return false; + } + if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){ + return false; + } + if (Pn532.packetbuffer[0]!=0) { + return false; + } + memcpy(&out[i<<4],&Pn532.packetbuffer[1],16); } - if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){ - return false; - } - if (Pn532.packetbuffer[0]!=0) { - return false; - } - memcpy(out,&Pn532.packetbuffer[1],16); - - Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; - Pn532.packetbuffer[1] = NTAG21X_CMD_READ; - Pn532.packetbuffer[2] = 0x08; // first page - - if (PN532_writeCommand(Pn532.packetbuffer, 3)) { - return false; - } - if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){ - return false; - } - if (Pn532.packetbuffer[0]!=0) { - return false; - } - memcpy(&out[16],&Pn532.packetbuffer[1],16); out[32]=0; - return true; } @@ -570,11 +532,11 @@ void PN532_ScanForTag(void) { if ((confPage=ntag21x_probe())>0) { /* NTAG EV1 found*/ str_pwd=PWD_NONE; - if (!ntag21x_read32(card_datas, sizeof(card_datas))) { + if (!ntag2xx_read32(card_datas, sizeof(card_datas))) { if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { if (memcmp(uid, nuid, sizeof(uid))==0) { if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;} - if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; + if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; if (Pn532.command == 1) { /* Erase */ } else @@ -588,7 +550,7 @@ void PN532_ScanForTag(void) { } else { if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { if (memcmp(uid, nuid, sizeof(uid))==0) { - if (!ntag20x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; + if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; } } } From cc7936bd7e90b0df19013fae1963baedb03f726c Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Thu, 27 Oct 2022 00:48:22 +0300 Subject: [PATCH 11/17] Add password operations --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 197 ++++++++++++------ 1 file changed, 134 insertions(+), 63 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index 3e8224d7a..639a3a8c8 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -60,9 +60,10 @@ TasmotaSerial *PN532_Serial; #define MIFARE_CMD_WRITE 0xA0 #define NTAG21X_CMD_GET_VERSION 0x60 -#define NTAG21X_CMD_READ 0x30 +#define NTAG2XX_CMD_READ 0x30 #define NTAG21X_CMD_FAST_READ 0x3A #define NTAG21X_CMD_PWD_AUTH 0x1B +#define NTAG2XX_CMD_WRITE 0xA2 const struct { uint8_t version[6]; @@ -344,15 +345,14 @@ void PN532_inRelease(void) { PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)); } -void PN532_inSelect(void) { +/* void PN532_inSelect(void) { Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT; Pn532.packetbuffer[1] = 1; if (PN532_writeCommand(Pn532.packetbuffer, 2)) { return ; } int16_t res = PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)); - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: Select %d %x"), res, Pn532.packetbuffer[0]); -} +} */ #ifdef USE_PN532_DATA_FUNCTION @@ -435,7 +435,7 @@ bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { return false; } /* Read the response packet */ - if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) { + if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) { return false; } } @@ -456,23 +456,20 @@ uint8_t ntag21x_probe (void) { return result; } -/* AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: NTAG Version %02x %02x %02x %02x %02x %02x %02x %02x %02x"), - Pn532.packetbuffer[0],Pn532.packetbuffer[1],Pn532.packetbuffer[2],Pn532.packetbuffer[3], - Pn532.packetbuffer[4],Pn532.packetbuffer[5],Pn532.packetbuffer[6],Pn532.packetbuffer[7], - Pn532.packetbuffer[8]); - */ if (Pn532.packetbuffer[3] != 4) { // not NTAG type return result; } for (uint8_t i=0; i= 33 */ + + if (!ntag2xx_read16(page, out)) { + return false; + } + if (!ntag2xx_read16(page + 4, &out[16])) { + return false; } out[32]=0; return true; } +bool ntag2xx_write4(uint8_t page, char *in) { + + Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; + Pn532.packetbuffer[1] = NTAG2XX_CMD_WRITE; + Pn532.packetbuffer[2] = page; // first page + memcpy(&Pn532.packetbuffer[3],in,4); + + if (PN532_writeCommand(Pn532.packetbuffer, 7)) { + return false; + } + + if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) { + return false; + } + return true; +} + +bool ntag2xx_writeN(uint8_t page, uint8_t numPages, char *in) { + + for (uint8_t i = 0; i < numPages; i++) { + if (!ntag2xx_write4(page +i, &in[i << 2])) { + return false; + } + } + return true; +} + +bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) { + char card_datas[16]; + + if (ntag2xx_read16(confPage, card_datas)) { + if (unsetPasswd) { + card_datas[3]=0xFF; + return ntag2xx_writeN(confPage,1,card_datas); + } + card_datas[3]=0; // Set AUTH0 for protect all pages + card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification + memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password + memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack + return ntag2xx_writeN(confPage,4,card_datas); + } + return false; +} + #endif // USE_PN532_DATA_FUNCTION void PN532_ScanForTag(void) { @@ -532,42 +580,45 @@ void PN532_ScanForTag(void) { if ((confPage=ntag21x_probe())>0) { /* NTAG EV1 found*/ str_pwd=PWD_NONE; - if (!ntag2xx_read32(card_datas, sizeof(card_datas))) { + if (!ntag2xx_read32(4, card_datas)) { if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { if (memcmp(uid, nuid, sizeof(uid))==0) { - if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;} - if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; - if (Pn532.command == 1) { - /* Erase */ - } else - if (Pn532.command == 2) { - /* Write */ + if (ntag21x_auth()) { + str_pwd=PWD_OK; + if (Pn532.function == 3) { /* new password */ + success = ntag21x_set_password(confPage, false); + } + if (Pn532.function == 4) { /* clear password */ + success = ntag21x_set_password(confPage, true); + } + } else { + str_pwd=PWD_NOK; } + if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0; } } - } - + } else { + if (Pn532.function == 3) { /* new password */ + success = ntag21x_set_password(confPage, false); + } + } } else { if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { if (memcmp(uid, nuid, sizeof(uid))==0) { - if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0; + if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0; } } } - } else - if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information + if ((Pn532.function == 1) || (Pn532.function == 2)) { + success = ntag2xx_writeN(4, 8, (char *)Pn532.newdata); + if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0; + } + } + else if (uid_len == 4) { // Lets try to read blocks 1 & 2 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 (Pn532.function == 1) { // erase blocks 1 & 2 of card - memset(card_datas,0,sizeof(card_datas)); - if ((success=mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas))) { - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success")); - } - } else - if (Pn532.function == 2) { - if ((success=mifareclassic_WriteDataBlock(1, Pn532.newdata))) { - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful")); - } + if ((Pn532.function == 1) || (Pn532.function == 2)) { + success=mifareclassic_WriteDataBlock(1, Pn532.newdata); } if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) { for (uint32_t i = 0; i < 32;i++) { @@ -586,14 +637,33 @@ void PN532_ScanForTag(void) { } switch (Pn532.function) { case 0x01: - if (!success) { - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode")); + if (success) { + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Erase success")); + } else { + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Erase fail - exiting erase mode")); } break; case 0x02: - if (!success) { - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Write failed - exiting set mode")); + if (success) { + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Data write successful")); + } else{ + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Write failed - exiting set mode")); } + break; + case 0x03: + if (success) { + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Set password successful")); + } else{ + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Set password failed - exiting set mode")); + } + break; + case 0x04: + if (success) { + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Unset password successful")); + } else{ + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Unset password failed - exiting set mode")); + } + break; default: break; } @@ -634,8 +704,9 @@ bool PN532_Command(void) { ArgV(argument, 1); UpperCase(argument,argument); if (!strncmp_P(argument,PSTR("ERASE"),5)) { + memset(Pn532.newdata,0,sizeof(Pn532.newdata)); Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00... - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased")); + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be erased")); ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}")); return serviced; } else @@ -649,7 +720,7 @@ bool PN532_Command(void) { strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata)); if (strlen(argument)>32) argument[32]=0; Pn532.function = 2; - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument); + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be set to '%s'"), argument); ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}")); return serviced; } @@ -657,16 +728,15 @@ bool PN532_Command(void) { if (!strncmp_P(argument,PSTR("AUTH"),4)) { if (ArgC() > 1) { Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0); - AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_auth); - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"NTAG_PWD\"}}")); + ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"AUTH\"}}")); } if (ArgC() > 2) { Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0); - AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_pack); } return true; } else if (!strncmp_P(argument,PSTR("SET_PWD"),7)) { + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will set password")); ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}")); Pn532.pwd_auth_new=Pn532.pwd_auth; Pn532.pwd_pack_new=Pn532.pwd_pack; @@ -680,8 +750,9 @@ bool PN532_Command(void) { return true; } else if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) { - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}")); - Pn532.function = 4; + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will unset password")); + ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}")); + Pn532.function = 4; return true; } return false; From b877c174b1fd5923041663ab91c9c87e55c1805a Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Thu, 27 Oct 2022 19:23:11 +0300 Subject: [PATCH 12/17] Ready fo test (32 bytes) --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index 639a3a8c8..e55a9d94d 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -83,8 +83,8 @@ struct PN532 { 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 uint16_t atqa; +#ifdef USE_PN532_DATA_FUNCTION uint8_t newdata[32]; uint8_t function = 0; uint32_t pwd_auth=0x64636261; @@ -336,15 +336,6 @@ bool PN532_SAMConfig(void) { return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))); } -void PN532_inRelease(void) { - Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE; - Pn532.packetbuffer[1] = 1; - if (PN532_writeCommand(Pn532.packetbuffer, 2)) { - return; - } - PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)); -} - /* void PN532_inSelect(void) { Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT; Pn532.packetbuffer[1] = 1; @@ -356,6 +347,15 @@ void PN532_inRelease(void) { #ifdef USE_PN532_DATA_FUNCTION +void PN532_inRelease(void) { + Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE; + Pn532.packetbuffer[1] = 1; + if (PN532_writeCommand(Pn532.packetbuffer, 2)) { + return; + } + PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)); +} + 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]; @@ -679,12 +679,12 @@ void PN532_ScanForTag(void) { ResponseAppend_P(PSTR(",\"Auth\":\"NOk\"")); } ResponseAppend_P(PSTR("}}")); + PN532_inRelease(); #else ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids); #endif // USE_PN532_DATA_FUNCTION MqttPublishTeleSensor(); - PN532_inRelease(); Pn532.scantimer = 7; // Ignore tags found for two seconds } } @@ -706,7 +706,7 @@ bool PN532_Command(void) { if (!strncmp_P(argument,PSTR("ERASE"),5)) { memset(Pn532.newdata,0,sizeof(Pn532.newdata)); Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00... - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be erased")); + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block will be erased")); ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}")); return serviced; } else From 116affb2fa8dd2cf928eb1a3069a40fe50843901 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Fri, 28 Oct 2022 01:12:33 +0300 Subject: [PATCH 13/17] 16 bytes operational --- tasmota/my_user_config.h | 4 +- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 177 ++++++++---------- 2 files changed, 82 insertions(+), 99 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 1838b9096..6bafe2c6a 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -776,8 +776,8 @@ #define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max) // #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) -#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) - #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) +#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem) + #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem) //#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8) //#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index e55a9d94d..0819e2d4c 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -16,8 +16,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) - #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) #ifdef USE_PN532_HSU /*********************************************************************************************\ @@ -85,7 +83,7 @@ struct PN532 { bool present = false; // Maintain detection flag uint16_t atqa; #ifdef USE_PN532_DATA_FUNCTION - uint8_t newdata[32]; + uint8_t newdata[16]; uint8_t function = 0; uint32_t pwd_auth=0x64636261; uint16_t pwd_pack=0x6665; @@ -395,50 +393,47 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) { /* Prepare the command */ - for (uint8_t i = 0; i < 2; i++) { - 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 + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */ + 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; - } - - /* 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; - } - - /* Copy the 16 data bytes to the output buffer */ - /* Block content starts at byte 9 of a valid response */ - memcpy (&data[i<<4], &Pn532.packetbuffer[1], 16); + if (PN532_writeCommand(Pn532.packetbuffer, 4)) { + return 0; } + + /* 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; + } + + /* 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; } bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { /* Prepare the first command */ - for (uint8_t i = 0; i < 2; i++) { - 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 + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */ - memcpy(&Pn532.packetbuffer[4], &data[i<<4], 16); /* Data Payload */ + 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 false; - } - /* Read the response packet */ - if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) { - return false; - } + if (PN532_writeCommand(Pn532.packetbuffer, 20)) { + return false; } + /* Read the response packet */ + if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) { + return false; + } + return true; } @@ -504,18 +499,6 @@ bool ntag2xx_read16 (const uint8_t page, char *out) { return true; } -bool ntag2xx_read32 (const uint8_t page, char *out) { /* Size of oun must be >= 33 */ - - if (!ntag2xx_read16(page, out)) { - return false; - } - if (!ntag2xx_read16(page + 4, &out[16])) { - return false; - } - out[32]=0; - return true; -} - bool ntag2xx_write4(uint8_t page, char *in) { Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; @@ -533,9 +516,9 @@ bool ntag2xx_write4(uint8_t page, char *in) { return true; } -bool ntag2xx_writeN(uint8_t page, uint8_t numPages, char *in) { +bool ntag2xx_write16(uint8_t page, char *in) { - for (uint8_t i = 0; i < numPages; i++) { + for (uint8_t i = 0; i < 4; i++) { if (!ntag2xx_write4(page +i, &in[i << 2])) { return false; } @@ -549,13 +532,13 @@ bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) { if (ntag2xx_read16(confPage, card_datas)) { if (unsetPasswd) { card_datas[3]=0xFF; - return ntag2xx_writeN(confPage,1,card_datas); + return ntag2xx_write4(confPage, card_datas); } card_datas[3]=0; // Set AUTH0 for protect all pages card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack - return ntag2xx_writeN(confPage,4,card_datas); + return ntag2xx_write16(confPage, card_datas); } return false; } @@ -570,7 +553,7 @@ void PN532_ScanForTag(void) { #ifdef USE_PN532_DATA_FUNCTION bool success = false; - char card_datas[34]={0}; + char card_datas[17]={0}; enum {NOPWD, PWD_NONE, PWD_OK, PWD_NOK} str_pwd=NOPWD; if (Pn532.atqa == 0x44) { @@ -580,7 +563,7 @@ void PN532_ScanForTag(void) { if ((confPage=ntag21x_probe())>0) { /* NTAG EV1 found*/ str_pwd=PWD_NONE; - if (!ntag2xx_read32(4, card_datas)) { + if (!ntag2xx_read16(4, card_datas)) { if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { if (memcmp(uid, nuid, sizeof(uid))==0) { if (ntag21x_auth()) { @@ -594,7 +577,7 @@ void PN532_ScanForTag(void) { } else { str_pwd=PWD_NOK; } - if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0; + if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0; } } } else { @@ -605,13 +588,13 @@ void PN532_ScanForTag(void) { } else { if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { if (memcmp(uid, nuid, sizeof(uid))==0) { - if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0; + if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0; } } } if ((Pn532.function == 1) || (Pn532.function == 2)) { - success = ntag2xx_writeN(4, 8, (char *)Pn532.newdata); - if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0; + success = ntag2xx_write16(4, (char *)Pn532.newdata); + if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0; } } else if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information @@ -621,13 +604,12 @@ void PN532_ScanForTag(void) { success=mifareclassic_WriteDataBlock(1, Pn532.newdata); } if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) { - for (uint32_t i = 0; i < 32;i++) { + for (uint32_t i = 0; i < 16; i++) { if (!isprint(card_datas[i])) { // do not output non-printable characters to the console card_datas[i] = 0; } } - card_datas[32] = 0; } else { card_datas[0] = 0; } @@ -668,6 +650,7 @@ void PN532_ScanForTag(void) { break; } Pn532.function = 0; + card_datas[16] = 0; ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\""), Pn532.uids, card_datas); if (str_pwd == PWD_NONE) { ResponseAppend_P(PSTR(",\"Auth\":\"None\"")); @@ -692,52 +675,45 @@ void PN532_ScanForTag(void) { #ifdef USE_PN532_DATA_FUNCTION bool PN532_Command(void) { - bool serviced = true; - uint8_t paramcount = 0; - if (XdrvMailbox.data_len > 0) { - paramcount=1; - } else { - serviced = false; + bool serviced = false; + char command[10]; + char log[70]; + if (ArgC() < 1) { return serviced; } + char argument[XdrvMailbox.data_len]; ArgV(argument, 1); - UpperCase(argument,argument); - if (!strncmp_P(argument,PSTR("ERASE"),5)) { + strncpy(command,UpperCase(argument,argument),sizeof(command)); + + if (!strcmp_P(argument,PSTR("ERASE"))) { memset(Pn532.newdata,0,sizeof(Pn532.newdata)); Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00... - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block will be erased")); - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}")); - return serviced; - } else - if (!strncmp_P(argument,PSTR("WRITE"),5)) { + snprintf_P(log, sizeof(log), PSTR("data block 1 (4-7 for NTAG) will be erased")); + serviced = true; + } + if (!strcmp_P(argument,PSTR("WRITE"))) { if (ArgC() > 1) { - if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') { - serviced = false; - return serviced; - } ArgV(argument, 2); + memset(Pn532.newdata,0,sizeof(Pn532.newdata)); strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata)); - if (strlen(argument)>32) argument[32]=0; + if (strlen(argument)>16) argument[16]=0; Pn532.function = 2; - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be set to '%s'"), argument); - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}")); - return serviced; + snprintf_P(log, sizeof(log), PSTR("data block 1 (4-7 for NTAG) will be set to '%s'"), argument); + serviced = true; } - } else - if (!strncmp_P(argument,PSTR("AUTH"),4)) { + } + if (!strcmp_P(argument,PSTR("AUTH"))) { if (ArgC() > 1) { Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0); - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"AUTH\"}}")); } if (ArgC() > 2) { Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0); } - return true; - } else - if (!strncmp_P(argument,PSTR("SET_PWD"),7)) { - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will set password")); - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}")); + serviced = true; + } + if (!strcmp_P(argument,PSTR("SET_PWD"))) { + snprintf_P(log, sizeof(log), PSTR("will be protected")); Pn532.pwd_auth_new=Pn532.pwd_auth; Pn532.pwd_pack_new=Pn532.pwd_pack; if (ArgC() > 1) { @@ -747,15 +723,22 @@ bool PN532_Command(void) { Pn532.pwd_pack_new=strtoul(ArgV(argument,3),nullptr,0); } Pn532.function = 3; - return true; - } else - if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) { - AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will unset password")); - ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}")); - Pn532.function = 4; - return true; + serviced = true; } - return false; + if (!strcmp_P(argument,PSTR("UNSET_PWD"))) { + snprintf_P(log, sizeof(log), PSTR("will be unprotected")); + Pn532.function = 4; + serviced = true; + } + if (!strcmp_P(argument,PSTR("CANCEL"))) { + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Job canceled")); + Pn532.function = 0; + serviced = true; + } else { + AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag %s"), log); + } + if (serviced) ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"%s\"}}"),command); + return serviced; } #endif // USE_PN532_DATA_FUNCTION From 0d22a162401a4c5bef51d11474844ea9dee1856e Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Fri, 28 Oct 2022 01:13:27 +0300 Subject: [PATCH 14/17] Disable in default config --- tasmota/my_user_config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 6bafe2c6a..858a3725e 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -776,8 +776,8 @@ #define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max) // #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) -#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem) - #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem) +//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem) +// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem) //#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8) //#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM) From d152199aee6a181305faffaefe483b5a9218fe6e Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Fri, 28 Oct 2022 01:24:22 +0300 Subject: [PATCH 15/17] Edit formats --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index 0819e2d4c..def685769 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -396,9 +396,9 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) { 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) */ + Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ - /* Send the command */ + /* Send the command */ if (PN532_writeCommand(Pn532.packetbuffer, 4)) { return 0; } @@ -414,27 +414,25 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) { /* 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; } -bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { +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) */ + 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 false; - } - /* Read the response packet */ - if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) { - return false; + return 0; } - return true; + /* Read the response packet */ +return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))); } uint8_t ntag21x_probe (void) { From 25079bb86b1fc57525be30af79e245f5c1c5a130 Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Fri, 28 Oct 2022 01:26:24 +0300 Subject: [PATCH 16/17] Ready for PR --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index def685769..c5afefa9f 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -432,7 +432,7 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { } /* Read the response packet */ -return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))); + return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))); } uint8_t ntag21x_probe (void) { From f1f8d27079d39832f740f0260f12700c14cde36a Mon Sep 17 00:00:00 2001 From: md5sum-as Date: Sun, 30 Oct 2022 20:09:52 +0300 Subject: [PATCH 17/17] Added prefix to all functions --- tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino index c5afefa9f..aaad8602a 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino @@ -1,7 +1,7 @@ /* xsns_40_pn532.ino - Support for PN532 (HSU) NFC Tag Reader on Tasmota - Copyright (C) 2021 Andre Thomas and Theo Arends + Copyright (C) 2021 Andre Thomas, Theo Arends and md5sum-as (https://github.com/md5sum-as) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -354,7 +354,7 @@ void PN532_inRelease(void) { PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)); } -uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) { +uint8_t PN532_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]; @@ -391,7 +391,7 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t return 1; } -uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) { +uint8_t PN532_mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) { /* Prepare the command */ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; Pn532.packetbuffer[1] = 1; /* Card number */ @@ -418,7 +418,7 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) { return 1; } -uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { +uint8_t PN532_mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { /* Prepare the first command */ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; Pn532.packetbuffer[1] = 1; /* Card number */ @@ -435,7 +435,7 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) { return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))); } -uint8_t ntag21x_probe (void) { +uint8_t PN532_ntag21x_probe (void) { uint8_t result=0; Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; @@ -461,7 +461,7 @@ uint8_t ntag21x_probe (void) { return result; //Return configuration page address } -bool ntag21x_auth(void) { +bool PN532_ntag21x_auth(void) { Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; Pn532.packetbuffer[1] = NTAG21X_CMD_PWD_AUTH; @@ -479,7 +479,7 @@ bool ntag21x_auth(void) { return memcmp(&Pn532.packetbuffer[1],&Pn532.pwd_pack,2)==0; } -bool ntag2xx_read16 (const uint8_t page, char *out) { +bool PN532_ntag2xx_read16 (const uint8_t page, char *out) { Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; Pn532.packetbuffer[1] = NTAG2XX_CMD_READ; @@ -497,7 +497,7 @@ bool ntag2xx_read16 (const uint8_t page, char *out) { return true; } -bool ntag2xx_write4(uint8_t page, char *in) { +bool PN532_ntag2xx_write4(uint8_t page, char *in) { Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU; Pn532.packetbuffer[1] = NTAG2XX_CMD_WRITE; @@ -514,29 +514,29 @@ bool ntag2xx_write4(uint8_t page, char *in) { return true; } -bool ntag2xx_write16(uint8_t page, char *in) { +bool PN532_ntag2xx_write16(uint8_t page, char *in) { for (uint8_t i = 0; i < 4; i++) { - if (!ntag2xx_write4(page +i, &in[i << 2])) { + if (!PN532_ntag2xx_write4(page +i, &in[i << 2])) { return false; } } return true; } -bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) { +bool PN532_ntag21x_set_password(uint8_t confPage, bool unsetPasswd) { char card_datas[16]; - if (ntag2xx_read16(confPage, card_datas)) { + if (PN532_ntag2xx_read16(confPage, card_datas)) { if (unsetPasswd) { card_datas[3]=0xFF; - return ntag2xx_write4(confPage, card_datas); + return PN532_ntag2xx_write4(confPage, card_datas); } card_datas[3]=0; // Set AUTH0 for protect all pages card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack - return ntag2xx_write16(confPage, card_datas); + return PN532_ntag2xx_write16(confPage, card_datas); } return false; } @@ -558,50 +558,50 @@ void PN532_ScanForTag(void) { uint8_t confPage=0; uint8_t nuid[] = { 0, 0, 0, 0, 0, 0, 0 }; uint8_t nuid_len = 0; - if ((confPage=ntag21x_probe())>0) { + if ((confPage=PN532_ntag21x_probe())>0) { /* NTAG EV1 found*/ str_pwd=PWD_NONE; - if (!ntag2xx_read16(4, card_datas)) { + if (!PN532_ntag2xx_read16(4, card_datas)) { if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { if (memcmp(uid, nuid, sizeof(uid))==0) { - if (ntag21x_auth()) { + if (PN532_ntag21x_auth()) { str_pwd=PWD_OK; if (Pn532.function == 3) { /* new password */ - success = ntag21x_set_password(confPage, false); + success = PN532_ntag21x_set_password(confPage, false); } if (Pn532.function == 4) { /* clear password */ - success = ntag21x_set_password(confPage, true); + success = PN532_ntag21x_set_password(confPage, true); } } else { str_pwd=PWD_NOK; } - if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0; + if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0; } } } else { if (Pn532.function == 3) { /* new password */ - success = ntag21x_set_password(confPage, false); + success = PN532_ntag21x_set_password(confPage, false); } } } else { if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) { if (memcmp(uid, nuid, sizeof(uid))==0) { - if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0; + if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0; } } } if ((Pn532.function == 1) || (Pn532.function == 2)) { - success = ntag2xx_write16(4, (char *)Pn532.newdata); - if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0; + success = PN532_ntag2xx_write16(4, (char *)Pn532.newdata); + if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0; } } else if (uid_len == 4) { // Lets try to read blocks 1 & 2 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 (PN532_mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) { if ((Pn532.function == 1) || (Pn532.function == 2)) { - success=mifareclassic_WriteDataBlock(1, Pn532.newdata); + success=PN532_mifareclassic_WriteDataBlock(1, Pn532.newdata); } - if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) { + if (PN532_mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) { for (uint32_t i = 0; i < 16; i++) { if (!isprint(card_datas[i])) { // do not output non-printable characters to the console