Frequent Disconnection ACR122U NFC Reader - android

When I put SIII (Android 4.3) on ACR122U NFC reader the LED keeps blinking green. When I put Samsung S4 (Android 4.3) LED turns green till the time phone is on the reader. In both the cases NFC is turned on and device is in unlocked state.
This behaviour translates into frequent disconnections in SIII and a stable connection on S4. Why two phones behave differently? I am aware of the fact that two phones have NFC chipsets from two different vendors namely NXP and Broadcom.
My question is what is the source for such inconsistent behaviour among these devices?
Another question is why does phone give an ATR at all?

The command sequence for software card emulation using an ACR122U/PN532 can be found in this answer.
In addition to that, there are different versions of the ACR122U:
Some always indicate the presence of a smartcard. In that case it is possible to connect to the "simulated" card using
// SCardConnect with SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY
Card card = cardTerminal.connect("*");
CardChannel cardChannel = card.getBasicChannel();
After that, PN532 commands can be sent using APDU wrapping:
> FF000000 Lc PN532-COMMAND
< PN532-RESPONSE 9000
with the cardChannel.transmit method:
CommandAPDU commandAPDU = ...
// SCardTransmit
Response responseAPDU = cardChannel.transmit(commandAPDU);
Other versions of the ACR122U do not always "simulate" the presence of a smartcard. Instead they automatically poll for contactless cards and only indicate card-presence if an actual card is presented to the reader. In that case using cardTerminal.connect("*"); would be only possible if there is an actual card present. However, this is typically not the case in situations where the ACR122U is used in software card emulation mode. In that case it is still possible to establish a connection to the reader using direct mode
// SCardConnect with SCARD_SHARE_DIRECT
Card card = cardTerminal.connect("direct");
After that, the same APDU-wrapped PN532 commands can be exchanged with the reader using escape commands (you might want to check the manual if the escape command is correct for your reader version):
final int IOCTL_SMARTCARD_ACR122_ESCAPE_COMMAND = 0x003136B0; //IOCTL(3500) for Windows
//final int IOCTL_SMARTCARD_ACR122_ESCAPE_COMMAND = 0x42000DAC; //IOCTL(3500) for Linux
byte[] commandAPDU = ...
// SCardControl
byte[] responseAPDU = card.transmitControlCommand(IOCTL_SMARTCARD_ACR122_ESCAPE_COMMAND, commandAPDU);

Related

NFC SWP applet selection returns 6999

I have a simple JavaCard applet installed on my SIM card. I try to communicate with my applet using Omnikey 5121 CL reader and NFC-enabled Sony Xperia L through NFC/SWP (single wire protocol).
The problem is I cannot select the applet - as a status word I get 6999. The LED light is turned on, so I suppose there is some communication between reader and the SIM card. Moreover, I cannot select my security domain either.
However, when I put the SIM card into a standard contact smartcard reader, everything works fine.
Is there any extra configuration of Android OS, SIM card, NFC modem etc. I have to setup before communicating with SIM card over NFC? Any ideas?
More information:
ATR of SIM accessed in the contact way:
3B9F96C00A3FC6A08031E073FE211F65D001900F3B810FE6
ATR (generated by PCSC from ATS) of SIM accessed over NFC in the contactless way:
3B8880010000000000817000F8
My INSTALL for INSTALL APDU: (worked, finally!)
80E6040C32 //CLA INS P1 P2 Lc
0CF0AAAAAAAAAAAAAAAABBBBBB // AIDs
09F0AAAAAAAAAAAAAAAA
09F0AAAAAAAAAAAAAAAA
01
00 //privileges
0B //length of parameters
EF07 //system parameters
A005A5038201FF
C900 //applet parameters
00
Receiving status code 6999 in response to the SELECT (by AID) command is a clear indication that the applet was not found/not selectable. If the applet has been installed and is selectable (using the same AID) over the contact interface of the UICC/SIM card, then it is likely not made selectable over the SWP (contactless) interface. Typically secure elements allow to selectively enable/disable applets for specific interfaces (in addition to this, applets can detect over which interface they are selected and can react accordingly).
Applets typically need to be explicitly made selectable over the contactless interface by setting the Contactless Protocol Parameters in the INSTALL (for MAKE SELECTABLE) command (or later on by doing a registry update). See Amendment C to the Global Platform Card specification for further details.
Btw. the security domain not being selectable over the contactless interface is not unusual for a SIM card. Card management is typically restricted to the contact interface for security reasons. (Card management over the contactless interface is typically not used in production environments anyways.)

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.

