I have a a number of newbie NfcA questions. There seems to be little guidance on this in the docs and elsewhere on the web, so I hope no-one minds me stringing a few basic questions together here...
I am using nfcA.transceive() to write data to my NTAG213 tag like this:
byte[] result = nfcA.transceive(new byte[] {
(byte)0xA2, // WRITE
(byte)(pageNum & 0x0ff),
myData[0], myData[1], myData[2], myData[3]
});
1. The result
array is a single byte of value 10. What does this mean and what other values should I look out for?
I am also using the same method to read data from my NTAG213 tags:
byte[] result = nfcA.transceive(new byte[] {
(byte)0x30, // READ
(byte)(pageNum & 0x0ff)
});
2. I expected this to return 4 bytes of user data (i.e., the 4 bytes that correspond to my pageNum), but it returned 16 bytes. Why is that the case?
3. Is it good practise to check nfcA.isConnected()
before calling nfcA.connect()
and, if so, is there likely to be any sigificant performance penalty in doing so? (I ask as I have seen code examples from reputable sources of both.)
4. Is it better to call nfcA.setTimeout()
before or after nfcA.connect()
?
5. For my NTAG213 tags nfcA.getMaxTransceiveLength()
returns 253. Does that really mean I can write up to 251 bytes of user data (plus the 2 other bytes) in one go and, if so, is that advisable or is it better to write each page (4 bytes) with separate nfcA.transceive()
calls?
The value 10 (Ah in hexadecimal or 1010b in binary representation) is an explicit ACK, an acknowledgement returned when a command that returns no data succeeds.
The possible values are actual data, ACK, passive ACK, or NACK. These are defined by the NFC Forum Digital Protocol specification and by the NFC Forum Type 2 Tag Operation specification.
The NTAG213/215/216 product data sheet is a bit more specific on possible NACK values:
In addition to the above, the NFC stack implementations on some devices do not properly propagate NACK responses to the app. Instead they either throw a TagLostException
or return null
. Similarly, you might(?) get a TagLostException
indicating a passive ACK.
Thus, you would typically check the result of the transceive method for the following (unless you send a command that is expected to result in a passive ACK):
try {
response = nfca.transceive(command);
if (response == null) {
// either communication to the tag was lost or a NACK was received
} else if ((response.length == 1) && ((response[0] & 0x00A) != 0x00A)) {
// NACK response according to Digital Protocol/T2TOP
} else {
// success: response contains ACK or actual data
}
} catch (TagLostException e) {
// either communication to the tag was lost or a NACK was received
}
The READ command is defined to return 4 blocks of data starting with the specified block number (in the NFC Forum Type 2 Tag Operation specification). Thus, if you send a READ command for block 4, you get the data of blocks 4, 5, 6, and 7.
nfcA.isConnected()
before calling nfcA.connect()
and, if so, is there likely to be any sigificant performance penalty in doing so?If you receive the Tag
handle directly from the NFC system service (through an NFC intent) the tag won't be connected. So unless you use the Tag
handle before calling nfca.connect()
, I don't see why you would want to call nfca.isConnected()
before. However, calling that method before connecting has barely any performance overhead since calling isConnected()
on a closed tag technology object will be handled by the famework API without calling into the NFC system service. Hence, it's not much more overhead than a simple if
over a boolean member variable of the NfcA
object.
nfcA.setTimeout()
before or after nfcA.connect()
?I'm not sure about that one. However, the transceive timeout is typically reset on disconnecting the tag technology.
nfcA.getMaxTransceiveLength()
returns 253. Does that really mean I can write up to 251 bytes of user data (plus the 2 other bytes) in one go and, if so, is that advisable or is it better to write each page (4 bytes) with separate nfcA.transceive()
calls?No, you can only write one block at a time. This is limited by the WRITE command of the NTAG213, which only supports one block as data input.
However, a transceive buffer size of 253 allows you to use the FAST_READ command to read multiple blocks (up to 62, so up to 45 for the NTAG213) at a time:
int firstBlockNum = 0;
int lastBlockNum = 42;
byte[] result = nfcA.transceive(new byte[] {
(byte)0x3A, // FAST_READ
(byte)(firstBlockNum & 0x0ff),
(byte)(lastBlockNum & 0x0ff),
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With