1
votes

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?

1
What mode are you using? Are the phones used in reader/writer mode, card emulation mode or peer-to-peer mode?Michael Roland
I am simply connecting the reader with default settings, no PC application. No additional app is installed on phone and only setting changed is NFC on.Sunita
So you are using one NFC device (the ACR122U) in reader/writer mode and the second NFC device (Android phone) in peer-to-peer mode (or are you using an NFC-enabled SIM card? In that case at least the S4 will also activate card emulation mode...) While peer-to-peer mode (under certain conditions) will look like a contactless card to a reader, you can't expect them to communicate with each other due to the different operating modes and protocols. So what you are trying to do does not make much sense (except for the case with the NFC-enabled SIM card) and won't lead to any useful results.Michael Roland
We're not using NFC SIM cards. The real problem comes when I use PC/SC library to send TginitTarget command to reader's NFC controller to put it on PICC emulation mode. Algorithmically we select a reader then connect to reader and send controller command wrapped with special APDU prescribed by ACR122U. In case of S4 connect to reader succeeds since phone gives ATR and connection remains stable while in S3 connection fails and TginitTarget fails with 6300. code.google.com/p/ismb-snep-java/issues/detail?id=1Sunita
So could you explain what exactly you are doing now? If you use TgInitAsTarget, then you are not using the ACR122U in reader/writer mode but in card emulation mode. In that case, the Android device would operate in reader/writer mode. Could you also explain why you believe that the phone sends an ATR? (Btw. there is no ATR involved in either case as an ATR is specific to contact smartcards.)Michael Roland

1 Answers

3
votes

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);