nfc: dynamic memory allocation

The static buffer pool is disabled and
 the buffers are allocated on demand.
Only buffer allocation mechanism is affected no attempts to
 optimize memory allocations in the code.
Basic memory leak check is also included for testing.

Bug: 146228323
Test: runs ok, no obvious regressions
Change-Id: I804dd60ef2d092d98e5340ab9236cff6e18f275f
diff --git a/SN100x/src/Android.bp b/SN100x/src/Android.bp
index 44e03e9..30dfbfc 100755
--- a/SN100x/src/Android.bp
+++ b/SN100x/src/Android.bp
@@ -27,6 +27,7 @@
         "libnfcutils",
     ],
     cflags: [
+        "-DDYN_ALLOC=1",
         "-DBUILDCFG=1",
         "-Wall",
         "-Werror",
diff --git a/SN100x/src/gki/common/gki_buffer.cc b/SN100x/src/gki/common/gki_buffer.cc
index 0621d24..a4da12a 100755
--- a/SN100x/src/gki/common/gki_buffer.cc
+++ b/SN100x/src/gki/common/gki_buffer.cc
@@ -47,6 +47,8 @@
 static void gki_remove_from_pool_list(uint8_t pool_id);
 #endif /*  BTU_STACK_LITE_ENABLED == FALSE */
 
+extern bool nfc_debug_enabled;
+
 using android::base::StringPrintf;
 
 /*******************************************************************************
@@ -272,22 +274,40 @@
 ******************************************************************************/
 void* GKI_getbuf(uint16_t size) {
   BUFFER_HDR_T* p_hdr;
+  FREE_QUEUE_T* Q;
 
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
   if (size == 0) {
     LOG(ERROR) << StringPrintf("getbuf: Size is zero");
+#ifndef DYN_ALLOC
     abort();
+#else
+    return (nullptr);
+#endif
   }
 
-  size_t total_sz = size + sizeof(BUFFER_HDR_T);
+  size = ALIGN_POOL(size);
+  size_t total_sz = size + sizeof(BUFFER_HDR_T)
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+                    + sizeof(uint32_t);
+#else
+      ;
+#endif
   p_hdr = (BUFFER_HDR_T*)GKI_os_malloc(total_sz);
   if (!p_hdr) {
     LOG(ERROR) << StringPrintf("unable to allocate buffer!!!!!");
+#ifndef DYN_ALLOC
     abort();
+#else
+    return (nullptr);
+#endif
   }
 
   memset(p_hdr, 0, total_sz);
 
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+  *(uint32_t*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE + size) = MAGIC_NO;
+#endif
   p_hdr->task_id = GKI_get_taskid();
   p_hdr->status = BUF_STATUS_UNLINKED;
   p_hdr->p_next = nullptr;
@@ -296,12 +316,18 @@
   p_hdr->q_id = 0;
   p_hdr->size = size;
 
-  UNUSED(gki_alloc_free_queue);
+  GKI_disable();
+  Q = &gki_cb.com.freeq[p_hdr->q_id];
+  if (++Q->cur_cnt > Q->max_cnt) Q->max_cnt = Q->cur_cnt;
+  GKI_enable();
 
+  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
+      "%s %p %d:%d", __func__, ((uint8_t*)p_hdr + BUFFER_HDR_SIZE), Q->cur_cnt,
+      Q->max_cnt);
+  UNUSED(gki_alloc_free_queue);
   return (void*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE);
 #else
   uint8_t i;
-  FREE_QUEUE_T* Q;
   tGKI_COM_CB* p_cb = &gki_cb.com;
 
   if (size == 0) {
@@ -386,7 +412,7 @@
 **
 *******************************************************************************/
 void* GKI_getpoolbuf(uint8_t pool_id) {
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
   uint16_t size = 0;
   switch (pool_id) {
     // NFC_NCI_POOL_ID, NFC_RW_POOL_ID and NFC_CE_POOL_ID are all redefined to
@@ -402,7 +428,11 @@
 
     default:
       LOG(ERROR) << StringPrintf("Unknown pool ID: %d", pool_id);
+#ifndef DYN_ALLOC
       abort();
+#else
+      return (nullptr);
+#endif
       break;
   }
 
@@ -467,22 +497,6 @@
 *******************************************************************************/
 void GKI_freebuf(void* p_buf) {
   BUFFER_HDR_T* p_hdr;
-
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-  p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
-
-  if (p_hdr->status != BUF_STATUS_UNLINKED) {
-    GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
-    return;
-  }
-
-  if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS) {
-    GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
-    return;
-  }
-
-  GKI_os_free(p_hdr);
-#else
   FREE_QUEUE_T* Q;
 
 #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
@@ -504,6 +518,14 @@
     return;
   }
 
+#if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
+  GKI_disable();
+  Q = &gki_cb.com.freeq[p_hdr->q_id];
+  if (Q->cur_cnt > 0) Q->cur_cnt--;
+  GKI_enable();
+
+  GKI_os_free(p_hdr);
+#else
   GKI_disable();
 
   /*
@@ -542,7 +564,7 @@
 
   p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
 
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
   return p_hdr->size;
 #else
   if ((uintptr_t)p_hdr & 1) return (0);
@@ -574,6 +596,7 @@
 
   if (*magic == MAGIC_NO) return false;
 
+  LOG(ERROR) << StringPrintf("%s 0x%x %p", __func__, *magic, p_buf);
   return true;
 
 #else
diff --git a/SN100x/src/gki/common/gki_common.h b/SN100x/src/gki/common/gki_common.h
index d814f07..701d23b 100644
--- a/SN100x/src/gki/common/gki_common.h
+++ b/SN100x/src/gki/common/gki_common.h
@@ -54,7 +54,7 @@
   uint8_t task_id;            /* task which allocated the buffer*/
   uint8_t status;             /* FREE, UNLINKED or QUEUED */
   uint8_t Type;
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#if defined(DYN_ALLOC) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
   uint16_t size;
 #endif
 } BUFFER_HDR_T;
diff --git a/SN100x/src/include/buildcfg.h b/SN100x/src/include/buildcfg.h
index 9c658be..7ba9b2c 100755
--- a/SN100x/src/include/buildcfg.h
+++ b/SN100x/src/include/buildcfg.h
@@ -70,8 +70,12 @@
 #if (NXP_EXTNS == TRUE)
 #define GKI_NUM_FIXED_BUF_POOLS 5
 #else
+#ifdef DYN_ALLOC
+#define GKI_NUM_FIXED_BUF_POOLS 0
+#else
 #define GKI_NUM_FIXED_BUF_POOLS 4
 #endif
+#endif
 
 #if (NXP_EXTNS == TRUE)
 void initializeGlobalAppDtaMode();