0

I' currently trying to get HCE running with my arduino uno device mounted with a seeed NFC Shield V 2.0

I'm using the example code from https://github.com/Seeed-Studio/PN532/blob/master/PN532/examples/android_hce/android_hce.ino

#include <SPI.h>
#include <PN532_SPI.h>
#include <PN532Interface.h>
#include <PN532.h>

PN532_SPI pn532spi(SPI, 10);
PN532 nfc(pn532spi);


void setup()
{
    Serial.begin(115200);
    Serial.println("-------Peer to Peer HCE--------");

    nfc.begin();

    uint32_t versiondata = nfc.getFirmwareVersion();
    if (! versiondata) {
      Serial.print("Didn't find PN53x board");
      while (1); // halt
    }

    // Got ok data, print it out!
    Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
    Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
    Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

    // Set the max number of retry attempts to read from a card
    // This prevents us from waiting forever for a card, which is
    // the default behaviour of the PN532.
    //nfc.setPassiveActivationRetries(0xFF);

    // configure board to read RFID tags
    nfc.SAMConfig();
}

void loop()
{
  bool success;

  uint8_t responseLength = 32;

  Serial.println("Waiting for an ISO14443A card");

  // set shield to inListPassiveTarget
  success = nfc.inListPassiveTarget();

  if(success) {

     Serial.println("Found something!");

    uint8_t selectApdu[] = { 0x00, /* CLA */
                              0xA4, /* INS */
                              0x04, /* P1  */
                              0x00, /* P2  */
                              0x07, /* Length of AID  */
                              0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* AID defined on Android App */
                              0x00  /* Le  */ };

    uint8_t response[32];

    success = nfc.inDataExchange(selectApdu, sizeof(selectApdu), response, &responseLength);

    if(success) {

      Serial.print("responseLength: "); Serial.println(responseLength);

      nfc.PrintHexChar(response, responseLength);

      do {
        uint8_t apdu[] = "Hello from Arduino";
        uint8_t back[32];
        uint8_t length = 32;

        success = nfc.inDataExchange(apdu, sizeof(apdu), back, &length);

        if(success) {

          Serial.print("responseLength: "); Serial.println(length);

          nfc.PrintHexChar(back, length);
        }
        else {

          Serial.println("Broken connection?");
        }
      }
      while(success);
    }
    else {

      Serial.println("Failed sending SELECT AID");
    }
  }
  else {

    Serial.println("Didn't find anything!");
  }

  delay(1000);
}

void printResponse(uint8_t *response, uint8_t responseLength) {

   String respBuffer;

    for (int i = 0; i < responseLength; i++) {

      if (response[i] < 0x10)
        respBuffer = respBuffer + "0"; //Adds leading zeros if hex value is smaller than 0x10

      respBuffer = respBuffer + String(response[i], HEX) + " ";
    }

    Serial.print("response: "); Serial.println(respBuffer);
}

void setupNFC() {

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }

  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();
}

My android code is taken from the HCE development guide and I also tried the code form https://github.com/grundid/host-card-emulation-sample

My problem is, that the arduino code doesn't even recognize a tag. So all I'm getting is:

Waiting for an ISO14443A card
Didn't find anything!
Waiting for an ISO14443A card
Didn't find anything!
Waiting for an ISO14443A card 

As a matter of fact, on the Android side, I do not receive any packet, neither is the fancy NFC sound playing, which usually indicates that at least something is happening. So my question is, has someone tried to use the Galaxy S3 with cyanogenmod 10 along with HCE support. I'm really out of any ideas, I triplechecked my code, read a lots of question here on SO, but all did at least receive something from the NFC Shield.

I know that the common NFC mode works fine, as I have an application using NFC in "normal" mode. When I run this NFC-protocol on my arduino, all applications receive a packet, (although they can't route them correctly, because they are not adpu packets)

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
evildead
  • 4,607
  • 4
  • 25
  • 49
  • I just wanted to give an update here. It was the device, which had the NXP NFC Chipset. I tried the same code with a Nexus 4 (which has a Broadcom NFC chipset), and everything works flawlessly. – evildead Mar 31 '14 at 09:59

2 Answers2

3

Android 4.4 HCE does not run on Samsung Galaxy S3 with NXP chip. I had tested for both Galaxy Nexus, Nexus 7(2012) and Galaxy S3. All these 3 devices are not able to run HCE on Kitkat.

You may check the device for HCE support:

boolean isHceSupported = getPackageManager().hasSystemFeature("android.hardware.nfc.hce");

arghtype
  • 4,376
  • 11
  • 45
  • 60
  • You may use the [NFC Check by Tapkey](https://play.google.com/store/apps/details?id=net.tpky.tools.nfccheck) App to view details about NFC Features supported on your phone. This only checks for the official HCE API, not for the Cyanogen API. – MarkusM Jul 22 '14 at 06:48
  • Hi Makus, the nfc is supported but the HCE is not. The reason is the the android route message to the builtin SE, and SE keep reply LLC length mismatch. As a result the reader will keep beeping. For those HCE enabled device the reader will only beep once and the device will waiting for the SELECT AID request from reader rather than report and LLC error. – user3860290 Jul 22 '14 at 10:16
2

Android HCE (as provided by the Android 4.4 HCE API) is not supported on CyanogenMod 10.*. That API is only available starting with CyanogenMod 11 and even then I'm not sure that the CyanogenMod implementation of the Android HCE API works on devices with NXP chipset (e.g. Galaxy S3).

CyanogenMod 10.* has a different HCE API. See Nikolay's blog for an example on how to use that API.

Basically, for your Arduino program to work, you would have to implement HCE based on the IsoPcdA technology.

Also note that if you ever switch from CyanogenMod HCE to Android HCE, you have to use ISO 7816-4 compliant APDUs. Thus, an "APDU" like you use it in your code above,

apdu[] = "Hello from Arduino";

would not work. CyanogenMod HCE, however, does not require the use of ISO 7816-4 APDUs on top of the ISO 14443-4 transport protocol and will, therefore, happily accept this string instead of an APDU.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • Hi Michael. Thanks for your answer. I changed the subject as I was referencing to cyanogenmod 11. Was a typo Form me. So what I read out is that even with cm 11 nxp chipset is not supported right? Found that in the net too, on my way back home in the train. So I guess I have to use another phone. – evildead Mar 27 '14 at 18:10
  • You could still give the above method (CyanogenMod HCE) a try. I would assume that this method is still available in CM 11, though I have not checked that. – Michael Roland Mar 27 '14 at 18:41