Snap for 4459973 from 69dc1a5a267e3c7c5e43661bff9523e0d417c418 to pi-release

Change-Id: I1fc726ccbf26c7a44f8bec2d083ad4bc3c1c46a4
diff --git a/Android.bp b/Android.bp
index 2bfbef0..9679a81 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1 +1 @@
-subdirs = ["src"]
+subdirs = ["src", "utils"]
diff --git a/run_unit_tests.sh b/run_unit_tests.sh
new file mode 100755
index 0000000..c2c9904
--- /dev/null
+++ b/run_unit_tests.sh
@@ -0,0 +1,125 @@
+#!/bin/sh
+
+known_tests=(
+  nfc_test_utils
+)
+
+known_remote_tests=(
+)
+
+
+usage() {
+  binary="$(basename "$0")"
+  echo "Usage: ${binary} --help"
+  echo "       ${binary} [-i <iterations>] [-s <specific device>] [--all] [<test name>[.<filter>] ...] [--<arg> ...]"
+  echo
+  echo "Unknown long arguments are passed to the test."
+  echo
+  echo "Known test names:"
+
+  for name in "${known_tests[@]}"
+  do
+    echo "    ${name}"
+  done
+
+  echo
+  echo "Known tests that need a remote device:"
+  for name in "${known_remote_tests[@]}"
+  do
+    echo "    ${name}"
+  done
+}
+
+iterations=1
+device=
+tests=()
+test_args=()
+while [ $# -gt 0 ]
+do
+  case "$1" in
+    -h|--help)
+      usage
+      exit 0
+      ;;
+    -i)
+      shift
+      if [ $# -eq 0 ]; then
+        echo "error: number of iterations expected" 1>&2
+        usage
+        exit 2
+      fi
+      iterations=$(( $1 ))
+      shift
+      ;;
+    -s)
+      shift
+      if [ $# -eq 0 ]; then
+        echo "error: no device specified" 1>&2
+        usage
+        exit 2
+      fi
+      device="$1"
+      shift
+      ;;
+    --all)
+      tests+=( "${known_tests[@]}" )
+      shift
+      ;;
+    --*)
+      test_args+=( "$1" )
+      shift
+      ;;
+    *)
+      tests+=( "$1" )
+      shift
+      ;;
+  esac
+done
+
+if [ "${#tests[@]}" -eq 0 ]; then
+  tests+=( "${known_tests[@]}" )
+fi
+
+adb=( "adb" )
+if [ -n "${device}" ]; then
+  adb+=( "-s" "${device}" )
+fi
+
+failed_tests=()
+for spec in "${tests[@]}"
+do
+  name="${spec%%.*}"
+  binary="/data/nativetest/${name}/${name}"
+
+  push_command=( "${adb[@]}" push {"${ANDROID_PRODUCT_OUT}",}"${binary}" )
+  test_command=( "${adb[@]}" shell "${binary}" )
+  if [ "${name}" != "${spec}" ]; then
+    filter="${spec#*.}"
+    test_command+=( "--gtest_filter=${filter}" )
+  fi
+  test_command+=( "${test_args[@]}" )
+
+  echo "--- ${name} ---"
+  echo "pushing..."
+  "${push_command[@]}"
+  echo "running..."
+  failed_count=0
+  for i in $(seq 1 ${iterations})
+  do
+    "${test_command[@]}" || failed_count=$(( $failed_count + 1 ))
+  done
+
+  if [ $failed_count != 0 ]; then
+    failed_tests+=( "${name} ${failed_count}/${iterations}" )
+  fi
+done
+
+if [ "${#failed_tests[@]}" -ne 0 ]; then
+  for failed_test in "${failed_tests[@]}"
+  do
+    echo "!!! FAILED TEST: ${failed_test} !!!"
+  done
+  exit 1
+fi
+
+exit 0
diff --git a/src/Android.bp b/src/Android.bp
index 19725dc..a5f613a 100644
--- a/src/Android.bp
+++ b/src/Android.bp
@@ -23,6 +23,9 @@
         "libutils",
         "android.hardware.nfc@1.0",
     ],
