问题
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?
回答1:
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.
回答2:
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.
回答3:
- 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.
来源:https://stackoverflow.com/questions/20173181/setting-up-host-card-emulation