Reputation: 193
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
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
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.
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
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