Get Static NFC Tag Id with HCE mode

I'm new in NFC thing, so I tested several phones with calling getTagId() method in HCE mode, and this is the result:
device | UID
LG G2 | random
LG G3 | static
S4 | random
HTC One Mini | static
Xiaomi mi3 | static
My questions:
Why do some phones have static UID and some do not? Is this chipset related?
Is it possible to get a fixed UID? I need it to authenticate the device.
On other side, I'm using Kitkat CyanogenMod 11 on Xperia M, but I did not manage to use it for HCE, why?
Any documents that can explain/support the answer?
Why do some phones have static UID and some do not? Is this chipset related?
That depends on the chipset and the implementation of the NFC stack. As far as I'm aware of, there are three different scenarios used by various Android NFC devices:
The device has a secure element and uses the static UID of that secure element.
The device generates a new random UID whenever it is turned on.
The device generates a new random UID on every activation by an external reader device. I.e. whenever an external HF field is applied to the NFC antenna of the Android device.
The device has no secure element but still uses a static UID (typically not unique), e.g. 0x01020304. [Thanks to ErikM for pointing this out.]
Is it possible to get a fixed UID?
Typically, you can't influence this. Specifically without modifying the Android device firmware (changes to the NFC stack) it's definitely not possible. See this answer for a method to set the UID value on Broadcom chipsets through modifying the libnfc-nci library.
I need it to authenticate the device.
Don't do this! See this answer for more information on that.

KitKat: How to route APDUs to the SIM

