2

I am currently attempting to communicate with a device using HCE on android. I have created my own NFC service that extends the HostApduService class, declared the NFC parts in the AndroidManifest.xml and created the apduservice.xml where the AIDs are specified.

When I run my app on a Nexus4 or Nexus 5 (4.4.4) device all works as expected(!), I receive the APDU array from the device and send back an answer and then continue with the propriatary protocol. So it seems the above configuration part is properly set up.

However, when I deploy my app on a Sony Xperia Z2 (4.4.2), a Samsung Galaxy S5 (4.4.2) or a Motorola Moto X (4.4.3) my code in processCommandApdu() is not even called. The first line of that method contains a log output which I don't see at all.

According to the list compiled here my devices should support HCE.

When I tap the (not working) phones in front of the device I get the following log output, but I cannot seem to find the exact meaning of the error code:

D/STATUSBAR-NetworkController(1085): refreshSignalCluster - setNWBoosterIndicators(false)
D/STATUSBAR-NetworkController(1085): refreshSignalCluster: data=-1 bt=false
D/STATUSBAR-IconMerger(1085): checkOverflow(504), More:false, Req:false Child:6
D/HostEmulationManager(1277): notifyHostEmulationActivated
D/HostEmulationManager(1277): notifyHostEmulationData
D/HostEmulationManager(1277): call findSelectAid - 1
D/HostEmulationManager(1277): Selecting next, last or previous AID occurrence is not supported
D/NfcService(1277): onSeListenDeactivated - Skip this one, user select the onHost apk temporarily
D/HostEmulationManager(1277): notifyHostEmulationDeactivated
E/NfcNfa(1277): UICC/ESE[0x402] is not activated

Where can I look up the error code 0x402?

Here the apduservice.xml:

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
       android:description="@string/service_desc" 
       android:requireDeviceUnlock="false">
<aid-group android:description="@string/aid_description"
           android:category="other">
    <aid-filter android:name="F04B4142413134" />
    <aid-filter android:name="F0404B75737469"/>
</aid-group>
</host-apdu-service>

The APDU command I receive with the Nexus 5 looks as follows, which looks to me as if it follows the APDU spec to select an application:

output: [00, a4, 04, 00, 07, f0, 4b, 41, 42, 41, 31, 34]
00 -> class
a4 -> instruction select
04 -> P1, select by name
00 -> P2
07 -> length of the following aid
rest -> corresponds to the first aid-filter

Bonus question:

How can I set breakpoints in the android OS source code, for example in HostApduService.java? I can open the file and see the code but setting the breakpoint does not do any effect, at least visually it is not shown, also when run in debug mode, it doesn't break at that spot.

I'm guessing that there is something happening when android is supposed to select the app that corresponds to the specified AID. My question is somewhat related to this one, but answers are related to payment which didn't help me much.

Any ideas why I cannot run it on other devices? Thanks in advance.

Community
  • 1
  • 1
SOERGI
  • 193
  • 2
  • 13
  • The line "Selecting next, last or previous AID occurrence is not supported" suggests that the reader side is not sending the APDU that you show in your post. What APDU command do you actually send to the phone? Particularly, could you verify that the lower two bits of P2 are set to 00? – Michael Roland Sep 25 '14 at 13:55
  • Thanks for your comment. I cannot directly verify that device is sending the same APDU commands to all of the smart phones, since I do not get the byte array. According to the manufacturer of the device to read, it should always send the same command. Is there a way to read the AID (or APDU command) from an app that does not know the AID of the device to read? – SOERGI Sep 26 '14 at 14:59

3 Answers3

4

In the meanwhile I figured out the root of the problem. Following Michael Roland's suggestion I tried to find out what APDU command the reader was sending. I tested my app with all the android phones I could get my hands on and found out that all phones that have a NFC controller manifactured by NXP where not working.

  • working: Nexus 4, 5, 7 G2, 10 (Broadcom chips)
  • not working: Nexus S, Nexus 7 G1, Samsung Galaxy S5, Sony Xperia Z2, Motorola Moto X (NXP chips)

The reason being that the random ID sent by NXP chips is not following the standard my reader was expecting (as described here). It is supposed to look according to this:

0x08, A, B, C

where A,B and C are random. But the IDs sent by the NXP chips where either constants

0x1, 0x2, 0x3, 0x4

or there were 7 bytes that were random after the first 0x08, instead of only 3 Bytes.

This caused the reader to send an APDU which did not make android trigger to call my processCommandApdu() method.

Community
  • 1
  • 1
SOERGI
  • 193
  • 2
  • 13
  • There was nothing I could do on Android app side. The workaround was that manufacturer of the device which sends the APDU command to the smartphone adapted the device's firmware to accept non-standard random IDs such as the ones from NXP chips described above. – SOERGI Jan 30 '15 at 08:10
  • Basically, I am facing same sort of problem. My basic PoC is working fine on Google Nexus 5/4 but its not able to invoke HostApduService on samsung galaxy S4/S5. Unfortunately my clients has sumsung devices!! – iuq Jan 30 '15 at 10:44
1

The error

E/NfcNfa(1277): UICC/ESE[0x402] is not activated

is not really the relevant error in your case. The important message is

D/HostEmulationManager(1277): Selecting next, last or previous AID occurrence is not supported

This clearly indicates that the P2 byte of the SELECT (by DF name/AID) command is not equal to 0x00. The current Android HCE implementation requires the application selection command to have P2 equal to 0x00 (indicating selection of the "first or only occurence" of the selected AID/DF name). See HostEmulationManager.java:437.

Therefore, you need to make sure that the reader side is sending proper commands for application selection.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
0

The Problem is caused by the fact that for some reason lollipop does not support Card Identifier or CID in the APDU sent. Thus when the reader sends the next command with CID the phone will disable that command and remain in recieving mode. This thus requires one to send APDU commands without CID. The work around is to contact the device manufacturers to support cards that do not require CID as @SOERGI said.

Santa Teclado
  • 186
  • 10