1

I'm trying to write a byte array that was converted from a hex string into the memory of an NTAG203 RFID tag. I'm using a Raspberry Pi 3, a PN532 chip and the Adafruit PN532 python library.

hex_string = '59e7168f267df300018e15b0'
formatted_hex = bytearray.fromhex(hex_string)

byte_data = bytearray(16)
byte_data[3:15] = formatted_hex

if not pn532.mifare_classic_write_block(4, byte_data):
    print('Error! Failed to write to the card.')
    sys.exit(-1)

When I do pn532.mifare_classic_read_block(4) to read the value from memory again it comes out like this:

print '0x{0}'.format(binascii.hexlify(<function call result>))
>>> 0x00000059440300fe0000000000000000

The value is chopped off and has trailing and leading zeroes. What is happening here?

I would like to be able to convert the value back into hex again to use it to search a database.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
Sai
  • 153
  • 5
  • What do you expect `pn532.mifare_classic_read_block(4)` to return? – wwii Jan 23 '18 at 15:26
  • The documentation says: "If the block is successfully read a bytearray of length 16 with data starting at the specified block will be returned." – Sai Jan 23 '18 at 15:27
  • Have you checked `type()` and `len()`? maybe you aren't reading successfully or you are reading the wrong block or you didn't write correctly. – wwii Jan 23 '18 at 19:39
  • I got and 34. Maybe the library is for MiFare cards only and block 4 on the NTAG203 is in a different position? – Sai Jan 25 '18 at 09:04

1 Answers1

1

First of all, functions named mifare_classic_* might not be well suited for accessing NTAG203 tags since MIFARE Classic and NTAG203 use deviating framing and command sets.

However, the PN532 abstracts access to MIFARE Classic tags using a command set that is somewhat supported by NTAG203 tags. More specifically,

  • the READ commands are identical (both read 16 bytes of data starting at a given block number). The only difference is the memory organization on NTAG203 compared to MIFARE Classic. While MIFARE Classic has 16 bytes per block, NTAG203 only has 4 bytes per block. As a result, the READ command returns 4 consecutive blocks.

  • the MIFARE Classic WRITE command is supported as COMPATIBILITY WRITE c command by NTAG203. The only difference is that you can only write 4 bytes (one block) on NTAG203. Thus, since you still have to provide 16 bytes of data in the write command, only the first 4 bytes are written.

And this is exactly what you observed: pn532.mifare_classic_write_block(4, byte_data) writes only the first 4 bytes of byte_data to block 4. Note that the first 4 bytes are 00 00 00 59 since you copy formatted_hex to the slice 3:15 and leave bytes 0..2 at their default value of 0. Since the READ command reads 16 bytes (4 blocks with 4 bytes each), the read data also contains some old memory content for blocks 5..7: 440300fe0000000000000000. That value looks reasonable since that matches the initial memory contents that's factory programmed on NTAG203.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • Thanks for taking the time to help! So to be able to write a bytearray with the length of 12 to memory I would have to use the COMPATIBILITY WRITE command 3 times with 4 bytes each time? How do I specify which block to write to, is that what the 4 in the function call stands for? – Sai Jan 26 '18 at 11:38
  • 1
    @Sai Correct. You would call the write method for each block. The first argument of `pn532.mifare_classic_write_block()` (4 in the code above) is the block number. – Michael Roland Jan 26 '18 at 12:32