evildead
evildead

Reputation: 4757

Android HCE with Arduino and Galaxy S3 cyanogenmod 11

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)

Upvotes: 0

Views: 1497

Answers (2)

user3860290
user3860290

Reputation: 31

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");

Upvotes: 3

Michael Roland
Michael Roland

Reputation: 40849

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.

Upvotes: 2

Related Questions