Search code examples
androidarduinonfcapduhce

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:

  • On the Arduino side of things, what kind of 'message' does the NFC shield needs to send to my phone for my phone to understand that I'm looking for a certain app in category 'Other'?

  • On the android side of things, what will be the aid-filter tag value to catch that intent? Can I make up a custom one or do I need to stick to some kind of ISO specification for this to work?

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?


Solution

  • 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.