Frequent Disconnection ACR122U NFC Reader

2019-02-20 10:06发布

问题:

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:

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