Android: card emulation - read ndef message with PN532 nfc module - android

I have an LG D320n Android phone, elechouse's PN532 nfc module and Stollmann's NFCPlayer with which I can read NFC tags properly.
I tested a sample from here: https://github.com/grundid/host-card-emulation-sample
It works fine, when I read one Android device as tag with another Android device as reader. But I can not read the Android device as tag with PN532 reader through NFCPlayer. I want reader to read an NDEF message from the Android device acting as a tag, but NFCPlayer doesn't even recognise the Android device. I think I have to write some modifications on the Android side but I can't figure it out what to do. I think I don't have enough knowlege about how NFC communication and HCE work, even though I read this:
https://developer.android.com/guide/topics/connectivity/nfc/hce.html
I would really appreciate any guideline that could help me understand what am I missing here.

The grundid example app should be discovered by NFCPlayer as a "legacy tag" (tab "R/W: Legacy") as it does not implement the NDEF abstraction layer. On that tab, you can exchange PDUs (APDUs in the case of HCE) with the emulated smartcard. A valid APDU for the example app would be
00 A4 04 00 07 F0010203040506 00
You can send this APDU by typing it into the PDU field and clicking on the "Exch. PDU" button. Note that the grundid HCE app does not even implement ISO/IEC 7816-4 response APDUs. Hence, you may run into troubles with some contactless smartcard readers.
If you want your emulated smartcard to be discoverabe by NFCPlayer as NFC Forum Type 4 tag containing an NDEF message (tab "R/W: NDEF"), you would need to implement the NFC Forum Type 4 Tag Operation specification (as defined by the NFC Forum. This specification defines how data must be stored on an (emulated) ISO/IEC 14443-4 smartcard to be interpreted as NDEF tag. As a starting point you could use this NDEF on HCE example app (though, the quality and reliability of that code is questionable). This example implements the smartcard filesystem for storing NDEF data.

Related

Configure MIFARE DESFire EV1 as NFC Forum Type 4 Tag for NDEF

I started my studies using NFC in Android. I can easily read and write in NDEF format.
My problem is with MIFARE DESFire EV1, I have some factory cards and I understand that they do not conform to the NFC Forum type 4 Tag specification and, consequently, do not accept to be read or written in NDEF format (when in their factory configuration).
I can get access to the tag through android.nfc.tech.NfcA or android.nfc.tech.IsoDep.
So far I understand that I need to use IsoDep.transceive() method to pass commands that enable me to build an NFC Forum Type 4 compliant tag.
But I'm having a lot of trouble. I'm using TagWriter and it does the service perfectly. Every time I use the NDEF dataset it automatically performs a routine that makes the card an NFC Forum Type 4 Tag and, consequently, an NDEF tag.
However, I could not find any simple example to do this procedure myself. Even after reading the specification document NFCForum-TS-Type-4-Tag_2.0, I'm still very lost.
Is there any practical example to do the process that the TagWriter application does?
Recognize NfcA / IsoDep (ok here)
Make the card conform to the NFC Forum Type 4 Tag specification
Start recognizing the tag as android.nfc.tech.Ndef
Enable read and write of NDEF
The procedure to prepare MIFARE DESFire EV1 as an NFC Forum Type 4 Tag (V2.0) is not part of the platform independend NFC Forum specifications. Instead, this procedure is defined by the chip manufacturer (NXP) in their application note AN11004: MIFARE DESFire as Type 4 Tag. The procedure is about the following:
If Android already detects the Ndef tag technology, you are done. Since Android tries to detect the NDEF tag application and an NDEF message contained in the NDEF data file, finding the Ndef tag technology means that the tag is already prepared for NDEF (i.e. it already is configured as NFC Forum Type 4 Tag).
Else, you would check if the tag really is a DESFire EV1 tag. You can do this based on the type identification procedure described in AN10833: MIFARE Type Identification Procedure and based on the version information obtained from the DESFire tag.
Once you know that the tag is a DESFire EV1 tag (and that you have sufficient access to the master application in order to apply the necessary modifications to the tag, which may require and authentication step), you would first create the NDEF Tag Application. This is a DESFire application that has its ISO 7816-4 DF name (= AID) set to D2760000850101 during creation. The values that you chose for the DESFire AID, the ISO file ID are not important for proper T4T operation (note that this is different for the pre-EV1 generation of DESFire). The key settings depend on your usage scenario. The only other important parameter that you need to set during application creation is to allow ISO 7816-4 file identifiers for files within the application (bit 5 in the Key Settings 2 byte set to '1').
Select the newly created application.
Create a new standard data file, the capability container file, with a size of 15 bytes. You need to set the ISO 7816-4 file ID to E103. Make sure to allow plain communication by setting the Com.Set. byte to 0x00. Set the Access Rights field so that you can later modify the file contents during the initialization.
Create another new standard data file, the NDEF data file. If you only use the tag as NDEF tag, you would typically use all the remaining available space. Set the ISO 7816-4 file ID to E104. Make sure to allow plain communication by setting the Com.Set. byte to 0x00. Set the Access Rights field to 0xE000 for a read-only tag or 0xEEE0 for a tag that should allow read and write access through the Ndef tag technology.
Select the capability container file and write the capability container data to it:
000F 20 003A 0034 04 06 E104 xxxx 00 yy
where xxxx is the size of the NDEF data file and yy is 0x00 if the file is freely writable or 0xFF if the file is read-only.
Select the NDEF message file and write the first 2 bytes as 0x0000 (in order to indicate that the file is empty).
Note that creating the NDEF Tag Application structures on a DESFire (EV1) card requires you to use either the native or the wrapped native command set of MIFARE DESFire. Since some versions of Android cause known problems with the native commands, you are better off using wrapped native commands. You can find details on the DESFire command set in the DESFire product datasheets (available only under NDA from NXP).

Start an Android App when an "unknown tag type" is scanned

I am working on an Android NFC reader project in which I use the AS3953 NFC chip. according to the datasheet: This NFC chip could be used
Where log data is stored periodically by the microcontroller and can
then be read by the PCD even when the microcontroller is not powered.
And this is exactly what I am trying to do, read passively the NFC tag. The problem is that my Android phone doesn't recognise the tag when it's not connected to the microcontroller. I have just a noise when I scan the tag and no information appear. I tried with another smartphone and I had the same behaviour with a small message: "unknown tag type".
My question is:
How can I start an Android App when an "unknown tag type" is detected. I tried the three Android intent handlers: TAG_DISCOVERED, TECH_DISCOVERED and NDEF_DSICOVERED, but none of these solutions has worked.
N.B: according to the datasheet, The AS3953A supports ISO 14443A up to Level-4
N.B2: when I use the constructor demokit I can read the EEPROM values when the NFC is supplied via the SPI interface.
I contacted the manufacturer "ams". They said that this tag (AS3953 HW) is not NFC Forum standards compliant (contrary to what is mentioned in the datasheet). So to read passively the tag I have to code their proprietary commands (a list is provided in the datasheet) into my app.

AID for HID readers

If I want my android phone to emulate a physical card to the following reader:
http://www.hidglobal.com/products/readers/iclass/rw100
Which AID would I have to use?
I was following this example:
https://developer.android.com/guide/topics/connectivity/nfc/hce.html#HceServices
But when debugging, my code never reaches the
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
method. Seems the Android device still represents itself as a unique number on a HW level so I was suspecting an incorrect AID within the code may be the cause?
FYI, I am using the Sony Xperia Z3 compact with an NXP NFC chip inside...
None.
Android HCE requires the reader to "speak" ISO/IEC 7816-4 over ISO/IEC 14443-4 (ISO-DEP). For ISO/IEC 14443 Type A this reader is only capable of reading the anti-collision identifier (UID) of cards but it does not send any APDUs. Consequently, the reader does not perform any AID based application selection.
Note that the UID cannot be configured through the Android HCE API and is randomly generated on many Android devices. Consequently, there is no sensible way you could use that reader in combination with Android devices that generate a random UID.

Host card emulation on Android (4.4 / KitKat and above) with Nexus 5

I'm trying to emulate an NFC tag with my Nexus 5 according to this document, but my service is never invoke.
Should I turn off Android beam?
I'd like to emulate a simple tag containing a url.
The reader is a Nexus 7 (2012) and I've figured out the process like a simple scan of a NFC tag using Android beam on Nexus 7.
In addition I'm a bit confused about aid-filter name. Is there a list of them?
I'm sure that I don't understand something.
Thanks
First of all (though this does not directly answer your question), the preferred way to transfer a URL between two Android NFC device is to use Android Beam (peer-to-peer mode). Android HCE (Host Card Emulation) is typically intended for emulation of contactless smartcard applications other than NFC tags.
Do I need to turn off Android Beam in order to use Android HCE?
No, Android HCE is not influenced by the on/off setting of Android Beam. Actually, even if Beam is turned off an Android NFC device will still perform peer-to-peer mode link activation.
I'd like to emulate a simple tag containing a URL.
Android HCE emulates smartcard applications based on ISO/IEC 14443-4 and ISO/IEC 7816-4. Thus, if you want to emulate an NFC tag with this, you would need to implement the NFC Forum's Type 4 Tag Operation specification in your Android HCE service. The NFC Forum's specifications are freely available on their website.
To summarize the requirements of this specification:
You need to register your service for the NFC Forum Type 4 tag application AID: D2760000850101.
Your service needs to respond with status code success (0x9000) to a SELECT (by DF name) APDU for that AID:
> 00 A4 04 00 07 D2760000850101 00
< 9000
Your service needs to respond with status code success to a SELECT (by EF ID) APDU for the capability container (CC) file (E103):
> 00 A4 00 0C 02 E103
< 9000
Your service needs to responds with the CC (or parts of it) upon receiving a READ BINARY APDU (after the CC file had been selected):
> 00 B0 Offset_High Offset_Low Length
< <Length bytes of the CC starting at Offset> 9000
Your service needs to respond with status code success to a SELECT (by EF ID) APDU for the NDEF file (EF ID as defined in the CC):
> 00 A4 00 0C 02 <EF ID>
< 9000
Your service needs to responds with the NDEF file content (or parts of it) upon receiving a READ BINARY APDU (after the NDEF file had been selected):
> 00 B0 Offset_High Offset_Low Length
< <Length bytes of the NDEF file starting at Offset> 9000
I want a second Android device to automatically pick up the URL.
That's the problematic part and the reason why Beam is the preferred way to go. Even if you emulate an NFC Forum Type 4 tag with one Android device, putting two Android devices together will still result in them establishing a peer-to-peer link (even if Beam is turned off!). Thus, the second Android device will not detect your HCE emulated card as an NFC tag. The only way to overcome this limitation is to use the NFC Reader mode API (new in Android 4.4) on the second device. However, in that case, you would need to have an app on the receiving device that is active in the foreground (that's the only way to enable the Reader mode API).

