+//-----------------------------------------------------------------------------
+// Hitag2 operations
+//-----------------------------------------------------------------------------
+
+static bool hitag2_write_page(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) {
+ switch (writestate) {
+ case WRITE_STATE_START:
+ tx[0] = HITAG2_WRITE_PAGE | (blocknr << 3) | ((blocknr^7) >> 2);
+ tx[1] = ((blocknr^7) << 6);
+ *txlen = 10;
+ writestate = WRITE_STATE_PAGENUM_WRITTEN;
+ break;
+ case WRITE_STATE_PAGENUM_WRITTEN:
+ // Check if page number was received correctly
+ if ((rxlen == 10)
+ && (rx[0] == (HITAG2_WRITE_PAGE | (blocknr << 3) | ((blocknr^7) >> 2)))
+ && (rx[1] == (((blocknr & 0x3) ^ 0x3) << 6))) {
+ *txlen = 32;
+ memset(tx, 0, HITAG_FRAME_LEN);
+ memcpy(tx, writedata, 4);
+ writestate = WRITE_STATE_PROG;
+ } else {
+ Dbprintf("hitag2_write_page: Page number was not received correctly: rxlen=%d rx=%02x%02x%02x%02x",
+ rxlen, rx[0], rx[1], rx[2], rx[3]);
+ bSuccessful = false;
+ return false;
+ }
+ break;
+ case WRITE_STATE_PROG:
+ if (rxlen == 0) {
+ bSuccessful = true;
+ } else {
+ bSuccessful = false;
+ Dbprintf("hitag2_write_page: unexpected rx data (%d) after page write", rxlen);
+ }
+ return false;
+ default:
+ DbpString("hitag2_write_page: Unknown state %d");
+ bSuccessful = false;
+ return false;
+ }
+
+ return true;
+}
+
+static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool write) {