Writing NDEF message with PN532

58 Views Asked by At

I am currently trying to write an NDEF message (for example www.google.com) with a PN532 board, utilizing the ndeflib library. I can read and write the blocks.

However when I tap any of the card with my phone the website won't open. I have analyzed the protocol as well as asked chatgpt to decode the block I am writing (block 6) - and it seems to be OK, still doesn't work tho.

Could you please give me some insights or ideas what am I doing wrong here?

I'll below attach the code I am using:

import adafruit_pn532.spi as PN532_SPI
import adafruit_pn532.adafruit_pn532
from digitalio import DigitalInOut
import board
import busio
import ndef
import time


def write_url_ndef_message(url):
    # Set up SPI communication with the PN532 NFC module
    spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
    cs_pin = DigitalInOut(board.D5)
    pn532 = PN532_SPI.PN532_SPI(spi, cs_pin, debug=False)

    # Configure PN532 to communicate with NFC tags
    pn532.SAM_configuration()

    ic, ver, rev, support = pn532.firmware_version
    print("Found PN532 with firmware version: {0}.{1}".format(ver, rev))

    print("Waiting for RFID/NFC card to write to!")

    key = b"\xFF\xFF\xFF\xFF\xFF\xFF"

    uri_record = ndef.UriRecord(iri=url)

    # Create an NDEF message with the URI record
    ndef_message = [uri_record]

    # Convert the NDEF message to bytes
    ndef_message_bytes = b''.join(ndef.message_encoder(ndef_message))

    print(f"printing the message created from the UriRecord: {ndef_message}")

    # Ensure the NDEF message is 16 bytes long (pad if necessary)
    if len(ndef_message_bytes) < 16:
        ndef_message_bytes += b'\x00' * (16 - len(ndef_message_bytes))

    print("length of the ndef message byte array is: ", len(ndef_message_bytes))
    print(f"printing the encoded message: {ndef_message_bytes}")

    while True:
        print('Place the card on the board...')
        uid = pn532.read_passive_target(timeout=0.5)
        # Try again until a card is available.
        if uid is not None:
            break
        else:
            time.sleep(1)

    print("Found card with UID:", [hex(i) for i in uid])

    block_to_write = 6

    print(f"Authenticating block {block_to_write}...")

    authenticated = pn532.mifare_classic_authenticate_block(uid, block_to_write,
                                                            adafruit_pn532.adafruit_pn532.MIFARE_CMD_AUTH_B,
                                                            key)

    if not authenticated:
        print("Authentication failed!")
    else:
        print(f'Authentication for block {block_to_write} has been successful')

    print(f"Now writing block {block_to_write}...")
    # Write 16 byte block.
    pn532.mifare_classic_write_block(block_to_write, ndef_message_bytes)

    print(
        f"Wrote to block {block_to_write}, now trying to read that data:",
        [hex(x) for x in pn532.mifare_classic_read_block(block_to_write)],
    )


if __name__ == "__main__":
    write_url_ndef_message("google.com")

I should also always pad the byte array to be exactly 16 bytes otherwise the write operation fails. What happens if the URL is more than 16 bytes? I know it is possible to write an NDEF message along multiple blocks but did not find much information about it, and I am even struggling with interpreting one block... Thank you in advance for your support!

0

There are 0 best solutions below