Android NFC communication with Mifare DESFire EV1

Using a Nexus 4 and the latest Android API level 18 to communicate with a Mifare DESFire EV1 AES tag is giving me a headache. Following the NXP native protocol in order to write and read this type of tag, these steps must be followed:
Select application
Authenticate
Write or Read
To do it so, I use Android's IsoDep class which provides access to ISO 14443-4 properties and I/O operations. The very weird thing about it is that once I send the select application native command I get an unexpected response. Imagine I have the AID F4013D so I send:
-> 5AF4013D
<- 6E00
All possible responses must be one byte length (success 0x00 or error_code) and never two or more. Thus, the 0x6E before the success response is absolutely unexpected. It does not happen always, and when it does not and works fine, the select application and authentication processes work fine. However once authenticated the write command does not have a correct behavior, all write commands finishes with a 0xAF from the PICC instead of a success 0x00. It seems like the PICC expect some extra data when it should not (I send the correct length payload). If I send any other command I get a 0xCA (Command Aborted) error code.
-> 5AF4013D
<- 00 /*Success*/
-> AA01
<- AFA8394ED57A5E83106B4EE72FD2BB0CC4
-> AF148F525E1DDE0AD6AB60B4B615552475C91F2E8D89B8523E4465113DD5BD19C6
<- 0066D255C93F2F492AFE3715C88964F1BD /*Authentication success*/
-> 3D02000000030000222222 /*Write 3 bytes to file nÂș2*/
<- AF /*Unexpected, 0x00 was expected*/
As it is normal, if I send these type of commands with a personal reader (non Android NFC) it always works fine. It seems that something in the Android NFC API is going strange, when it should just be a raw data transporter which never interprets or modifies data.
I have also tried with ISO 7816-4 APDU structure with the same result. As a curiosity, with a Galaxy Nexus does not happen the select application strange response, but yes the write command one always.
(1) For the first part concerning the status code 6E00:
6E 00 is not a "strange byte 0x6E + success status code 0x00". Instead it is a response APDU status word 6E 00 ("Class not supported"). This indicates that there was previous communication with the card using APDU-based access (e.g. Android itself tried to read the card as Type 4 tag and did not reset the connection afterwards). Thus, the card will expect all further communication to be in ISO 7816-4 APDUs. In that case (i.e. if you receive an ISO 7816-4 status code like 6E 00), you could continue using DESFire APDU wrapped commands by simply wrapping your native commands.
EDIT: In fact, this is somewhat expected behavior on an NFC device. The idea is that an NFC device will automatically scan detected tags for NDEF messages. In the case of a DESFire card, the NFC device will detect the card as potential Type 4 tag. Thus the NFC device will send ISO 7816-4 APDUs as it would send to any other Type 4 tag. Hence, if the NFC device doesn't reset the communication with the tag before handing the detected tag to the app, the app can only communicate using ISO 7816-4 APDUs. Note, however, that I would consider it a bug that this happens only for some activations on the same device. In my opinion, the behavior on one specific device model should be consistent.
EDIT: While I would not consider this behavior a bug, it is actually caused by a known bug (#58773) in Android's NFC stack for devices with Broadcom NFC controller. On affected devices, the automatic presence check sends ISO 7816-4 APDUs at timed intervals that cause DESFire cards to switch into ISO 7816-4 APDU mode.
(2) For the second part concerning the (unexpected) response code 0xAF:
Could it be that your file's communication settings are setup for either "plain communication secured by MACing" or "fully enciphered communication"? In that case, simply sending the three data bytes would not be enough. Instead you would need to send either the plain data plus MAC or the padded, CRCed and encyrypted data. Hence the 0xAF indicating that the card expects further data.
EDIT: So to summarize the comments below. After sending further bytes (one byte at a time for each received 0xAF status code: AF FF) it turned out that exactly 8 more bytes were expected by the card. 8 bytes is exactly the size of the CMAC for AES authentication. Thus, the communication settings were set to "plain communication secured by MACing".

Categories

Resources