androidreact-nativenfcreact-native-ioscore-nfc

Android NFC: How transceive method working with memory?


I have ntag213. I'm trying to understand how work blocks, sections of memory of my tag. I found project https://github.com/lepunk/react-native-nfc-demo/blob/master/RNNFCDemo/App.js but cannot understand what is agruments for transceive method:

let text = this.state.text;
        let fullLength = text.length + 7;
        let payloadLength = text.length + 3;

        let cmd = Platform.OS === 'ios' ? NfcManager.sendMifareCommandIOS : NfcManager.transceive;

        resp = await cmd([0xA2, 0x04, 0x03, fullLength, 0xD1, 0x01]); // 0x0C is the length of the entry with all the fluff (bytes + 7)
        resp = await cmd([0xA2, 0x05, payloadLength, 0x54, 0x02, 0x65]); // 0x54 = T = Text block, 0x08 = length of string in bytes + 3

What it the arguments in every cmd?


Solution

  • You need to read Section 10 of the datasheet for the card e.g. https://www.nxp.com/docs/en/data-sheet/NTAG213_215_216.pdf

    Basically with the write command (the 0xA2 first byte of the array), then you need to give it the block address, in first command this is block 4 and then block 5 (note block 4 is the first one you can write to) and then the next 4 bytes of data (as you can only write one 4 byte block at once).

    So basically the commands are

    [Write Command, Block Address, Data1 Byte, Data2 Byte, Data3 Byte, Data4 Byte]

    So overall that code is encoding some text in a custom format to the card. Blocks 4 and 5 are header blocks for the custom format, then it writes the text in 4 byte chucks to blocks 6 onwards all with no checking that each write was a success (other than logging the response)

    Update: to answer question

    for

    let currentPage = 6;
                let currentPayload = [0xA2, currentPage, 0x6E];
    
                for(let i=0; i<text.length; i++){
                    currentPayload.push(text.charCodeAt(i));
                    if (currentPayload.length == 6){
                        resp = await cmd(currentPayload);
                        currentPage += 1;
                        currentPayload = [0xA2, currentPage];
                    }
                }
    
    

    This loop starts at the next free page after the headers (page/block 6)

    A valid transceive command is 6 bytes long as detailed before.

    It defines a currentPayload as partial command of 3 bytes long.
    Then it iterates over the text string in a loop adding characters one at a time until the transceive command reaches 6 bytes long and then sends it. After that it increases the page number and resets the base partial command to 2 bytes long.

    payload.length == 6 is how it detects a write command has all the data it can take ( 1 byte command + 1 byte address + 4 bytes data = 6 bytes in length)

    This is a method of splitting a variable length text string to fit in to multiple 6 byte write commands (which have 4 bytes of data).

    On further thought this possibly looks like it is trying to write a NDEF text record but I would need to check the NDEF spec in more detail to confirm it.