ReX357
ReX357

Reputation: 1229

Setting up host card emulation

I am currently attempting to connect between an Arduino UNO with NFC Shield to my Nexus 4 running Android 4.4.

I have the service setup, it's simply logging at the moment. Problem is, the NFC intent doesn't get bound to my app. The debugger reports the following error:

11-24 02:45:46.139    4006-4027/? E/BrcmNfcNfa﹕ UICC[0x0] is not activated

So here's my 2 questions:

UPDATE

OK so here's the relevant part of my Arduino sketch where I build my APDU:

            uint8_t message[5];

            message[0] = 0x00;
            message[1] = 0xA4;
            message[2] = 0x04;
            message[3] = 0x00;
            message[4] = 0x08;              
            message[5] = 0x4C656C616E746F73ULL;

And here's the APDU service XML file in my android app:

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/servicedesc"
    android:requireDeviceUnlock="false">
    <aid-group android:description="@string/aiddescription"
        android:category="other">
        <aid-filter android:name="4C656C616E746F73"/>
    </aid-group>
</host-apdu-service>

And this is the log I get when I hover my phone over the NFC shield:

11-24 22:33:40.563    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: event=0x18
11-24 22:33:40.563    4006-4027/? D/HostEmulationManager﹕ notifyHostEmulationActivated
11-24 22:33:40.563    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: event=0x17
11-24 22:33:40.563    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=5
11-24 22:33:40.563    4006-4027/? D/HostEmulationManager﹕ notifyHostEmulationData
11-24 22:33:40.563    4006-4027/? D/HostEmulationManager﹕ Dropping non-select APDU in STATE_W4_SELECT
11-24 22:33:40.683    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: event=0x17
11-24 22:33:40.683    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=5
11-24 22:33:40.683    4006-4027/? D/HostEmulationManager﹕ notifyHostEmulationData
11-24 22:33:40.683    4006-4027/? D/HostEmulationManager﹕ Dropping non-select APDU in STATE_W4_SELECT
11-24 22:33:40.804    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: event=0x17
11-24 22:33:40.804    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=5
11-24 22:33:40.804    4006-4027/? D/HostEmulationManager﹕ notifyHostEmulationData
11-24 22:33:40.804    4006-4027/? D/HostEmulationManager﹕ Dropping non-select APDU in STATE_W4_SELECT
11-24 22:33:40.924    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: event=0x17
11-24 22:33:40.924    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=5
11-24 22:33:40.934    4006-4027/? D/HostEmulationManager﹕ notifyHostEmulationData
11-24 22:33:40.934    4006-4027/? D/HostEmulationManager﹕ Dropping non-select APDU in STATE_W4_SELECT
11-24 22:33:41.054    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: event=0x17
11-24 22:33:41.054    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=5
11-24 22:33:41.054    4006-4027/? D/HostEmulationManager﹕ notifyHostEmulationData
11-24 22:33:41.054    4006-4027/? D/HostEmulationManager﹕ Dropping non-select APDU in STATE_W4_SELECT
11-24 22:33:41.174    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: event=0x17
11-24 22:33:41.174    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: NFA_CE_DATA_EVT; h=0x302; data len=5
11-24 22:33:41.174    4006-4027/? D/HostEmulationManager﹕ notifyHostEmulationData
11-24 22:33:41.174    4006-4027/? D/HostEmulationManager﹕ Dropping non-select APDU in STATE_W4_SELECT
11-24 22:33:41.304    4006-4027/? D/BrcmNfcJni﹕ RoutingManager::stackCallback: event=0x19
11-24 22:33:41.304    4006-4027/? D/HostEmulationManager﹕ notifyHostEmulationDeactivated
11-24 22:33:41.304    4006-4027/? E/BrcmNfcNfa﹕ UICC[0x0] is not activated

How come Android isn't routing the APDU to my HCE Service?

Upvotes: 1

Views: 6046

Answers (3)

MandarCT
MandarCT

Reputation: 57

This can be done select the AID="F0394148148100" which is within proprietary range i. e. the bits 8-5 of the first byte must each be set to '1'. which is 'F' then use the AID in the APDU of the arudino as follows.

 private static byte[] AID={
              (byte)0x00
            , (byte)0xA4
            , (byte)0x04
            , (byte)0x00
            , (byte)0x07
            , (byte)0xF0, (byte)0x39, (byte)0x41, (byte)0x48, (byte)0x14, (byte)0x81, (byte)0x00
            , (byte)0x00
    };

Then use this AID in apduxml which is as follows

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

        </aid-group>
</host-apdu-service>  

then use the service which is defined in service tag of manifest of your application

public class MyHostApduService extends HostApduService
{

    @Override
    public void onDeactivated(int reason) 
    {
        // TODO Auto-generated method stub

    }

    @Override
    public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) 
    {
        // TODO Auto-generated method stub
        String n1="Hi there this is working";
        byte[] response=n1.getBytes();
        System.err.println(response);
        return response;
    }

}

then get the response APDU and get the string within result.

Upvotes: 1

Michael Roland
Michael Roland

Reputation: 40821

You do realize that

uint8_t message[5];

message[0] = 0x00;
message[1] = 0xA4;
message[2] = 0x04;
message[3] = 0x00;
message[4] = 0x08;              
message[5] = 0x4C656C616E746F73ULL;

will actually result in an array that looks like this?

uint8_t message[] = { 0x00, 0xA4, 0x04, 0x00, 0x08, 0x73 };

Which means that the remaining parts of your AID (0x4C, 0x65, 0x6C, 0x61, 0x6E, 0x74, 0x6F) are effectively cut off and consequently your APDU also has a wrong length (Lc) field.

So you may want to properly format the SELECT APDU:

uint8_t message[] = {
    0x00, /* CLA */
    0xA4, /* INS */
    0x04, /* P1  */
    0x00, /* P2  */
    0x08, /* Lc  */
    0x4C, 0x65, 0x6C, 0x61, 0x6E, 0x74, 0x6F, 0x73,
    0x00  /* Le  */ };

Moreover, I suggest that you use an AID of the form Fxxxxxxxxx... (i.e. the upper nibble of the first byte set to 0xF, length between 5 and 16 bytes) indicating a proprietary, unregistered AID, otherwise you might collide with other standard applications. See ISO/IEC 7816-4 for more information on properly formatting AIDs.

Upvotes: 4

geri-m
geri-m

Reputation: 695

  • the AID needs to meet the ISO Criteria with regard to length, eg: aid-filter android:name="F0010203040506"
  • the Arduino needs to send a well-format APDU the the Nexus. (CLA/INS/P1/P2/Len)
  • with regard to the error: it seams that your messages are routed to the UICC. This could be the case, if the HCE Application does not define the correct AID you are selecting with the Aduino Board.

The example here (http://developer.android.com/guide/topics/connectivity/nfc/hce.html) works out of the box.

Upvotes: 0

Related Questions