Make Transceive Length configurable for ISO DEP Technology

ISO_DEP_MAX_TRANSCEIVE has been added to indicate the maximum APDU
length that is supported by the underlying NFC chip. If the
configuration is not set, default maximum of 261 is set.

Check if device supports Extended APDUs, if yes, return true for
getExtendedLengthApdusSupported()

Test: Read IsoDep Tag and check the maxTransceive length.
Bug: 37005118
Change-Id: I198c06fdcbcd3b45932f544fa063e920f84f7968
diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp
index 9ac86b6..817da21 100644
--- a/nci/jni/NativeNfcManager.cpp
+++ b/nci/jni/NativeNfcManager.cpp
@@ -1844,6 +1844,28 @@
       PowerSwitch::POWER_STATE_OFF);
 }
 
+/*******************************************************************************
+**
+** Function:        nfcManager_getIsoDepMaxTransceiveLength
+**
+** Description:     Get maximum ISO DEP Transceive Length supported by the NFC
+**                  chip. Returns default 261 bytes if the property is not set.
+**
+** Returns:         max value.
+**
+*******************************************************************************/
+static jint nfcManager_getIsoDepMaxTransceiveLength(JNIEnv*, jobject) {
+  unsigned long maxLength;
+  /* Check if extended APDU is supported by the chip.
+   * If not, default value is returned.
+   * The maximum length of a default IsoDep frame consists of:
+   * CLA, INS, P1, P2, LC, LE + 255 payload bytes = 261 bytes
+   */
+  if (!GetNumValue(NAME_ISO_DEP_MAX_TRANSCEIVE, &maxLength, sizeof(maxLength)))
+    maxLength = 261;
+  return maxLength;
+}
+
 /*****************************************************************************
 **
 ** JNI functions for android-4.0.1_r1
@@ -1921,7 +1943,10 @@
 
     {"getNciVersion", "()I", (void*)nfcManager_doGetNciVersion},
     {"doEnableDtaMode", "()V", (void*)nfcManager_doEnableDtaMode},
-    {"doDisableDtaMode", "()V", (void*)nfcManager_doDisableDtaMode}
+    {"doDisableDtaMode", "()V", (void*)nfcManager_doDisableDtaMode},
+
+    {"getIsoDepMaxTransceiveLength", "()I",
+     (void*)nfcManager_getIsoDepMaxTransceiveLength}
 
 };
 
diff --git a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
index 488801f..5354193 100755
--- a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
+++ b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
@@ -50,6 +50,7 @@
     /* Native structure */
     private long mNative;
 
+    private int mIsoDepMaxTransceiveLength;
     private final DeviceHostListener mListener;
     private final Context mContext;
 
@@ -75,9 +76,13 @@
 
     private native boolean doInitialize();
 
+    private native int getIsoDepMaxTransceiveLength();
+
     @Override
     public boolean initialize() {
-        return doInitialize();
+        boolean ret = doInitialize();
+        mIsoDepMaxTransceiveLength = getIsoDepMaxTransceiveLength();
+        return ret;
     }
 
     private native void doEnableDtaMode();
@@ -303,12 +308,7 @@
             case (TagTechnology.NFC_V):
                 return 253; // PN544 RF buffer = 255 bytes, subtract two for CRC
             case (TagTechnology.ISO_DEP):
-                /* The maximum length of a normal IsoDep frame consists of:
-                 * CLA, INS, P1, P2, LC, LE + 255 payload bytes = 261 bytes
-                 * such a frame is supported. Extended length frames however
-                 * are not supported.
-                 */
-                return 261; // Will be automatically split in two frames on the RF layer
+                return mIsoDepMaxTransceiveLength;
             case (TagTechnology.NFC_F):
                 return 252; // PN544 RF buffer = 255 bytes, subtract one for SoD, two for CRC
             default:
@@ -331,7 +331,9 @@
 
     @Override
     public boolean getExtendedLengthApdusSupported() {
-        // TODO check BCM support
+        /* 261 is the default size if extended length frames aren't supported */
+        if (getMaxTransceiveLength(TagTechnology.ISO_DEP) > 261)
+            return true;
         return false;
     }