I'm using an AS3953 to emulate an NFC Tag, and was already able to read out a simple NDEF message using Samsung S4 or Fame with Broadcom chipsets,
now I'm trying to make it work with a HTC One SV which is using NXP PN544 controller,
the problem is that after my Tag sends the NDEF as an answer to a READ-BINARY from the Smarphone, it is requesting even more,
it's also strange, that it is reading the EF starting from 0x00 while the Broadcom devices start reading from 0x02, which makes more sense to me because address 0x00 and 0x01 contain the size information, which already has been read before,
is this the normal behaviour for PN544 ?
Thx for any ideas,
Andreas
-- ADF_NAME SELECT
0x00: 0x02
0x01: 0x00
0x02: 0xA4
0x03: 0x04
0x04: 0x00
0x05: 0x07
0x06: 0xD2
0x07: 0x76
0x08: 0x00
0x09: 0x00
0x0A: 0x85
0x0B: 0x01
0x0C: 0x01
0x0D: 0x00
>>0x02,0x90,0x00
-- CC_SELECT
0x00: 0x03
0x01: 0x00
0x02: 0xA4
0x03: 0x00
0x04: 0x0C
0x05: 0x02
0x06: 0xE1
0x07: 0x03
>>0x03,0x90,0x00
-- CC_READ
0x00: 0x02
0x01: 0x00
0x02: 0xB0
0x03: 0x00
0x04: 0x00
0x05: 0x0F
>> 0x02, // PCB
0x00,0x0F, // length of CC
0x20, // tag version 2.0
0x00,0x3B, // max length for read
0x00,0x34, // max length for write
0x04, // TLV 4:NDEF EF, 5:Propriety EF (more then one TLV block is allowed by NFC Forum)
0x06, // length info
0xE1,0x04, // NDEF file ID, values 0x0000,0xE102,0xE103,0x3F00,0x3FFF,0xFFFF are reserved
0x10,0x00, // N-max, max size of the file containing the NDEF message, valid range: 0005h to FFFEh
0x00,0x00, // read/write permissions, 0x00: full access
0x90,0x00); // OK
NDEF-SELECT
0x00: 0x03
0x01: 0x00
0x02: 0xA4
0x03: 0x00
0x04: 0x0C
0x05: 0x02
0x06: 0xE1
0x07: 0x04
>>0x03,0x90,0x00
NDEF-SIZE-READ
0x00: 0x02
0x01: 0x00
0x02: 0xB0
0x03: 0x00
0x04: 0x00
0x05: 0x02
>> 0x02,
0x00,0x0D, // length of NDEF message
0x90,0x00); // OK
NDEF-SELECT
0x00: 0x03
0x01: 0x00
0x02: 0xA4
0x03: 0x00
0x04: 0x0C
0x05: 0x02
0x06: 0xE1
0x07: 0x04
>>0x03,0x90,0x00
NDEF-READ
0x00: 0x02
0x01: 0x00
0x02: 0xB0
0x03: 0x00
0x04: 0x00 <- why does it start from 0x00 ?
0x05: 0x0D
>>
0x02, // PCB header
0xD1, // NDEF header, sizeNDEF counts from here (not including the 2 trailing bytes)
0x01, // type length
9, // payload length
'T', // type, for example: 'T'=Text
0x02, // payload: status bytes, UTF-8 ??
'e','n', // language code, for example: "en"
'h','e','l','l','o',0x0A, // text
0x90,0x00 ); // OK
why does the Reader request more ??
0x00: 0x03
0x01: 0x00
0x02: 0xB0
0x03: 0x00
0x04: 0x0D
0x05: 0x3B
It is not the chip that is deciding what commands get sent to your tag-emulation. That decission is made in the middle-ware NFC stack. These differ between Broadcom and NXP PN544 chips.
Regarding the command that you see: Just answer back according to the standard. If the binary-read command fails, then return a proper error-code.
The NFC middleware may send you this command just to see if an answer comes back. It sometimes does this to check if the tag is still in the field. You may also see strange commands that you don't expect because the NFC-stack is probing for rare or special tags that aren't 100% NDEF compatible and need special work-arounds (Old Mifare Desfire tags are one common example).
I just found out the reason: the HTC One SV with PN544 (Android 4.1.2) is requesting the correct length of the EF, but the request starts with an offset of zero, normally the offset should be 0x02, because the first two bytes contain the length information, that means that the apdu answer from the Tag is incomplete, the last two bytes of the message are missing. The software knows it and sends another read request to fetch the last 2 bytes. My apdu answer was hard coded to start at offset of 2
Related
I have qot android app for printing the cp1250 chars to ESC/POS BT printer.
I initialize the printer with header
byte header[] = null;
header = new byte[] { 0x1b, 0x40, 0x1c, 0x26, 0x1b, 0x39, 0x01 };
os.write(header);
0x1b, 0x40 - initialize printer
0x1c, 0x26 - Kanji character mode
0x1b, 0x39, 0x01 - what does it mean ?
Would it be possible to explain what is Kanji character mode ? If i print with whole header { 0x1b, 0x40, 0x1c, 0x26, 0x1b, 0x39, 0x01 } my printing cp1250 characters is right. If I use only { 0x1b, 0x40 } printing cp1250 chars is wrong
The specification of the command supported by the printer is included in the device driver which can be downloaded from this page.
Rongta Tech - Thermal Receipt Printer Driver, Mobile Printer Driver
Portable Printer 58mm CD (For RPP200/02/02N/210/210A/02A/02B)
However, the commands corresponding to 0x1B, 0x39, 0x01 did not seem to exist.
The command of 0x1C, 0x26 is described and has the following contents.
This is the same as EPSON's ESC/POS.
FS &
FS &
[Name] Select Kanji character mode
[Format] ASCII FS &
Hex 1C 26
Decimal 28 38
[Description] Selects Kanji character mode.
[Notes] For Kanji model:
- When the Kanji character mode is selected, the printer processes all Kanji code as two bytes each.
- Kanji codes are processed in the order of the first byte and second byte.
- Kanji character mode is not selected when the power is turned on.
[Reference] FS .
The command to switch to code page 1250 is 0x1B, 0x74, 0x1E.
ESC t n
[Name] Select character code table
[Format] ASCII ESC t n
Hex 1B 74 n
Decimal 27 116 n
[Range] 0 ≤ n ≤ 5, 16 ≤ n ≤ 19, n = 255
[Description] Selects page n from the character code table.
30 WCP1250[Central Europe]
Kanji character mode is a mode to print Japanese character set.
In Addition:
Looking at the details, code page 1250 is not supported in the specification.
n parameter 30 was not in the supported range.
[Range] 0 ≤ n ≤ 5, 16 ≤ n ≤ 19, n = 255
If your control code allows the code page 1250 to print, it's either private or hasn't been documented yet.
{ 0x1b, 0x40, 0x1c, 0x26, 0x1b, 0x39, 0x01 }
Please ask your vendor's support desk.
All my attemps to verify a PIN code on a PINPAD reader ends up in failure, here is my situation:
Setup
Belgian EID card;
Vasco DIGIPASS 875, connected in Bluetooth;
Android application using the SDK from Vasco.
Situation
I've used APDU command to select and read files, to set the secure environment (MSE : SET), and after numerous research and merging of different solutions from different documentation, I can make the reader ask for my PIN code. But with my pseudo-APDU command, I receive a 69|C# response. The same process (reading files, set secure environment and verify the PIN) works fine on a USB reader with no PINPAD, so I guess that the APDU command is ok, but not the pseudo-APDU command that precedes.
Documentation used
The BEID documentation, PC/SC Spec part 10 (2.5.2) and supplement (2.2.1) and USB Smart Card devices for chapter from 6.1.11.3 to 6.1.11.6.
What did I understand?
The first part should be FF C2 01 06 for direct PIN verification on reader, followed by the size of the subsequent data.
Next should follow the structure from PC/SC part 10, with:
Timeout 1 & 2 (00 for default);
Format (should be 89 for me, as it should be 10001001 for 1 byte offset PIN, justified left and BCD);
PIN block format (should be 48 because 4 bit length included and 8 byte for the PIN block);
PIN length format (04: 4 bit offset in the PIN block);
Min/Max PIN length : 040C (but didn't work like that, 0404 is sure to work);
Validation condition is 02 for ok button;
Number of messages : 01 to use the one in the command;
Language is 0409 for english;
Message to display is 00 for enter PIN;
000000 because this field isn't used;
The length of the final APDU command to transmit once formatted with the PIN (0000000D is my guess);
And then the APDU command : 0020000108FFFFFFFFFFFFFFFF
Results
I have changed several times some values that I wasn't so sure (2, 3, 4, 11 and 12 for the padding characters already present or not), with no success, just different result codes sometimes.
What do I do wrong here ?
Thx in advance !
After a last round of research and checkup, I found another example showing me my mistake: the PIN block ! It was 47, because it didn't include the control/effective PIN length. So the correct answer for me was :
0xFF, 0xC2, 0x01, 0x06, // Base PPDU command
0x20, // Length of the data
0x00, // timeout
0x00, // timeout
0x89, // format
0x47, // PIN block
0x04, // PIN length format
0x04, // Min pin size
0x04, // Max pin size
0x02, // Entry validation condition
0x01, // Number of messages to display
0x04, 0x09, // English
0x00, // Message "Enter pin"
0x00, 0x00, 0x00, // Non significant here
0x00, 0x00, 0x00, 0x0D, // Length of the apdu once formatted
0x00, 0x20, 0x00, 0x01, // APDU command VERIFY
0x08, // APDU command Data length
0x20, // APDU command Control data + Effective PIN length
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // APDU command PIN + filler
I write data to a 14443A Tag with a HTC One SV (PN544, Android 4.1.2), using the "binary update" APDU command, but I see between the message size (byte#5) and the beginning of the NDEF record two additional zero-bytes (#6,7). I checked the ISO7816 standard and can't see the purpose of these two additional bytes, is this conforming to the standard ?
I'm parsing the APDU/NDEF message in a C-program, how can I find the beginning of the NDEF message, can I assume that these two zero bytes are always there or do I have to search for the "D1" byte ?
The ISO7816, UPDATE BINARY:
CLA As defined in 5.4.1
INS 'D6'
P1-P2 See text below
Lc field Length of the subsequent data field
Data field String of data units to be updated
Le field Empty
If b8=1 in P1, then b6-5 are set to 0 (RFU bits). bit5-1 of P1 are a short EF identifier and P2 is the offset of the first byte to be updated in data units from the beginning of the file.
If b7=1 in P1, then P1||P2 is the offset of the first byte to be written in data units from the beginning of the file.
cmdMessage = "\u0002"+"en"+"erase";
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefRecord txtRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], cmdMessage.getBytes());
NdefMessage newMessage = new NdefMessage(new NdefRecord[] { txtRecord});
writeNdefMessageToTag(newMessage, tag);
0x00: 0x02
0x01: 0x00 CLA
0x02: 0xD6 INS, bin update
0x03: 0x00 P1, Address MSB
0x04: 0x00 P2, Address LSB
0x05: 0x0E Lc, msg size
0x06: 0x00 ??
0x07: 0x00 ??
0x08: 0xD1 NDEF header, TNF
0x09: 0x01 type-len
0x0A: 0x08 payload-len
0x0B: 0x54 "T"
0x0C: 0x02 0x02
0x0D: 0x65 e "en"
0x0E: 0x6E n
0x0F: 0x65 e "erase"
0x10: 0x72 r
0x11: 0x61 a
0x12: 0x73 s
0x13: 0x65 e
after sending the 0x9000 acknowledge the smartphone is sending another write message:
what's the purpose of this additional write access ?
I guess that 0x0C is the size of the NDEF message which was written in previous sequence,
but why sending this information in a separate write access ?
0x00: 0x03<\n>
0x01: 0x00<\n>
0x02: 0xD6<\n>
0x03: 0x00<\n>
0x04: 0x00<\n>
0x05: 0x02<\n>
0x06: 0x00<\n>
0x07: 0x0C<\n>
The first two bytes of the NDEF message file contain the data size (i.e. the number of valid bytes in the file). In the first write command (i.e. while writing the NDEF message, these two bytes are set to zero. Thus, if the write operation is interrupted before the whole message was written, reading the the NDEF file will show an empty file instead of a corrupted NDEF message. Then, when the whole NDEF message was successfully written to the file, another write command is issued to update the data size to the size of the NDEF message. Now, if the file is read, the reader will receive the correct NDEF message size and will thus be able to read the full NDEF message.
I'm trying to read some information out of an ISO/IEC 14443 Type A card.
After analysing the card with the android app NFC TagInfo, I found out, that the application (AID: 15845F) has the particular file (File ID: 01) that I need.
I already managed to connect to the card and to select the application.
String action = getIntent().getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action))
{
Tag tagFromIntent = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
Log.i(TAG, Arrays.toString(tagFromIntent.getTechList()));
IsoDep isoDep = IsoDep.get(tagFromIntent);
try
{
isoDep.connect();
byte[] SELECT = {
(byte) 0x00, // CLA = 00 (first interindustry command set)
(byte) 0xA4, // INS = A4 (SELECT)
(byte) 0x04, // P1 = 04 (select file by DF name)
(byte) 0x0C, // P2 = 0C (first or only file; no FCI)
(byte) 0x06, // Lc = 6 (data/AID has 6 bytes)
(byte) 0x31, (byte) 0x35,(byte) 0x38,(byte) 0x34,(byte) 0x35,(byte) 0x46 // AID = 15845F
};
byte[] result = isoDep.transceive(SELECT);
Log.i(TAG, "SELECT: " + bin2hex(result));
if (!(result[0] == (byte) 0x90 && result[1] == (byte) 0x00))
throw new IOException("could not select application");
byte[] GET_STRING = {
(byte) 0x00, // CLA Class
(byte) 0xB0, // INS Instruction
(byte) 0x00, // P1 Parameter 1
(byte) 0x00, // P2 Parameter 2
(byte) 0x04 // LE maximal number of bytes expected in result
};
result = isoDep.transceive(GET_STRING);
Log.i(TAG, "GET_STRING: " + bin2hex(result));
}
}
But my second query fails with the error code: 6A86 (Incorrect parameters P1-P2). I already googled a lot and found different documentations (for example: http://bit.ly/180b6tB), but I just could not understand, how I can implement the right values for P1 and P2.
EDIT
Tag type of the card using NFC TagInfo: ISO/IEC 14443-4 Smart Card, Mifare DESFire EV1 (MF3ICD81)
The SELECT command as used in the source code actually did not fail, but instead it returned a 9000 response. So this is why I assumed that everything is working fine.
You mentioned that NFC TagInfo does not provide the correct values for DF-names etc. Is the value 0x313538343546 correct and how did you find it out?
Can you provide me a short description, how I could get the data I want? Are there any other android apps that I can use to read the right DF-names, AIDs etc.? I basically need to get ONE file out of ONE application. I could also provide some screenshots of the information gathered with NFC TagInfo, if needed.
EDIT 2
I have rewritten the commands, but (as you proposed) kept them in the APDU wrapper. Therefore I ended up having two different commands, one for the selection of the application and the other one for the selection of the file.
private final byte[] NATIVE_SELECT_APP_COMMAND = new byte[]
{
(byte) 0x90, (byte) 0x5A, (byte) 0x00, (byte) 0x00, 3, // SELECT
(byte) 0x5F, (byte) 0x84, (byte) 0x15, (byte) 0x00 // APPLICATION ID
};
private final byte[] NATIVE_SELECT_FILE_COMMAND = new byte[]
{
(byte) 0x90, (byte) 0xBD, (byte) 0x00, (byte) 0x00, 7, // READ
(byte) 0x01, // FILE ID
(byte) 0x00, (byte) 0x00, (byte) 0x00, // OFFSET
(byte) 0x00, (byte) 0x00, (byte) 0x00, // LENGTH
(byte) 0x00
};
The search for a tutorial for native Mifire-Desfire commands was not successful, so I stick to the following tutorial: http://noobstah.blogspot.de/2013/04/mifare-desfire-ev1-and-android.html
This tutorial provides a card authentification, which I disabled, and also uses the transceive method, which for my understanding is not a proper way for executing native commands? Which method, purhaps even code snippit, is used for executing native commands? Which Android-Class should I use?
I have rewritten the class provided in the tutorial and uploaded it to pastebin. After executing the class I've got following results.
Select APPLICATION: 9100
Read DATA: 91AE
At this point I am quite stuck and do not know what steps I should do next. Was is actually the error or rather what changes in the queries should I perform, to get the data I want?
Given the information you extracted from NFC TagInfo and the commands you are trying to use, I assume the card is MIFARE DESFire EV1. Correct?
Regarding your selection command: NFC TagInfo does not currently read the DF name value used in the ISO command set for DESFire EV1. Thus, I assume that the DF-name that's setup for this application is actually 0x313538343546, otherwise the SELECT command should fail. Note, however, that this value is by no means derivable from the DESFire AID shown in NFC TagInfo! In fact the DF-name is a seperate value defined during application creation. (This is different from the previous DESFire version.)
Regarding your READ BINARY command: The command you used would imply that you previously selected a file. However, you only selected the application. Thus, you would either need to issue a SELECT command for the data file or use a short file ID within the READ BINARY command:
byte[] READ_BINARY = {
(byte) 0x00, // CLA Class
(byte) 0xB0, // INS Instruction
(byte) 0x80, // P1 (indicate use of SFI)
(byte) 0x01, // P2 (SFI = 0x01)
(byte) 0x04 // LE maximal number of bytes expected in result
};
However, when it comes to DESFire (EV1) I suggest that you rather stick to the DESFire native command set (either direct or wrapped) instead of using ISO 7816-4 APDUs.
With the native command set, you get the full functionality of MIFARE DESFire. Command wrapping is done by embedding native DESFire commands into a ISO 7816-4 APDU structure. The wrapping command looks like this:
0x90 CMD 0x00 0x00 LEN CMD-PARAM 0x00
Where CMD is the native DESFire command and CMD-PARAM are the commands parameters. The response is:
[DATA] 0x91 STATUS
Where status is the native DESFire status code. If STATUS is 0xAF, you can get the remaining response data by issuing this command:
0x90 0xAF 0x00 0x00 0x00
So in your case, you would issue a select application command for your application 0x15845F (mind the different byte order!):
0x90 0x5A 0x00 0x00 3 0x5F 0x84 0x15 0x00
|SELECT| |APPLICATION ID|
Then, you want to read the data file 0x01 (whole file, starting at offset 0):
0x90 0xBD 0x00 0x00 7 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|READ| |FILE| OFFSET | LENGTH |
Regarding your question how to get the ISO DF names and ISO FIDs for your application, you can try the following commands:
Select master application:
905A00000300000000
Get applications including their DF names:
906D000000
Select your application:
905A0000035F841500
Get DESFire FIDs:
906F000000
Get ISO FIDs:
9061000000
You can always use the transceive() method of the IsoDep object. IsoDep (i.e. ISO/IEC 14443-4) is used anyways (for native DESFire commands, for wrapped native commands and for ISO 7816-4 commands).
The error code you received from the card (0xAE) indicates an authentication error (see this datasheet for further information: DESFire). Thus, the file allows authenticated read only (see the access conditions shown in NFC TagInfo).
Thus, in order to read this file, you will need to implement the authentication procedure.
My goal is to have an Android phone (Samsung Galaxy Nexus) communicate with a TI TRF7970A card in emulation mode (emulates ISO-14443 type B tag) through NFC.
I understand that the PCD (Android phone) sends out a "REQB" with a given AFI and then which ever PICC's (in my case only PICC is the TI TRF7970 card) that have a matching AFI will send an "ATQB" back to the PCD.
In some TRF7970A firmware the "ATQB" response was set up like so:
0x50; //
//PUPI
0x80; // PUPI_0
0x12; // PUPI_1
0x34; // PUPI_2
0x56; // PUPI_3
//Application DATA
0x40; // APP_0 AFI Telecommunication (Telephone,GSM) All Sub families 1-F
0xE2; // APP_1 CRC_B of the AID (multibyte application identifier code which identifies an application provider or issuer and indicates if the application provider is registered with ISO)
0xAF; // APP_2 CRC_B of the AID
0x11; // APP_3 # of applications (1)
//Protocol DATA
0x80; // Data rate capabilities (Same bit rate from PCD to PICC and from PICC to PCD compulsory)
0x71; // Max Frames (128 bytes) / Protocol Type (supports PICC ISO 14443-4)
0x85; // FWI (0b1000 - 8192 ETUs or 77328.6 us) / ADC (0b01 - determines what APP_0-3 are if 0b00 then App data can be anything) / FO (0b01 - CID Supported - used for identification of multiple cards in the Active state)
This "ATQB" has the PCD (Android phone) automatically launch the web browser with URL "http://www.Cisco Auth Complete".
Question:
(1) Which field tells the phone to automatically launch the web browser? How can I change that field so that I can manually chose which application acts on the intent?
I've tried looking online to learn how I can manipulate the fields but have had no luck.
I read 3 Type B 14443-4 Smart Cards (MAXIM-MAX66020k-00AA+) with my Android phone and the "ATQB"'s were as follows:
Card 1 Card 2 Card 3
0x50 0x50 0x50
//PUPI
0xd8 0x99 0x1a
0x60 0x5c 0x61
0x02 0x02 0x02
0x00 0x00 0x00
//Application Data
0x10 0x20 0x10
0x10 0x00 0x10
0x11 0x2b 0x11
0x11 0xe0 0x11
//Protocol Data
0x00 0x00 0x00 106Kbits/sec
0x00 0x00 0x00 16 bytes / Not type B -4 complient)
0x00 0x00 0x00 32 ETUs / Application is proprietary / Nad "nor" CID are supported
I tried sending these exact ATQB messages with the TI TRF7970A card but the Android phone still does not act on the "ATQB" response.
Question:
(2) Can you point out a reason why any of these last 3 "ATQB"'s wouldn't be excepted?
(3) What are some legit "ATQB"'s that when sent to my Android phone it will create an intent?
(4) Are there rules I can follow so that my android phone always creates an intent on the "ATQB"'s I respond with from the TI TRF7970A?
If you could direct me to a source that can explain any of this, it would be greatly appreciated.
Thanks in advance!
-Derek
I think you are looking in the wrong place. The TRF7970A is probably emulating an NFC Forum Type 4 Tag, containing an NDEF message.
How this results in an intent is explained at http://developer.android.com/guide/topics/nfc/nfc.html