SOERGI
SOERGI

Reputation: 193

HCE not working on other phones than Nexus 5

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.

Upvotes: 2

Views: 2866

Answers (3)

Santa Teclado
Santa Teclado

Reputation: 186

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.

Upvotes: 0

SOERGI
SOERGI

Reputation: 193

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.

Upvotes: 4

Michael Roland
Michael Roland

Reputation: 40849

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.

Upvotes: 1

Related Questions