+    static_libs: [
+        "libnfcutils",
+    ],
     cflags: [
         "-DBUILDCFG=1",
         "-Wall",
diff --git a/src/adaptation/debug_nfcsnoop.cc b/src/adaptation/debug_nfcsnoop.cc
index 057c70f..2339589 100644
--- a/src/adaptation/debug_nfcsnoop.cc
+++ b/src/adaptation/debug_nfcsnoop.cc
@@ -20,9 +20,10 @@
 #include <zlib.h>
 #include <mutex>
 
+#include <ringbuffer.h>
+
 #include "bt_types.h"
 #include "include/debug_nfcsnoop.h"
-#include "include/ringbuffer.h"
 #include "nfc_int.h"
 
 #define USEC_PER_SEC 1000000ULL
diff --git a/src/include/config.h b/src/include/config.h
index de282c3..c1dbf6e 100644
--- a/src/include/config.h
+++ b/src/include/config.h
@@ -39,5 +39,6 @@
 #define NAME_NFA_POLL_BAIL_OUT_MODE "NFA_POLL_BAIL_OUT_MODE"
 #define NAME_NFA_PROPRIETARY_CFG "NFA_PROPRIETARY_CFG"
 #define NAME_NFA_AID_BLOCK_ROUTE "NFA_AID_BLOCK_ROUTE"
+#define NAME_ISO_DEP_MAX_TRANSCEIVE "ISO_DEP_MAX_TRANSCEIVE"
 
 #endif
diff --git a/src/include/gki_target.h b/src/include/gki_target.h
index 3bf0c8f..dfca10b 100644
--- a/src/include/gki_target.h
+++ b/src/include/gki_target.h
@@ -168,7 +168,7 @@
 
 /* The size of the buffers in pool 3. */
 #ifndef GKI_BUF3_SIZE
-#define GKI_BUF3_SIZE 2500
+#define GKI_BUF3_SIZE (0xFFB0)
 #endif
 
 /* The number of buffers in buffer pool 3. */
diff --git a/utils/Android.bp b/utils/Android.bp
new file mode 100644
index 0000000..c34591f
--- /dev/null
+++ b/utils/Android.bp
@@ -0,0 +1,38 @@
+cc_defaults {
+    name: "nfc_utils_defaults",
+    include_dirs: [
+        "system/nfc",
+    ],
+    target: {
+        linux_glibc: {
+            cflags: ["-D_GNU_SOURCE"],
+        },
+        darwin: {
+            enabled: false,
+        }
+    },
+}
+
+cc_library_static {
+    name: "libnfcutils",
+    defaults: ["nfc_utils_defaults"],
+    export_include_dirs = ["include"],
+    host_supported: true,
+    srcs: [
+        "ringbuffer.cc",
+    ],
+}
+
+cc_test {
+    name: "nfc_test_utils",
+    defaults: ["nfc_utils_defaults"],
+    test_suites: ["device-tests"],
+    host_supported: true,
+    srcs: [
+        "test/ringbuffer_test.cc",
+    ],
+    static_libs: [
+        "libnfcutils",
+        "libgmock",
+    ],
+}
diff --git a/src/include/ringbuffer.h b/utils/include/ringbuffer.h
similarity index 100%
rename from src/include/ringbuffer.h
rename to utils/include/ringbuffer.h
diff --git a/src/adaptation/ringbuffer.cc b/utils/ringbuffer.cc
similarity index 100%
rename from src/adaptation/ringbuffer.cc
rename to utils/ringbuffer.cc
diff --git a/utils/test/ringbuffer_test.cc b/utils/test/ringbuffer_test.cc
new file mode 100644
index 0000000..bebf8a2
--- /dev/null
+++ b/utils/test/ringbuffer_test.cc
@@ -0,0 +1,138 @@
+#include <gtest/gtest.h>
+
+#include <ringbuffer.h>
+
+TEST(RingbufferTest, test_new_simple) {
+  ringbuffer_t* rb = ringbuffer_init(4096);
+  ASSERT_TRUE(rb != NULL);
+  EXPECT_EQ((size_t)4096, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)0, ringbuffer_size(rb));
+  ringbuffer_free(rb);
+}
+
+TEST(RingbufferTest, test_insert_basic) {
+  ringbuffer_t* rb = ringbuffer_init(16);
+
+  uint8_t buffer[10] = {0x01, 0x02, 0x03, 0x04, 0x05,
+                        0x06, 0x07, 0x08, 0x09, 0x0A};
+  ringbuffer_insert(rb, buffer, 10);
+  EXPECT_EQ((size_t)10, ringbuffer_size(rb));
+  EXPECT_EQ((size_t)6, ringbuffer_available(rb));
+
+  uint8_t peek[10] = {0};
+  size_t peeked = ringbuffer_peek(rb, 0, peek, 10);
+  EXPECT_EQ((size_t)10, ringbuffer_size(rb));  // Ensure size doesn't change
+  EXPECT_EQ((size_t)6, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)10, peeked);
+  ASSERT_TRUE(0 == memcmp(buffer, peek, peeked));
+
+  ringbuffer_free(rb);
+}
+
+TEST(RingbufferTest, test_insert_full) {
+  ringbuffer_t* rb = ringbuffer_init(5);
+
+  uint8_t aa[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
+  uint8_t bb[] = {0xBB, 0xBB, 0xBB, 0xBB, 0xBB};
+  uint8_t peek[5] = {0};
+
+  size_t added = ringbuffer_insert(rb, aa, 7);
+  EXPECT_EQ((size_t)5, added);
+  EXPECT_EQ((size_t)0, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)5, ringbuffer_size(rb));
+
+  added = ringbuffer_insert(rb, bb, 5);
+  EXPECT_EQ((size_t)0, added);
+  EXPECT_EQ((size_t)0, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)5, ringbuffer_size(rb));
+
+  size_t peeked = ringbuffer_peek(rb, 0, peek, 5);
+  EXPECT_EQ((size_t)5, peeked);
+  EXPECT_EQ((size_t)0, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)5, ringbuffer_size(rb));
+
+  ASSERT_TRUE(0 == memcmp(aa, peek, peeked));
+
+  ringbuffer_free(rb);
+}
+
+TEST(RingbufferTest, test_multi_insert_delete) {
+  ringbuffer_t* rb = ringbuffer_init(16);
+  EXPECT_EQ((size_t)16, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)0, ringbuffer_size(rb));
+
+  // Insert some bytes
+
+  uint8_t aa[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
+  size_t added = ringbuffer_insert(rb, aa, sizeof(aa));
+  EXPECT_EQ((size_t)8, added);
+  EXPECT_EQ((size_t)8, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)8, ringbuffer_size(rb));
+
+  uint8_t bb[] = {0xBB, 0xBB, 0xBB, 0xBB, 0xBB};
+  ringbuffer_insert(rb, bb, sizeof(bb));
+  EXPECT_EQ((size_t)3, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)13, ringbuffer_size(rb));
+
+  uint8_t content[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+                       0xAA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB};
+  uint8_t peek[16] = {0};
+  size_t peeked = ringbuffer_peek(rb, 0, peek, 16);
+  EXPECT_EQ((size_t)13, peeked);
+  ASSERT_TRUE(0 == memcmp(content, peek, peeked));
+
+  // Delete some bytes
+
+  ringbuffer_delete(rb, sizeof(aa));
+  EXPECT_EQ((size_t)11, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)5, ringbuffer_size(rb));
+
+  // Add some more to wrap buffer
+
+  uint8_t cc[] = {0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC};
+  ringbuffer_insert(rb, cc, sizeof(cc));
+  EXPECT_EQ((size_t)2, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)14, ringbuffer_size(rb));
+
+  uint8_t content2[] = {0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC};
+  peeked = ringbuffer_peek(rb, 0, peek, 7);
+  EXPECT_EQ((size_t)7, peeked);
+  ASSERT_TRUE(0 == memcmp(content2, peek, peeked));
+
+  // Pop buffer
+
+  memset(peek, 0, 16);
+  size_t popped = ringbuffer_pop(rb, peek, 7);
+  EXPECT_EQ((size_t)7, popped);
+  EXPECT_EQ((size_t)9, ringbuffer_available(rb));
+  ASSERT_TRUE(0 == memcmp(content2, peek, peeked));
+
+  // Add more again to check head motion
+
+  uint8_t dd[] = {0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD};
+  added = ringbuffer_insert(rb, dd, sizeof(dd));
+  EXPECT_EQ((size_t)8, added);
+  EXPECT_EQ((size_t)1, ringbuffer_available(rb));
+
+  // Delete everything
+
+  ringbuffer_delete(rb, 16);
+  EXPECT_EQ((size_t)16, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)0, ringbuffer_size(rb));
+
+  // Add small token
+
+  uint8_t ae[] = {0xAE, 0xAE, 0xAE};
+  added = ringbuffer_insert(rb, ae, sizeof(ae));
+  EXPECT_EQ((size_t)13, ringbuffer_available(rb));
+
+  // Get everything
+
+  popped = ringbuffer_pop(rb, peek, 16);
+  EXPECT_EQ(added, popped);
+  EXPECT_EQ((size_t)16, ringbuffer_available(rb));
+  EXPECT_EQ((size_t)0, ringbuffer_size(rb));
+  ASSERT_TRUE(0 == memcmp(ae, peek, popped));
+
+  ringbuffer_free(rb);
+}