I want to route APDUs I get from an NFC Reader to the SIM Card. According to the HCE documentation I thought it would be possible simply by creating an OffHostApduService with the according routing-entries (which I did).
Sadly, the SIM does not seem to get any APDUs. SELECT-Commands that work when the SIM is directly attached to my workstation by a SIM-Reader return with 6a82 (File not found).
In LogCat I found two interesting bits of information:
Every time I shoot a select command which should be routed to the SIM, I get these entries:
01-14 10:44:18.501: D/BrcmNfcJni(1009): RoutingManager::stackCallback: event=0x17
01-14 10:44:18.501: D/BrcmNfcJni(1009): RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=12
01-14 10:44:18.501: D/HostEmulationManager(1009): notifyHostEmulationData
I think that this is a clue that the routing is not set correctly, since I think the Android OS should not be aware when the routing to the SIM is active, and a select or another command is sent to the SIM.
Every time I remove the phone from the NFC field of the reader, I receive the following error:
01-14 10:46:48.791: E/BrcmNfcNfa(1009): UICC[0x0] is not activated
I tried to track the cause of this error down and found the file external/libnfc-nci/src/nfa/ce/nfa_ce_act.chere which seems to belong to the Broadcom NFC Driver.
I think that the mistake is that the application cannot set the correct routing for the APDUs since the driver thinks that the SIM is not activated. In the moment I send the commands, the SIM is unlocked (PIN-Entry), but I doubt that this has anything to do with it since I don't have to unlock the SIM before using it in the card reader.
I use a Nexus 5 for testing. Does anybody have experience and / or a working example where the APDUs can be routed to the SIM instead of the CPU?
A quick check (analyzing the signals on the SWP pin of a UICC inserted into the device) revealed that the Nexus 5 is not activating the SIM as an NFC secure element (neither at boot nor when putting the phone on a smartcard reader).
However, I found two interesting files on the device's system partition:
/system/etc/libnfc-brcm-20791b05.conf and
/system/etc/libnfc-brcm.conf.
These two files seem to provide the configuration for the NFC controller (the first one a chip-sepecific configuration and the second one a chip-family specific one?).
After unlocking the bootloader, I was able to modify those files through adb by booting a clockworkmod recovery image, so I did some experimenting with the configuration parameters.
The result is that I managed to let the device activate the UICC (UICC was activated and registered its CE gates through SWP?), the device sometimes even notified the UICC about field status changes. However, with none of my modified configurations, I was able to get the reader to smoothly discover card emulation (this was working before, when only HCE was available on the device) nor to communicate with the UICC.
The interesting parameters in /system/etc/libnfc-brcm.conf seem to be:
NFA_MAX_EE_SUPPORTED: This is currently set to 0. I tried a value of 3, which seems to be the default.
ACTIVE_SE: This is currently set to 0 (no active SE). I tried to uncomment that line to let the device use the first SE detected.
NFA_HCI_STATIC_PIPE_ID_??: Should not be necessary but on out GS4 this is set to 0x71 for ?? = F3 and F4.
UICC_LISTEN_TECH_MASK: This is set to 0x00 on our GS4.
REGISTER_VIRTUAL_SE: I left this as it was (== commented out).
SCREEN_OFF_POWER_STATE: I did not experiment with this, but on our GS4 this is set to 3 (screen-off CE).
The interesting parameters in /system/etc/libnfc-brcm-20791b05.conf seem to be:
NFA_DM_START_UP_CFG: I've tried the commented-out parameters for UICC and I tried to use the configuration from our GS4. The value starts with a length byte and is structured in TLV format (one tag byte, one length byte, parameter data). The relevant tag for UICC activation seems to be C2, where the upper two bits in the second parameter byte disable the SWP interfaces of the NFC controller if set.
NFA_DM_PRE_DISCOVERY_CFG: The comments suggest that this need to be uncommented for UICC support.
It's been a while since I last played with card emulation on Android but AFAIK (I could be wrong), secure element access (internal or inside SIM) has not yet been opened to all developers (without some hacking). There are many non-technical issues regarding SE control which seem not yet solved (who keeps the biggest slice of the cake the Telcos or service providers?).
The news is that Google has taken a different approach with KitKat and its HCE, which basically consists on implementing a NFC card emulation mode without hardware secure element. IMHO this basically breaks the security required for the interesting card emulation mode applications: e-payment, ticketing, authentication, etc. Nexus 5 lacks such secure element and I doubt Google will pander to carriers by easing the access to secure element inside SIM, so I guess it still will not be possible to send APDUs to the SIM with stock firmware.
If you add the following to /etc/libnfc-brcm.conf
DEFAULT_ISODEP_ROUTE=0xF3
the UICC will receive APDUs
You also need all modifications above in libnfc-brcm.conf and libnfc-brcm-20791b05.conf
Up to Jelly Bean 4.3, normal way is to use nfc_extras and its method CardEmulationRoute (<route>, <nfcEe>) to route the UICC to the RF.
But on KITKAT, this brutal modification through DEFAULT_ISODEP_ROUTE is enough to have UICC Card Emulation enabled.

Transceive failed on Galaxy S3 with a NFC-B card

