Is there any way to check if the last message in the Host Card emulation was received by the terminal?

In my Android app, I have an implementation HostApduService. Here is a snippet of its implementation:

public final class MyHostApduService extends HostApduService {

    private boolean disconnected = false;

    @Override
    public byte[] processCommandApdu(byte[] commandApdu, @Nullable Bundle extras) {
        //process apdu in a background thread and call sendResponseApdu() when ready
        Single.fromCallable(() -> processInternal(commandApdu))
                .subscribeOn(nfcScheduler)
                .subscribe(this::sendResponseApdu, t -> Log.e("could not create response", t));
        return null;
    }

    ...
    @Override
    public void onDeactivated(int reason) {
       disconnected = true;
    }


    private void processInternal(byte[] apdu) {
        //business logic
        if(!disconnected) {
           //last message was probably received by the terminal
        }
    }
}

Thus, in my observation, the callback onDeactivated()may appear in the middle processCommandApdu(), and even then the OS seems to recognize the bit earlier when the NFC field is lost than onDeactivated().

Here is an example of a lost field during communication:

16:21:16.808 I/MyHostApduService : processApdu[request|13bytes] 0A4040007A000000004306000
16:21:16.811 D/MyHostApduService : do business logic
16:21:16.890 D/HostEmulationManager: notifyHostEmulationDeactivated
16:21:16.890 D/HostEmulationManager: Unbinding from service ComponentInfo{app.debug/internal.MyHostApduService}
16:21:16.890 I/MyHostApduService : onDeactivated LINK_LOSS
16:21:16.898 I/MyHostApduService : processApdu[response|2bytes|90ms] 6A82

The problem is that I need to confidently check whether the last message was received or discarded, because some important completion code needs to be executed (but only if the terminal receives the message). Is there a better way to check if a message is received than to use onDeactivated()(which, apparently, is not time-determined)?

+4
2

. , .

Android, (ISO/IEC 7816-4 ISO/IEC 14443-4). -. Smartcards - , (- ), RF NFC.

( ). -. , - ( ):

  • .
  • - .
  • - .

(ISO/IEC 7816-4), (ISO/IEC 14443-4, ISO-DEP) - . - , , .

, - ( ). , ( , , , reset). , - .

, . - . . / reset (). , Android, HCE. , , - HCE , . , , . , reset (.. SELECT ( DF), ) - , , .

, ( ) . - :

T--->  SELECT APPLICATION
<---C  FCI | 9000
T--->  PERFORM CRITICAL OPERATION
<---C  CRITICAL OPERATION RESULT

:

T--->  SELECT APPLICATION
<---C  FCI | 9000
T--->  PERFORM CRITICAL OPERATION
<---C  CRITICAL OPERATION RESULT
T--->  CONFIRM RECEPTION OF RESULT
<---C  9000

, (9000) .

+1

: , ( HCE). T = CL (ISO7816) ack NFC .

, NFC Android com.android.nfc.NfcService Messenger. , , , HostApduService HostNfcFService .

3 :

  • MSG_COMMAND_APDU = 0
  • MSG_RESPONSE_APDU = 1
  • MSG_DEACTIVATED = 2

0 (MSG_COMMAND_APDU) 1 (MSG_RESPONSE_APDU). 2 (MSG_DEACTIVATED). , , . , . , 100 + , , . , NfcService, ( ).

, , ( ), NfcService HAL .

+1

Source: https://habr.com/ru/post/1691796/


All Articles