3

I am trying to communicate between PN532 and HCE on Android with ISO 7816-4 command, I am successfully select the AID (a DF), but when I select the EF under that DF (that EF does not exist, so I assume that Select command will create that EF), and then write the records to that EF but it display like this:

inList passive target
write:  4A 1 0
read:   4B 1 1 0 4 60 4 8 23 5A 4D 5 75 80 70 2
write:  40 1 0 A4 4 0 7 F0 1 2 3 4 5 6 0
read:   41 0 48 65 6C 6C 6F 20 44 65 73 6B 74 6F 70 21

Successfully hehe 

48 65 6C 6C 6F 20 44 65 73 6B 74 6F 70 21    Hello Desktop!
write:  40 1 0 A4 2 C 1 1 0
read:   41 0 48 65 6C 6C 6F 20 44 65 73 6B 74 6F 70 21
Not enough space
write:  40 1 0 D2 0 0 7 42 41 4F 47 49 41 40 0
read:   41 0 4D 65 73 73 61 67 65 20 66 72 6F 6D 20 61 6E 64 72 6F 69 64 3A 20 30
Not enough space
write:  40 1 0 D2 0 2 4 44 4F 41 4E 0
read:   41 0 4D 65 73 73 61 67 65 20 66 72 6F 6D 20 61 6E 64 72 6F 69 64 3A 20 31
Not enough space
write:  40 1 0 B2 0 0 7 42 41 4F 47 49
read:   41 0 4D 65 73 73 61 67 65 20 66 72 6F 6D 20 61 6E 64 72 6F 69 64 3A 20 32
Not enough space
write:  40 1 0 B2 0 2 4 44 4F 41 4E 0
read:   41 0 4D 65 73 73 61 67 65 20 66 72 6F 6D 20 61 6E 64 72 6F 69 64 3A 20 33
Not enough space

I don't know what I am doing wrong here?

On Android, the log is :

04-15 09:36:54.024: D/HostEmulationManager(929): notifyHostEmulationData
04-15 09:36:54.024: W/System.err(17710): [B@41ed5970
04-15 09:36:54.024: I/HCEDEMO(17710): Received: ???????BAOGI
04-15 09:36:54.024: D/HostEmulationManager(929): Sending data
04-15 09:36:54.164: D/BrcmNfcJni(929): RoutingManager::stackCallback: event=0x17
04-15 09:36:54.164: D/BrcmNfcJni(929): RoutingManager::stackCallback: NFA_CE_DATA_EVT;       h=0x302; data len=10
04-15 09:36:54.164: D/HostEmulationManager(929): notifyHostEmulationData
04-15 09:36:54.164: W/System.err(17710): [B@41ed5e20
04-15 09:36:54.164: I/HCEDEMO(17710): Received: ?????DOAN??
04-15 09:36:54.174: D/HostEmulationManager(929): Sending data
04-15 09:36:54.885: D/BrcmNfcJni(929): RoutingManager::stackCallback: event=0x19
04-15 09:36:54.885: D/HostEmulationManager(929): notifyHostEmulationDeactivated
04-15 09:36:54.885: I/HCEDEMO(17710): Deactivated: 0
04-15 09:36:54.885: D/HostEmulationManager(929): Unbinding from service  ComponentInfo{de.grundid.hcedemo/de.grundid.hcedemo.MyHostApduService}
04-15 09:36:54.895: E/BrcmNfcNfa(929): UICC[0x0] is not activated

It displays that it can receive some data, but it misses some elements I want to transmit, but, from PN532, when I use read records, it does not display these data?

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
Bao Doan
  • 87
  • 1
  • 2
  • 13
  • You shall NOT assume that if an EF does not exist, Select command will create that EF. You need to create the EF using CREATE FILE command. – David Apr 15 '14 at 06:38
  • Sorry, but I could not find CREATE FILE command, only SELECT FILE command? – Bao Doan Apr 15 '14 at 08:53
  • The link for the commands I use is here: http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_6_basic_interindustry_commands.aspx – Bao Doan Apr 15 '14 at 08:53
  • You should refer to ISO 7816-9 for CREATE FILE command – David Apr 15 '14 at 14:19
  • @David The file system part is completely irrelevant as -- looking at the R-APDUs -- there obviously is no file system implementation behind the Android HCE service that Bao Doan is communicating with. – Michael Roland Apr 15 '14 at 14:38

1 Answers1

7

The commands that your Android HCE emulated smartcard application understands and processes are completely up to you (as long as they are formatted as valid ISO 7816-4 APDUs).

In your case, your Android HCE service obviously processes the SELECT (by DF name) APDU,

00 A4 04 00 07 F0010203040506 00

and gives this as a response:

48 65 6C 6C 6F 20 44 65 73 6B 74 6F 70 21 ("Hello Desktop!" when interpreted as ASCII)

(Note that this response is not a valid response APDU according to ISO 7816-4 as it lacks a status word.)

The next command you send is an invalid SELECT (by EF) command:

00 A4 02 0C 01 01 00

For that command, Lc should be 2 and the EF identifier should consist of two bytes if following ISO 7816-4. In response to that, your Android HCE service again sends

48 65 6C 6C 6F 20 44 65 73 6B 74 6F 70 21 ("Hello Desktop!" when interpreted as ASCII)

(Note that this response is not a valid response APDU according to ISO 7816-4 as it lacks a status word.)

So I would guess, that your Android HCE service performs a check like this:

public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
    if (apdu[1] == (byte)0xA4) {
        return "Hello Desktop!".getBytes("US-ASCII");
    }
}

The next command that you send is a malformed WRITE RECORD command that tries to write "BAOGIA@" in the first record of the cuirrently selected file (malformed, because a WRITE RECORD command normally does not have an Le field):

00 D2 00 00 07 42 41 4F 47 49 41 40 00

As a response your Android HCE service sends:

4D 65 73 73 61 67 65 20 66 72 6F 6D 20 61 6E 64 72 6F 69 64 3A 20 30 ("Message from android: 0" when interpreted as ASCII)

(Note that this response is again not a valid response APDU according to ISO 7816-4 as it lacks a status word.)

You then repeat the WRITE RECORD command with a different record payload and after that you send two malformed READ RECORD commands:

00 D2 00 02 04 44 4F 41 4E 00
00 B2 00 00 07 42 41 4F 47 49
00 B2 00 02 04 44 4F 41 4E 00

As a response your Android HCE service sends:

4D 65 73 73 61 67 65 20 66 72 6F 6D 20 61 6E 64 72 6F 69 64 3A 20 xx ("Message from android: X" when interpreted as ASCII)

Where xx seems to be an ASCII digit X that is incremented for each received command.

So I would guess, that your Android HCE service looks like this:

private int mCommandCounter = 0;
public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
    String response;
    if (apdu[1] == (byte)0xA4) {
        response = "Hello Desktop!";
    } else {
        response = "Message from android: " + Integer.toString(mCommandCounter);
        ++mCommandCounter;
    }
    return response.getBytes("US-ASCII");
}

So, to summarize this, your Android HCE service will understand and process only those commands that you (or whoever develops it) implement. So it is up to you what commands you can send to the HCE device. There is no file system behind it. ISO 7816-4 only suggests a file system layout for smartcard applications.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • You are right Michael, but how can I use the existence structure of I so 7816-4 instead of building my own commands? – Bao Doan Apr 16 '14 at 08:41
  • The Android HCE emulated smartcard application does **not have any** existing file structure. If **you** want **your** HCE application to accept certain commands, **you** have to implement them on the Android side. These commands can, **of course**, be commands that mimic a file system structure. – Michael Roland Apr 16 '14 at 10:02