I am working on an application for Android reading a contactless smart card but I have some problems with my Galaxy S3.
Before to describe problems, I need to precise that on a PC, I can communicate perfectly with the card using the smartcardio API in Java and NFC readers from different manufacturers.
This card is detected as supporting technologies "IsoDep" and "NfcB" by the NFC stack.
However, when I send my apdu command with "transceive", I get an exception "Transceive failed". I have tried to increase timeout but no better result.
iso = IsoDep.get(tag);
if (iso!=null) {
try {
iso.connect();
// txMessage is a TextView object used for debugging purpose
txMessage.setText("Max:"+iso.getMaxTransceiveLength()+" timeout:"+iso.getTimeout()+" connected:"+iso.isConnected());
iso.setTimeout(2000);
txMessage.setText("Max:"+iso.getMaxTransceiveLength()+" timeout:"+iso.getTimeout()+" connected:"+iso.isConnected());
byte[] command = new byte[] {(byte) 0x00, (byte) 0xA4, (byte) 0x04,(byte) 0x00, (byte) 0x06,(byte) 0xA0,(byte) 0x00,(byte) 0x00, (byte) 0x00,(byte) 0x12,(byte) 0x00};
byte[] response = iso.transceive(command);
} catch (IOException e) {
txMessage.setText(txMessage.getText()+"\n"+e.getMessage());
}
}
When running this code, I get:
Max:261 timeout:309 connected: true
Max:261 timeout:2474 connected: true
Transceive failed
I have noticed that this card requires to be very close of the NFC antenna to work. I need to remove the additional plastic protection case (not the back cover) of my phone in order the card would be detected (I guess powered).
Before to post, I have read NFC typeb card not getting detected by any NFC application (like:nfctaginfo) and Android isodep.isConnected() returns false and maximum Transceive length:0 byte ,for type B card.? and several other posts elsewhere (http://forum.xda-developers.com/showthread.php?t=1705970 , http://code.google.com/p/android/issues/detail?id=35960 ) but I did not find a solution.
A possible solution would be to try to communicate with an external antenna but I am not sure where to connect it? On battery connector where there is no "+" and "-"?
Another solution would be to try to communicate with the card with NfcB (NfcB nfcb = NfcB.get(tag);), but I do not know the ISO14443-3B protocol (I only know quite well APDU, T0-TPDU but not other TPDU protocols).
Just to be sure, I have updated my phone to Android 4.1.2 (instead of 4.1.1) but no better result.
I have a Samsung Galaxy S3 too and I noticed that the connection performance for TypeB contactless cards is worse than for TypeA. Raising the timeout value seems to be a quick fix for problems of this kind, but as it didn't work for you, the problem might be with the strength of the RF-field. Have you tested if the call of transceive() fails because of the timeout or because of a connection loss? Maybe you could try raising the timeout even further, some operations might take a long time on a smart card.
Another suggestion to your problem is to remove the backcover of your S3 and place the smart card directly on the battery (the NFC antenna is integrated in there). In my experience it makes a slight difference where the chip is located on the smart card, so you could experiment with the orientation of the card. You might test this by sliding the card onto the battery from the bottom of the device to the top.
In my work with the Galaxy S3 (Android 4.1.1) I was able to connect to and transceive data to TypeA and TypeB contactless smart cards (German eID cards). I noticed that the TypeB card was lost sometimes without any reason while being idle. But I can send and receive data with it anyway. Even when the Chip on the card has to perform some computation and hence needs slightly more power from the RF field, the field of the NFC antenna seems sufficiently strong to keep the connection in my case. Maybe your card is not properly designed to work with lower power RF fields? Unfortunately to my knowledge there is no possibility to raise the power output of the NFC antenna on Android devices.
Communicating via the NfcB (NfcB nfcb = NfcB.get(tag);) does not seem to make any difference to me. I am able to comunicate via the IsoDep Object and transceive data perfectly.
Using an external or additional antenna would be worth a try. In this YouTube video it is shown how one can put an additional NFC antenna into the Galaxy S4. In the video you will notice the external antenna pins on the back of the S4. When watching the third picture here (Galaxy SIII teardown) - the one with the battery taken out - you will notice that there are additional antenna pins on the back of the SIII as well. The two golden contact pins on the left side. Googling a bit showed that these pins are named 'ANT500' and 'ANT501', so they are probably external NFC antenna contacts. If you search for "Samsung Galaxy Note2 external NFC antenna" or something similar on eBay (or any search engine), you will get the antenna used in the YouTube video. There are no official external NFC antennas for the SIII nor for the S4, but probably it will work. The antenna is not very expensive (currently around $5), so you might give it a try.
It is definitely a timeout thing, and a compatibility thing with NXP NFC chips (like the one in the S3)
I have worked with Type B tags on an antenna with a higher Q factor than that of a typical mobile phone antenna, and when doing ISO-DEP I need to still change the default timeouts of the NFC chip that I'm using (NXP PN532). Type A modulation was developed by Phillps, now NXP. Type B modulation was developed by Motorolla, and is under license to NXP for its reader chips, so only a basic implementation is included relative the the Type A implementation.
I am not doing this on an Android, but an embedded platform, so I have full access to the NFC chip's features. Thus, only by using a more basic transeiving method that requires the application to handle the 14443-4 protocol and extending the timeout tolerance of the reader was I able to talk to a Type B tag using ISO-DEP
Android 4.4 has something called reader mode, that may have a feature that enables you to extend this timeout.

Categories

Resources