Merge "Prevent OOB read in rw_i93_sm_format" into qt-qpr1-dev am: 630da80b15

Change-Id: I4541cc1f7be7baaa20f4d662b633b6a9596389d1
diff --git a/OWNERS b/OWNERS
index 0aa310b..45e7662 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,4 @@
 zachoverflow@google.com
-rmojumder@google.com
 jackcwyu@google.com
 georgekgchang@google.com
+alisher@google.com
diff --git a/src/Android.bp b/src/Android.bp
index 60fb9b0..9d2ae92 100644
--- a/src/Android.bp
+++ b/src/Android.bp
@@ -10,7 +10,6 @@
         "liblog",
         "libdl",
         "libhardware",
-        "libmetricslogger",
         "libz",
         "libchrome",
         "libbase",
@@ -18,8 +17,6 @@
 
         // Treble configuration
         "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
         "libutils",
         "android.hardware.nfc@1.0",
         "android.hardware.nfc@1.1",
diff --git a/src/adaptation/NfcAdaptation.cc b/src/adaptation/NfcAdaptation.cc
index 9c70947..b0fc549 100644
--- a/src/adaptation/NfcAdaptation.cc
+++ b/src/adaptation/NfcAdaptation.cc
@@ -30,6 +30,10 @@
 #include "nfc_config.h"
 #include "nfc_int.h"
 
+using ::android::wp;
+using ::android::hardware::hidl_death_recipient;
+using ::android::hidl::base::V1_0::IBase;
+
 using android::OK;
 using android::sp;
 using android::status_t;
@@ -131,6 +135,27 @@
   tHAL_NFC_DATA_CBACK* mDataCallback;
 };
 
+class NfcHalDeathRecipient : public hidl_death_recipient {
+ public:
+  android::sp<android::hardware::nfc::V1_0::INfc> mNfcDeathHal;
+  NfcHalDeathRecipient(android::sp<android::hardware::nfc::V1_0::INfc>& mHal) {
+    mNfcDeathHal = mHal;
+  }
+
+  virtual void serviceDied(
+      uint64_t /* cookie */,
+      const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
+    ALOGE(
+        "NfcHalDeathRecipient::serviceDied - Nfc-Hal service died. Killing "
+        "NfcServie");
+    if (mNfcDeathHal) {
+      mNfcDeathHal->unlinkToDeath(this);
+    }
+    mNfcDeathHal = NULL;
+    abort();
+  }
+};
+
 /*******************************************************************************
 **
 ** Function:    NfcAdaptation::NfcAdaptation()
@@ -141,6 +166,7 @@
 **
 *******************************************************************************/
 NfcAdaptation::NfcAdaptation() {
+  mNfcHalDeathRecipient = new NfcHalDeathRecipient(mHal);
   memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
 }
 
@@ -499,6 +525,9 @@
   LOG(INFO) << StringPrintf("%s: INfc::getService() returned %p (%s)", func,
                             mHal.get(),
                             (mHal->isRemote() ? "remote" : "local"));
+  if (mHal) {
+    mHal->linkToDeath(mNfcHalDeathRecipient, 0);
+  }
 }
 
 /*******************************************************************************
diff --git a/src/adaptation/debug_nfcsnoop.cc b/src/adaptation/debug_nfcsnoop.cc
index 130e1f7..cd655cd 100644
--- a/src/adaptation/debug_nfcsnoop.cc
+++ b/src/adaptation/debug_nfcsnoop.cc
@@ -54,7 +54,7 @@
 
   while (ringbuffer_available(buffer) < (length + sizeof(nfcsnooz_header_t))) {
     ringbuffer_pop(buffer, (uint8_t*)&header, sizeof(nfcsnooz_header_t));
-    ringbuffer_delete(buffer, header.length - 1);
+    ringbuffer_delete(buffer, header.length);
   }
 
   // Insert data
diff --git a/src/adaptation/libmain.cc b/src/adaptation/libmain.cc
index 8ceb5ff..6e26347 100644
--- a/src/adaptation/libmain.cc
+++ b/src/adaptation/libmain.cc
@@ -89,7 +89,11 @@
   int fileStream = open(filename.c_str(), O_RDONLY);
   if (fileStream >= 0) {
     uint16_t checksum = 0;
-    read(fileStream, &checksum, sizeof(checksum));
+    size_t checkSumRdData = read(fileStream, &checksum, sizeof(checksum));
+    if (checkSumRdData <= 0) {
+      LOG(ERROR) << StringPrintf("%s: failed to read checksum, errno = 0x%02x",
+                                 __func__, errno);
+    }
     size_t actualReadData = read(fileStream, pBuffer, nbytes);
     close(fileStream);
     if (actualReadData > 0) {
@@ -174,11 +178,30 @@
 
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
 
-  remove(getFilenameForBlock(DH_NV_BLOCK).c_str());
-  remove(getFilenameForBlock(HC_F2_NV_BLOCK).c_str());
-  remove(getFilenameForBlock(HC_F3_NV_BLOCK).c_str());
-  remove(getFilenameForBlock(HC_F4_NV_BLOCK).c_str());
-  remove(getFilenameForBlock(HC_F5_NV_BLOCK).c_str());
+  if (remove(getFilenameForBlock(DH_NV_BLOCK).c_str())) {
+    LOG(ERROR) << StringPrintf(
+        "%s: fail to delete DH_NV_BLOCK file, errno = 0x%02X", __func__, errno);
+  }
+  if (remove(getFilenameForBlock(HC_F2_NV_BLOCK).c_str())) {
+    LOG(ERROR) << StringPrintf(
+        "%s: fail to delete HC_F2_NV_BLOCK file, errno = 0x%02X", __func__,
+        errno);
+  }
+  if (remove(getFilenameForBlock(HC_F3_NV_BLOCK).c_str())) {
+    LOG(ERROR) << StringPrintf(
+        "%s: fail to delete HC_F3_NV_BLOCK file, errno = 0x%02X", __func__,
+        errno);
+  }
+  if (remove(getFilenameForBlock(HC_F4_NV_BLOCK).c_str())) {
+    LOG(ERROR) << StringPrintf(
+        "%s: fail to delete HC_F4_NV_BLOCK file, errno = 0x%02X", __func__,
+        errno);
+  }
+  if (remove(getFilenameForBlock(HC_F5_NV_BLOCK).c_str())) {
+    LOG(ERROR) << StringPrintf(
+        "%s: fail to delete HC_F5_NV_BLOCK file, errno = 0x%02X", __func__,
+        errno);
+  }
 }
 
 /*******************************************************************************
diff --git a/src/adaptation/nfc_config.cc b/src/adaptation/nfc_config.cc
index 5891cc4..f406847 100644
--- a/src/adaptation/nfc_config.cc
+++ b/src/adaptation/nfc_config.cc
@@ -19,6 +19,7 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
+#include <android-base/properties.h>
 #include <android-base/strings.h>
 
 #include <config.h>
@@ -27,12 +28,9 @@
 using namespace ::android::base;
 
 namespace {
-
-std::string findConfigPath() {
+std::string searchConfigPath(std::string file_name) {
   const vector<string> search_path = {"/odm/etc/", "/vendor/etc/",
                                       "/product/etc/", "/etc/"};
-  const string file_name = "libnfc-nci.conf";
-
   for (string path : search_path) {
     path.append(file_name);
     struct stat file_stat;
@@ -41,6 +39,28 @@
   }
   return "";
 }
+// Configuration File Search sequence
+// 1. If prop_config_file_name is defined.(where prop_config_file_name is the
+//   value of the property persist.nfc_cfg.config_file_name)
+//   Search a file matches prop_config_file_name.
+// 2. If SKU is defined (where SKU is the value of the property
+//   ro.boot.product.hardware.sku)
+//   Search a file matches libnfc-nci-SKU.conf
+// 3. If none of 1,2 is defined, search a default file name "libnfc-nci.conf".
+std::string findConfigPath() {
+  string f_path = searchConfigPath(
+      android::base::GetProperty("persist.nfc_cfg.config_file_name", ""));
+  if (!f_path.empty()) return f_path;
+
+  // Search for libnfc-nci-SKU.conf
+  f_path = searchConfigPath(
+      "libnfc-nci-" +
+      android::base::GetProperty("ro.boot.product.hardware.sku", "") + ".conf");
+  if (!f_path.empty()) return f_path;
+
+  // load default file if the desired file not found.
+  return searchConfigPath("libnfc-nci.conf");
+}
 
 }  // namespace
 
diff --git a/src/gki/ulinux/gki_ulinux.cc b/src/gki/ulinux/gki_ulinux.cc
index fc3b5c6..093b58d 100644
--- a/src/gki/ulinux/gki_ulinux.cc
+++ b/src/gki/ulinux/gki_ulinux.cc
@@ -118,8 +118,6 @@
   pthread_mutexattr_t attr;
   tGKI_OS* p_os;
 
-  memset(&gki_cb, 0, sizeof(gki_cb));
-
   gki_buffer_init();
   gki_timers_init();
   gki_cb.com.OSTicks = (uint32_t)times(nullptr);
@@ -315,7 +313,7 @@
       }
 #endif
       DLOG_IF(INFO, nfc_debug_enabled)
-          << StringPrintf("task %s dead", gki_cb.com.OSTName[task_id]);
+          << StringPrintf("task %s dead", gki_cb.com.OSTName[task_id - 1]);
       GKI_exit_task(task_id - 1);
     }
   }
diff --git a/src/include/NfcAdaptation.h b/src/include/NfcAdaptation.h
index 7bcba00..df12a44 100644
--- a/src/include/NfcAdaptation.h
+++ b/src/include/NfcAdaptation.h
@@ -24,6 +24,8 @@
 
 #include <utils/RefBase.h>
 
+using ::android::sp;
+
 namespace android {
 namespace hardware {
 namespace nfc {
@@ -81,6 +83,8 @@
   ThreadMutex& mm;
 };
 
+class NfcHalDeathRecipient;
+
 class NfcAdaptation {
  public:
   virtual ~NfcAdaptation();
@@ -105,6 +109,7 @@
   static android::sp<android::hardware::nfc::V1_1::INfc> mHal_1_1;
   static android::sp<android::hardware::nfc::V1_2::INfc> mHal_1_2;
   static android::hardware::nfc::V1_1::INfcClientCallback* mCallback;
+  sp<NfcHalDeathRecipient> mNfcHalDeathRecipient;
   static tHAL_NFC_CBACK* mHalCallback;
   static tHAL_NFC_DATA_CBACK* mHalDataCallback;
   static ThreadCondVar mHalOpenCompletedEvent;
diff --git a/src/include/buildcfg.h b/src/include/buildcfg.h
index 86e7aec..b66695b 100644
--- a/src/include/buildcfg.h
+++ b/src/include/buildcfg.h
@@ -17,6 +17,7 @@
  ******************************************************************************/
 #ifndef __BUILDCFG_H
 #define __BUILDCFG_H
+#include <cutils/memory.h>
 #include <memory.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/src/include/nci_defs.h b/src/include/nci_defs.h
index 6745673..b43cb1c 100644
--- a/src/include/nci_defs.h
+++ b/src/include/nci_defs.h
@@ -616,7 +616,7 @@
 } tNCI_RF_LF_PARAMS;
 
 #ifndef NCI_MAX_ATS_LEN
-#define NCI_MAX_ATS_LEN 60
+#define NCI_MAX_ATS_LEN 64
 #endif
 #ifndef NCI_MAX_HIS_BYTES_LEN
 #define NCI_MAX_HIS_BYTES_LEN 50
diff --git a/src/include/nfc_config.h b/src/include/nfc_config.h
index 68e2d88..dda4260 100644
--- a/src/include/nfc_config.h
+++ b/src/include/nfc_config.h
@@ -27,6 +27,7 @@
 #define NAME_POLLING_TECH_MASK "POLLING_TECH_MASK"
 #define NAME_P2P_LISTEN_TECH_MASK "P2P_LISTEN_TECH_MASK"
 #define NAME_UICC_LISTEN_TECH_MASK "UICC_LISTEN_TECH_MASK"
+#define NAME_HOST_LISTEN_TECH_MASK "HOST_LISTEN_TECH_MASK"
 #define NAME_NFA_DM_CFG "NFA_DM_CFG"
 #define NAME_SCREEN_OFF_POWER_STATE "SCREEN_OFF_POWER_STATE"
 #define NAME_NFA_MAX_EE_SUPPORTED "NFA_MAX_EE_SUPPORTED"
diff --git a/src/nfa/dm/nfa_dm_act.cc b/src/nfa/dm/nfa_dm_act.cc
index 5476749..aa494fb 100644
--- a/src/nfa/dm/nfa_dm_act.cc
+++ b/src/nfa/dm/nfa_dm_act.cc
@@ -153,7 +153,8 @@
 
     /* LF_T3T_PMM value is added to LF_T3T_IDENTIFIERS_X in NCI2.0. */
     for (xx = 0; xx < NFA_CE_LISTEN_INFO_MAX; xx++) {
-      for (uint8_t yy = 10; yy < NCI_PARAM_LEN_LF_T3T_ID(NCI_VERSION_2_0); yy++)
+      for (uint8_t yy = 10; yy < NCI_PARAM_LEN_LF_T3T_ID(NFC_GetNCIVersion());
+           yy++)
         nfa_dm_cb.params.lf_t3t_id[xx][yy] = 0xFF;
     }
   } else {
diff --git a/src/nfa/dm/nfa_dm_api.cc b/src/nfa/dm/nfa_dm_api.cc
index e8334dc..20b1730 100644
--- a/src/nfa/dm/nfa_dm_api.cc
+++ b/src/nfa/dm/nfa_dm_api.cc
@@ -1278,14 +1278,9 @@
   if (p_msg != nullptr) {
     p_msg->hdr.event = NFA_DM_API_SEND_RAW_VS_EVT;
     p_msg->p_cback = p_cback;
-    if (cmd_params_len && p_cmd_params) {
-      p_msg->cmd_params_len = cmd_params_len;
-      p_msg->p_cmd_params = (uint8_t*)(p_msg + 1);
-      memcpy(p_msg->p_cmd_params, p_cmd_params, cmd_params_len);
-    } else {
-      p_msg->cmd_params_len = 0;
-      p_msg->p_cmd_params = nullptr;
-    }
+    p_msg->cmd_params_len = cmd_params_len;
+    p_msg->p_cmd_params = (uint8_t*)(p_msg + 1);
+    memcpy(p_msg->p_cmd_params, p_cmd_params, cmd_params_len);
 
     nfa_sys_sendmsg(p_msg);
 
diff --git a/src/nfa/dm/nfa_dm_discover.cc b/src/nfa/dm/nfa_dm_discover.cc
index 8e5cd5c..0925434 100644
--- a/src/nfa/dm/nfa_dm_discover.cc
+++ b/src/nfa/dm/nfa_dm_discover.cc
@@ -1573,6 +1573,7 @@
     deact.status = NFC_STATUS_OK;
     deact.type = NFC_DEACTIVATE_TYPE_DISCOVERY;
     deact.is_ntf = true;
+    deact.reason = NFC_DEACTIVATE_REASON_DH_REQ;
     tNFC_DISCOVER nfc_discover;
     nfc_discover.deactivate = deact;
     nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF, &nfc_discover);
@@ -2164,7 +2165,7 @@
       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
         /* it's race condition. received deactivate NTF before receiving RSP */
 
-        tNFC_DEACTIVATE_DEVT deact;
+        tNFC_DEACTIVATE_DEVT deact = tNFC_DEACTIVATE_DEVT();
         deact.status = NFC_STATUS_OK;
         deact.type = NFC_DEACTIVATE_TYPE_IDLE;
         deact.is_ntf = true;
@@ -2251,23 +2252,17 @@
       } else if (p_data->nfc_discover.deactivate.type ==
                  NFC_DEACTIVATE_TYPE_DISCOVERY) {
         nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
-        /* if deactivation type is discovery and comes after 3 tentatives of
-         * unsuccessful deactivation to sleep then reset the counter and  notify
+        /* If deactivation type is discovery, reset the counter and notify
          * upper layer.
-         *
          */
-        if (nfa_dm_cb.deactivate_cmd_retry_count == 3) {
-          nfa_dm_cb.deactivate_cmd_retry_count = 0;
-          DLOG_IF(INFO, nfc_debug_enabled)
-              << __func__
-              << StringPrintf(
-                     " NFA_DM_RF_DEACTIVATE_NTF to discovery after 3 attempt "
-                     "of deactivate (sleep)");
-          if (p_data->nfc_discover.deactivate.reason ==
-              NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
-            nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
-                                            &(p_data->nfc_discover));
-          }
+        nfa_dm_cb.deactivate_cmd_retry_count = 0;
+        DLOG_IF(INFO, nfc_debug_enabled)
+            << __func__
+            << StringPrintf("NFA_DM_RF_DEACTIVATE_NTF to discovery");
+        if (p_data->nfc_discover.deactivate.reason ==
+            NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
+          nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
+                                          &(p_data->nfc_discover));
         }
         if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
           /* stop discovery */
@@ -2308,7 +2303,7 @@
 *******************************************************************************/
 static void nfa_dm_disc_sm_listen_active(tNFA_DM_RF_DISC_SM_EVENT event,
                                          tNFA_DM_RF_DISC_DATA* p_data) {
-  tNFC_DEACTIVATE_DEVT deact;
+  tNFC_DEACTIVATE_DEVT deact = tNFC_DEACTIVATE_DEVT();
 
   switch (event) {
     case NFA_DM_RF_DEACTIVATE_CMD:
@@ -2467,7 +2462,6 @@
   switch (event) {
     case NFA_DM_RF_INTF_ACTIVATED_NTF:
       nfa_dm_disc_new_state(NFA_DM_RFST_LP_ACTIVE);
-      nfa_dm_disc_notify_activation(&(p_data->nfc_discover));
       if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
           NFA_STATUS_FAILED) {
         DLOG_IF(INFO, nfc_debug_enabled)
diff --git a/src/nfa/ee/nfa_ee_act.cc b/src/nfa/ee/nfa_ee_act.cc
index 02548de..ccc1e50 100644
--- a/src/nfa/ee/nfa_ee_act.cc
+++ b/src/nfa/ee/nfa_ee_act.cc
@@ -122,7 +122,8 @@
                              uint8_t* p) {
   int len = aid_len;
   int xx, yy = 0;
-  char buff[100];
+  const uint8_t MAX_BUFF_SIZE = 100;
+  char buff[MAX_BUFF_SIZE];
 
   buff[0] = 0;
   if (aid_len > NFA_MAX_AID_LEN) {
@@ -131,7 +132,7 @@
     len = NFA_MAX_AID_LEN;
   }
   for (xx = 0; xx < len; xx++) {
-    yy += sprintf(&buff[yy], "%02x ", *p);
+    yy += snprintf(&buff[yy], MAX_BUFF_SIZE - yy, "%02x ", *p);
     p++;
   }
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
@@ -1487,7 +1488,11 @@
     evt_data.status = NFA_STATUS_INVALID_PARAM;
   }
   /* report the status of this operation */
-  nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_REMOVE_SYSCODE_EVT, &evt_data);
+  if (p_cb) {
+    nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_REMOVE_SYSCODE_EVT, &evt_data);
+  } else {
+    nfa_ee_report_event(NULL, NFA_EE_REMOVE_SYSCODE_EVT, &evt_data);
+  }
 }
 
 /*******************************************************************************
@@ -2072,8 +2077,7 @@
 
   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
     if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) ||
-        (p_cb->ee_status != NFA_EE_STATUS_ACTIVE) ||
-        ((p_cb->ecb_flags & NFA_EE_ECB_FLAGS_DISC_REQ) == 0)) {
+        (p_cb->ee_status != NFA_EE_STATUS_ACTIVE) ) {
       continue;
     }
     p_info->ee_handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
diff --git a/src/nfa/ee/nfa_ee_main.cc b/src/nfa/ee/nfa_ee_main.cc
index 30a44a7..69a70d0 100644
--- a/src/nfa/ee/nfa_ee_main.cc
+++ b/src/nfa/ee/nfa_ee_main.cc
@@ -323,7 +323,7 @@
 *******************************************************************************/
 void nfa_ee_proc_evt(tNFC_RESPONSE_EVT event, void* p_data) {
   tNFA_EE_INT_EVT int_event = 0;
-  tNFA_EE_NCI_WAIT_RSP cbk;
+  tNFA_EE_NCI_WAIT_RSP cbk = tNFA_EE_NCI_WAIT_RSP();
 
   switch (event) {
     case NFC_NFCEE_DISCOVER_REVT: /* 4  NFCEE Discover response */
diff --git a/src/nfa/hci/nfa_hci_act.cc b/src/nfa/hci/nfa_hci_act.cc
index fbc4fbf..70c519c 100644
--- a/src/nfa/hci/nfa_hci_act.cc
+++ b/src/nfa/hci/nfa_hci_act.cc
@@ -262,7 +262,7 @@
       if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0) {
         memset(&nfa_hci_cb.cfg.reg_app_names[xx][0], 0,
                sizeof(nfa_hci_cb.cfg.reg_app_names[xx]));
-        strncpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name,
+        strlcpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name,
                 NFA_MAX_HCI_APP_NAME_LEN);
         nfa_hci_cb.nv_write_needed = true;
         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
diff --git a/src/nfa/hci/nfa_hci_api.cc b/src/nfa/hci/nfa_hci_api.cc
index 03c2bb2..252cae2 100644
--- a/src/nfa/hci/nfa_hci_api.cc
+++ b/src/nfa/hci/nfa_hci_api.cc
@@ -81,7 +81,7 @@
 
     /* Save application name and callback */
     memset(p_msg->app_name, 0, sizeof(p_msg->app_name));
-    strncpy(p_msg->app_name, p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+    strlcpy(p_msg->app_name, p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
     p_msg->p_cback = p_cback;
     p_msg->b_send_conn_evts = b_send_conn_evts;
 
@@ -186,7 +186,7 @@
     p_msg->hdr.event = NFA_HCI_API_DEREGISTER_APP_EVT;
 
     memset(p_msg->app_name, 0, sizeof(p_msg->app_name));
-    strncpy(p_msg->app_name, p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+    strlcpy(p_msg->app_name, p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
 
     nfa_sys_sendmsg(p_msg);
     return (NFA_STATUS_OK);
diff --git a/src/nfa/hci/nfa_hci_main.cc b/src/nfa/hci/nfa_hci_main.cc
index b4c43be..2ee1e03 100644
--- a/src/nfa/hci/nfa_hci_main.cc
+++ b/src/nfa/hci/nfa_hci_main.cc
@@ -699,7 +699,8 @@
   uint8_t chaining_bit;
   uint8_t pipe;
   uint16_t pkt_len;
-  char buff[100];
+  const uint8_t MAX_BUFF_SIZE = 100;
+  char buff[MAX_BUFF_SIZE];
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
       "%s State: %u  Cmd: %u", __func__, nfa_hci_cb.hci_state, event);
   if (event == NFC_CONN_CREATE_CEVT) {
@@ -804,8 +805,8 @@
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
       "nfa_hci_conn_cback Recvd data pipe:%d  %s  chain:%d  assmbl:%d  len:%d",
       (uint8_t)pipe,
-      nfa_hciu_get_type_inst_names(pipe, nfa_hci_cb.type, nfa_hci_cb.inst,
-                                   buff),
+      nfa_hciu_get_type_inst_names(pipe, nfa_hci_cb.type, nfa_hci_cb.inst, buff,
+                                   MAX_BUFF_SIZE),
       (uint8_t)chaining_bit, (uint8_t)nfa_hci_cb.assembling, p_pkt->len);
 
   /* If still reassembling fragments, just return */
diff --git a/src/nfa/hci/nfa_hci_utils.cc b/src/nfa/hci/nfa_hci_utils.cc
index 1751af3..6a8db5d 100644
--- a/src/nfa/hci/nfa_hci_utils.cc
+++ b/src/nfa/hci/nfa_hci_utils.cc
@@ -313,11 +313,14 @@
     android_errorWriteLog(0x534e4554, "124521372");
     return NFA_STATUS_NO_BUFFERS;
   }
-  char buff[100];
+  const uint8_t MAX_BUFF_SIZE = 100;
+  char buff[MAX_BUFF_SIZE];
 
-  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
-      "nfa_hciu_send_msg pipe_id:%d   %s  len:%d", pipe_id,
-      nfa_hciu_get_type_inst_names(pipe_id, type, instruction, buff), msg_len);
+  DLOG_IF(INFO, nfc_debug_enabled)
+      << StringPrintf("nfa_hciu_send_msg pipe_id:%d   %s  len:%d", pipe_id,
+                      nfa_hciu_get_type_inst_names(pipe_id, type, instruction,
+                                                   buff, MAX_BUFF_SIZE),
+                      msg_len);
 
   if (instruction == NFA_HCI_ANY_GET_PARAMETER)
     nfa_hci_cb.param_in_use = *p_msg;
@@ -1321,27 +1324,30 @@
 **
 *******************************************************************************/
 char* nfa_hciu_get_type_inst_names(uint8_t pipe, uint8_t type, uint8_t inst,
-                                   char* p_buff) {
+                                   char* p_buff, const uint8_t max_buff_size) {
   int xx;
 
-  xx = sprintf(p_buff, "Type: %s [0x%02x] ", nfa_hciu_type_2_str(type).c_str(),
-               type);
+  xx = snprintf(p_buff, max_buff_size, "Type: %s [0x%02x] ",
+                nfa_hciu_type_2_str(type).c_str(), type);
 
   switch (type) {
     case NFA_HCI_COMMAND_TYPE:
-      sprintf(&p_buff[xx], "Inst: %s [0x%02x] ",
-              nfa_hciu_instr_2_str(inst).c_str(), inst);
+      snprintf(&p_buff[xx], max_buff_size - xx, "Inst: %s [0x%02x] ",
+               nfa_hciu_instr_2_str(inst).c_str(), inst);
+
       break;
     case NFA_HCI_EVENT_TYPE:
-      sprintf(&p_buff[xx], "Evt: %s [0x%02x] ",
-              nfa_hciu_evt_2_str(pipe, inst).c_str(), inst);
+      snprintf(&p_buff[xx], max_buff_size - xx, "Evt: %s [0x%02x] ",
+               nfa_hciu_evt_2_str(pipe, inst).c_str(), inst);
+
       break;
     case NFA_HCI_RESPONSE_TYPE:
-      sprintf(&p_buff[xx], "Resp: %s [0x%02x] ",
-              nfa_hciu_get_response_name(inst).c_str(), inst);
+      snprintf(&p_buff[xx], max_buff_size - xx, "Resp: %s [0x%02x] ",
+               nfa_hciu_get_response_name(inst).c_str(), inst);
+
       break;
     default:
-      sprintf(&p_buff[xx], "Inst: %u ", inst);
+      snprintf(&p_buff[xx], max_buff_size - xx, "Inst: %u ", inst);
       break;
   }
   return p_buff;
diff --git a/src/nfa/include/nfa_hci_int.h b/src/nfa/include/nfa_hci_int.h
index 456c279..c9c9550 100644
--- a/src/nfa/include/nfa_hci_int.h
+++ b/src/nfa/include/nfa_hci_int.h
@@ -523,7 +523,8 @@
 extern std::string nfa_hciu_get_event_name(uint16_t event);
 extern std::string nfa_hciu_get_state_name(uint8_t state);
 extern char* nfa_hciu_get_type_inst_names(uint8_t pipe, uint8_t type,
-                                          uint8_t inst, char* p_buff);
+                                          uint8_t inst, char* p_buff,
+                                          const uint8_t max_buff_size);
 extern std::string nfa_hciu_evt_2_str(uint8_t pipe_id, uint8_t evt);
 
 #endif /* NFA_HCI_INT_H */
diff --git a/src/nfa/p2p/nfa_p2p_act.cc b/src/nfa/p2p/nfa_p2p_act.cc
index 36726e7..3fca288 100644
--- a/src/nfa/p2p/nfa_p2p_act.cc
+++ b/src/nfa/p2p/nfa_p2p_act.cc
@@ -623,7 +623,7 @@
   if (server_sap == LLCP_INVALID_SAP) {
     evt_data.reg_server.server_handle = NFA_HANDLE_INVALID;
     evt_data.reg_server.server_sap = NFA_P2P_INVALID_SAP;
-    strncpy(evt_data.reg_server.service_name,
+    strlcpy(evt_data.reg_server.service_name,
             p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
     evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
 
@@ -644,7 +644,7 @@
 
   evt_data.reg_server.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
   evt_data.reg_server.server_sap = server_sap;
-  strncpy(evt_data.reg_server.service_name, p_msg->api_reg_server.service_name,
+  strlcpy(evt_data.reg_server.service_name, p_msg->api_reg_server.service_name,
           LLCP_MAX_SN_LEN);
   evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
 
@@ -903,7 +903,7 @@
   }
   /* NFA_P2pConnectByName () */
   else {
-    strncpy(conn_params.sn, p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
+    strlcpy(conn_params.sn, p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
     conn_params.sn[LLCP_MAX_SN_LEN] = 0;
 
     status = LLCP_ConnectReq(local_sap, LLCP_SAP_SDP, &conn_params);
diff --git a/src/nfa/p2p/nfa_p2p_api.cc b/src/nfa/p2p/nfa_p2p_api.cc
index 2e13dce..d27396c 100644
--- a/src/nfa/p2p/nfa_p2p_api.cc
+++ b/src/nfa/p2p/nfa_p2p_api.cc
@@ -89,7 +89,7 @@
     p_msg->server_sap = server_sap;
     p_msg->link_type = link_type;
 
-    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
+    strlcpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
     p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
 
     p_msg->p_cback = p_cback;
@@ -385,7 +385,7 @@
                   sizeof(tNFA_P2P_API_CONNECT))) != nullptr) {
     p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
 
-    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
+    strlcpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
     p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
 
     p_msg->dsap = LLCP_INVALID_SAP;
@@ -924,7 +924,7 @@
 
     p_msg->handle = handle;
 
-    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
+    strlcpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
     p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
 
     nfa_sys_sendmsg(p_msg);
diff --git a/src/nfc/include/nfc_api.h b/src/nfc/include/nfc_api.h
index 3a0b673..84a1426 100644
--- a/src/nfc/include/nfc_api.h
+++ b/src/nfc/include/nfc_api.h
@@ -435,6 +435,7 @@
  *  Deactivation Reasons
  **********************************************/
 #define NFC_DEACTIVATE_REASON_DH_REQ_FAILED NCI_DEACTIVATE_REASON_DH_REQ_FAILED
+#define NFC_DEACTIVATE_REASON_DH_REQ NCI_DEACTIVATE_REASON_DH_REQ
 typedef uint8_t tNFC_DEACT_REASON;
 
 /* the data type associated with NFC_RF_FIELD_REVT */
diff --git a/src/nfc/include/rw_int.h b/src/nfc/include/rw_int.h
index 61f0820..f4027a5 100644
--- a/src/nfc/include/rw_int.h
+++ b/src/nfc/include/rw_int.h
@@ -693,6 +693,13 @@
   RW_I93_STM_M24LR64E_R,             /* STM M24LR64E-R                   */
   RW_I93_STM_ST25DV04K,              /* STM ST25DV04K                    */
   RW_I93_STM_ST25DVHIK,              /* STM ST25DV 16K OR 64K            */
+  RW_I93_ONS_N36RW02,                /* ONS N36RW02                      */
+  RW_I93_ONS_N24RF04,                /* ONS N24RF04                      */
+  RW_I93_ONS_N24RF04E,               /* ONS N24RF04E                     */
+  RW_I93_ONS_N24RF16,                /* ONS N24RF16                      */
+  RW_I93_ONS_N24RF16E,               /* ONS N24RF16E                     */
+  RW_I93_ONS_N24RF64,                /* ONS N24RF64                      */
+  RW_I93_ONS_N24RF64E,               /* ONS N24RF64E                     */
   RW_I93_UNKNOWN_PRODUCT             /* Unknwon product version          */
 };
 
diff --git a/src/nfc/include/tags_defs.h b/src/nfc/include/tags_defs.h
index 23a8f03..4177c78 100644
--- a/src/nfc/include/tags_defs.h
+++ b/src/nfc/include/tags_defs.h
@@ -577,6 +577,7 @@
 #define I93_ICODE_CC_IPREAD_MASK 0x02
 /* More than 2040 bytes are supported in CC[3] */
 #define I93_STM_CC_OVERFLOW_MASK 0x04
+#define I93_ONS_CC_OVERFLOW_MASK 0x04
 
 /* ICODE TLV type */
 #define I93_ICODE_TLV_TYPE_NULL 0x00 /* NULL TLV         */
@@ -591,6 +592,7 @@
 #define I93_UID_IC_MFG_CODE_STM 0x02
 #define I93_UID_IC_MFG_CODE_NXP 0x04
 #define I93_UID_IC_MFG_CODE_TI 0x07
+#define I93_UID_IC_MFG_CODE_ONS 0x67
 
 /* NXP, UID Coding of ICODE type (UID Bit 48-41) */
 /* ICODE SLI, SLIX     */
@@ -656,7 +658,26 @@
  */
 #define I93_IC_REF_STM_ST25DVHIK 0x26
 
+/* ONS, product version (IC manufacturer code) */
+/* IC Reference for N36RW02:  00011010(b), blockSize: 4, numberBlocks: 0x40 */
+#define I93_IC_REF_ONS_N36RW02  0x1A
+/* IC Reference for N24RF04:  00101010(b), blockSize: 4, numberBlocks: 0x80 */
+#define I93_IC_REF_ONS_N24RF04  0x2A
+/* IC Reference for N24RF04E: 00101110(b), blockSize: 4, numberBlocks: 0x80 */
+#define I93_IC_REF_ONS_N24RF04E 0x2E
+/* IC Reference for N24RF16:  01001010(b), blockSize: 4, numberBlocks: 0x200 */
+#define I93_IC_REF_ONS_N24RF16  0x4A
+/* IC Reference for N24RF16E: 01001110(b), blockSize: 4, numberBlocks: 0x200 */
+#define I93_IC_REF_ONS_N24RF16E 0x4E
+/* IC Reference for N24RF64:  01101010(b), blockSize: 4, numberBlocks: 0x800 */
+#define I93_IC_REF_ONS_N24RF64  0x6A
+/* IC Reference for N24RF64E: 01101110(b), blockSize: 4, numberBlocks: 0x800 */
+#define I93_IC_REF_ONS_N24RF64E 0x6E
+
 #define I93_STM_BLOCKS_PER_SECTOR 32
 #define I93_STM_MAX_BLOCKS_PER_READ 32
 
-#endif /* TAGS_DEFS_H */
+#define I93_ONS_BLOCKS_PER_SECTOR 32
+#define I93_ONS_MAX_BLOCKS_PER_READ 32
+
+#endif /* TAGS_DEFS_H */ 
\ No newline at end of file
diff --git a/src/nfc/llcp/llcp_api.cc b/src/nfc/llcp/llcp_api.cc
index 93dbc6a..0ea8c8c 100644
--- a/src/nfc/llcp/llcp_api.cc
+++ b/src/nfc/llcp/llcp_api.cc
@@ -438,7 +438,7 @@
       return LLCP_INVALID_SAP;
     }
 
-    strncpy(p_app_cb->p_service_name, p_service_name.c_str(), length + 1);
+    strlcpy(p_app_cb->p_service_name, p_service_name.c_str(), length + 1);
     p_app_cb->p_service_name[length] = 0;
   } else
     p_app_cb->p_service_name = nullptr;
diff --git a/src/nfc/nci/nci_hrcv.cc b/src/nfc/nci/nci_hrcv.cc
index fdef020..6494e36 100644
--- a/src/nfc/nci/nci_hrcv.cc
+++ b/src/nfc/nci/nci_hrcv.cc
@@ -428,9 +428,7 @@
       DLOG_IF(INFO, nfc_debug_enabled)
           << StringPrintf("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
       if (p_tlv->len > NFC_MAX_EE_INFO) p_tlv->len = NFC_MAX_EE_INFO;
-      p = pp;
       STREAM_TO_ARRAY(p_tlv->info, pp, p_tlv->len);
-      pp = p += yy;
     }
   } else if (op_code == NCI_MSG_NFCEE_MODE_SET) {
     nfc_response.mode_set.status = *pp;
diff --git a/src/nfc/nfc/nfc_ncif.cc b/src/nfc/nfc/nfc_ncif.cc
index f14e6f2..80c964d 100644
--- a/src/nfc/nfc/nfc_ncif.cc
+++ b/src/nfc/nfc/nfc_ncif.cc
@@ -26,7 +26,6 @@
 #include <android-base/stringprintf.h>
 #include <base/logging.h>
 #include <log/log.h>
-#include <metricslogger/metrics_logger.h>
 
 #include "nfc_target.h"
 
@@ -181,7 +180,7 @@
   p_data = (NFC_HDR*)GKI_getfirst(&p_cb->tx_q);
 
   /* post data fragment to NCIT task as credits are available */
-  while (p_data && (p_data->len >= 0) && (p_cb->num_buff > 0)) {
+  while (p_data && (p_cb->num_buff > 0)) {
     if (p_data->len <= buffer_size) {
       pbf = 0; /* last fragment */
       ulen = (uint8_t)(p_data->len);
@@ -557,7 +556,6 @@
 void nfc_ncif_event_status(tNFC_RESPONSE_EVT event, uint8_t status) {
   tNFC_RESPONSE evt_data;
   if (event == NFC_NFCC_TIMEOUT_REVT && status == NFC_STATUS_HW_TIMEOUT) {
-    android::metricslogger::LogCounter("nfc_hw_timeout_error", 1);
     uint32_t cmd_hdr = (nfc_cb.last_hdr[0] << 8) | nfc_cb.last_hdr[1];
     android::util::stats_write(android::util::NFC_ERROR_OCCURRED,
                                (int32_t)NCI_TIMEOUT, (int32_t)cmd_hdr,
@@ -588,23 +586,6 @@
   }
   android::util::stats_write(android::util::NFC_ERROR_OCCURRED,
                              (int32_t)ERROR_NTF, (int32_t)0, (int32_t)status);
-
-  if (status == NFC_STATUS_TIMEOUT)
-    android::metricslogger::LogCounter("nfc_rf_timeout_error", 1);
-  else if (status == NFC_STATUS_EE_TIMEOUT)
-    android::metricslogger::LogCounter("nfc_ee_timeout_error", 1);
-  else if (status == NFC_STATUS_ACTIVATION_FAILED)
-    android::metricslogger::LogCounter("nfc_rf_activation_failed", 1);
-  else if (status == NFC_STATUS_EE_INTF_ACTIVE_FAIL)
-    android::metricslogger::LogCounter("nfc_ee_activation_failed", 1);
-  else if (status == NFC_STATUS_RF_TRANSMISSION_ERR)
-    android::metricslogger::LogCounter("nfc_rf_transmission_error", 1);
-  else if (status == NFC_STATUS_EE_TRANSMISSION_ERR)
-    android::metricslogger::LogCounter("nfc_ee_transmission_error", 1);
-  else if (status == NFC_STATUS_RF_PROTOCOL_ERR)
-    android::metricslogger::LogCounter("nfc_rf_protocol_error", 1);
-  else if (status == NFC_STATUS_EE_PROTOCOL_ERR)
-    android::metricslogger::LogCounter("nfc_ee_protocol_error", 1);
 }
 
 /*******************************************************************************
diff --git a/src/nfc/nfc/nfc_utils.cc b/src/nfc/nfc/nfc_utils.cc
index 7c2103a..855908b 100644
--- a/src/nfc/nfc/nfc_utils.cc
+++ b/src/nfc/nfc/nfc_utils.cc
@@ -177,7 +177,7 @@
 extern void nfc_reset_all_conn_cbs(void) {
   int xx;
   tNFC_CONN_CB* p_conn_cb = &nfc_cb.conn_cb[0];
-  tNFC_DEACTIVATE_DEVT deact;
+  tNFC_DEACTIVATE_DEVT deact = tNFC_DEACTIVATE_DEVT();
 
   deact.status = NFC_STATUS_NOT_INITIALIZED;
   deact.type = NFC_DEACTIVATE_TYPE_IDLE;
diff --git a/src/nfc/tags/ce_t4t.cc b/src/nfc/tags/ce_t4t.cc
index 691ac05..5f80587 100644
--- a/src/nfc/tags/ce_t4t.cc
+++ b/src/nfc/tags/ce_t4t.cc
@@ -562,6 +562,10 @@
   }
 
   p_c_apdu = (NFC_HDR*)p_data->data.p_data;
+  if (!p_c_apdu) {
+    LOG(ERROR) << StringPrintf("Invalid p_c_apdu");
+    return;
+  }
 
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("conn_id = 0x%02X", conn_id);
 
@@ -571,7 +575,7 @@
     LOG(ERROR) << StringPrintf("Wrong length in ce_t4t_data_cback");
     android_errorWriteLog(0x534e4554, "115635871");
     ce_t4t_send_status(T4T_RSP_WRONG_LENGTH);
-    if (p_c_apdu) GKI_freebuf(p_c_apdu);
+    GKI_freebuf(p_c_apdu);
     return;
   }
 
@@ -605,7 +609,7 @@
           LOG(ERROR) << StringPrintf("Wrong length in select app cmd");
           android_errorWriteLog(0x534e4554, "115635871");
           ce_t4t_send_status(T4T_RSP_NOT_FOUND);
-          if (p_c_apdu) GKI_freebuf(p_c_apdu);
+          GKI_freebuf(p_c_apdu);
           return;
         }
       }
diff --git a/src/nfc/tags/rw_i93.cc b/src/nfc/tags/rw_i93.cc
index 33d5229..996ec41 100644
--- a/src/nfc/tags/rw_i93.cc
+++ b/src/nfc/tags/rw_i93.cc
@@ -178,6 +178,34 @@
           break;
       }
     }
+  } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_ONS) &&
+             (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
+      switch (p_i93->ic_reference) {
+        case I93_IC_REF_ONS_N36RW02:
+          p_i93->product_version = RW_I93_ONS_N36RW02;
+          break;
+        case I93_IC_REF_ONS_N24RF04:
+          p_i93->product_version = RW_I93_ONS_N24RF04;
+          break;
+        case I93_IC_REF_ONS_N24RF04E:
+          p_i93->product_version = RW_I93_ONS_N24RF04E;
+          break;
+        case RW_I93_ONS_N24RF16:
+          p_i93->product_version = RW_I93_ONS_N24RF16;
+          break;
+        case RW_I93_ONS_N24RF16E:
+          p_i93->product_version = RW_I93_ONS_N24RF16E;
+          break;
+        case RW_I93_ONS_N24RF64:
+          p_i93->product_version = RW_I93_ONS_N24RF64;
+          break;
+        case RW_I93_ONS_N24RF64E:
+          p_i93->product_version = RW_I93_ONS_N24RF64E;
+          break;
+        default:
+          p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+        break;
+      }
   } else {
     p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
   }
@@ -275,8 +303,8 @@
     rw_i93_get_product_version(p_uid);
 
     if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
-      if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
-        /* STM supports more than 2040 bytes */
+      if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) || (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS)){
+        /* STM & ONS supports more than 2040 bytes */
         p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
       }
     }
@@ -409,6 +437,36 @@
             }
           }
         }
+      } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS) {
+        /*
+        **  N36RW02:  00011010(b), blockSize: 4, numberBlocks: 0x40
+        **  N24RF04:  00101110(b), blockSize: 4, numberBlocks: 0x80
+        **  N24RF04E: 00101010(b), blockSize: 4, numberBlocks: 0x80
+        **  N24RF16:  01001010(b), blockSize: 4, numberBlocks: 0x200
+        **  N24RF16E: 01001110(b), blockSize: 4, numberBlocks: 0x200
+        **  N24RF64:  01101010(b), blockSize: 4, numberBlocks: 0x800
+        **  N24RF64E: 01101110(b), blockSize: 4, numberBlocks: 0x800
+        */
+          p_i93->block_size = 4;
+          switch (p_i93->product_version){
+            case RW_I93_ONS_N36RW02:
+                 p_i93->num_block = 0x40;
+                 break;
+            case RW_I93_ONS_N24RF04:
+            case RW_I93_ONS_N24RF04E:
+                 p_i93->num_block = 0x80;
+                 break;
+            case RW_I93_ONS_N24RF16:
+            case RW_I93_ONS_N24RF16E:
+                 p_i93->num_block = 0x200;
+                 break;
+            case RW_I93_ONS_N24RF64:
+            case RW_I93_ONS_N24RF64E:
+                 p_i93->num_block = 0x800;
+                 break;
+            default:
+                 return false;
+          }
       }
     }
   }
@@ -431,7 +489,7 @@
 
   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
 
-  if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) &&
+  if (((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) || (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS)) &&
       (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
       (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
       (rw_i93_send_cmd_get_sys_info(nullptr, I93_FLAG_PROT_EXT_YES) ==
@@ -477,7 +535,7 @@
   if (flags & I93_FLAG_ERROR_DETECTED) {
     if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
       /* getting system info with protocol extension flag */
-      /* This STM tag supports more than 2040 bytes */
+      /* This STM & ONS tag supports more than 2040 bytes */
       p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
       p_i93->state = RW_I93_STATE_BUSY;
     } else if (length) {
@@ -957,7 +1015,7 @@
   ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
 
   if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
-    UINT16_TO_STREAM(p, block_number); /* Block number */
+    UINT8_TO_STREAM(p, block_number); /* Block number */
     p_cmd->len++;
   } else {
     UINT8_TO_STREAM(p, block_number); /* Block number */
@@ -1603,6 +1661,30 @@
       }
     }
 
+    if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS) {
+      /* N24RF04, N24RF04E, N24RF16, N24RF16E, N24RF64, N24RF64E requires
+      ** - The max number of blocks is 32 and they are all located in the
+      **   same sector.
+      ** - The sector is 32 blocks of 4 bytes.
+      */
+      if ((p_i93->product_version == RW_I93_ONS_N36RW02) ||
+          (p_i93->product_version == RW_I93_ONS_N24RF04) ||
+          (p_i93->product_version == RW_I93_ONS_N24RF04E)||
+          (p_i93->product_version == RW_I93_ONS_N24RF16) ||
+          (p_i93->product_version == RW_I93_ONS_N24RF16E)||
+          (p_i93->product_version == RW_I93_ONS_N24RF64) ||
+          (p_i93->product_version == RW_I93_ONS_N24RF64E)) {
+        if (num_block > I93_ONS_MAX_BLOCKS_PER_READ)
+          num_block = I93_ONS_MAX_BLOCKS_PER_READ;
+
+        if ((first_block / I93_ONS_BLOCKS_PER_SECTOR) !=
+            ((first_block + num_block - 1) / I93_ONS_BLOCKS_PER_SECTOR)) {
+          num_block = I93_ONS_BLOCKS_PER_SECTOR -
+                      (first_block % I93_ONS_BLOCKS_PER_SECTOR);
+        }
+      }
+    }
+
     return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
   } else {
     return rw_i93_send_cmd_read_single_block(first_block, false);
@@ -1681,7 +1763,7 @@
   if (flags & I93_FLAG_ERROR_DETECTED) {
     if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
       /* getting system info with protocol extension flag */
-      /* This STM tag supports more than 2040 bytes */
+      /* This STM & ONS tag supports more than 2040 bytes */
       p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
     } else {
       DLOG_IF(INFO, nfc_debug_enabled)
@@ -1766,11 +1848,11 @@
       **         without any security)
       **       : Bit 1-0:Write access condition (00b: write access granted
       **         without any security)
-      ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to
-      **         0xFF if more than 2040bytes]
-      ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
+      ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, ONS set
+      **         to 0xFF if more than 2040bytes]
+      ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM, ONS]
       **       : Bit 1:Inventory page read is supported [NXP]
-      **       : Bit 2:More than 2040 bytes are supported [STM]
+      **       : Bit 2:More than 2040 bytes are supported [STM, ONS]
       */
 
       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
@@ -2463,7 +2545,7 @@
       /* ignore error */
     } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
       /* getting system info with protocol extension flag */
-      /* This STM tag supports more than 2040 bytes */
+      /* This STM & ONS tag supports more than 2040 bytes */
       p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
       return;
     } else {
@@ -2709,7 +2791,7 @@
                   RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
         *(p++) = 0;
       } else {
-        /* STM except LRIS2K, Broadcom supports read multi block command */
+        /* STM except LRIS2K, ONS, Broadcom supports read multi block command */
 
         /* if memory size is more than 2040 bytes (which is not LRIS2K) */
         if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
@@ -4171,8 +4253,22 @@
       return "ST25DV04";
     case RW_I93_STM_ST25DVHIK:
       return "ST25DV";
+    case RW_I93_ONS_N36RW02:
+      return ("N36RW02");
+    case RW_I93_ONS_N24RF04:
+      return ("N24RF04");
+    case RW_I93_ONS_N24RF04E:
+      return ("N24RF04E");
+    case RW_I93_ONS_N24RF16:
+      return ("N24RF16");
+    case RW_I93_ONS_N24RF16E:
+      return ("N24RF16E");
+    case RW_I93_ONS_N24RF64:
+      return ("N24RF64");
+    case RW_I93_ONS_N24RF64E:
+      return ("N24RF64E");
     case RW_I93_UNKNOWN_PRODUCT:
     default:
       return "UNKNOWN";
   }
-}
+} 
\ No newline at end of file
diff --git a/src/nfc/tags/rw_mfc.cc b/src/nfc/tags/rw_mfc.cc
index 7fff8c8..07b5465 100644
--- a/src/nfc/tags/rw_mfc.cc
+++ b/src/nfc/tags/rw_mfc.cc
@@ -1332,7 +1332,7 @@
  **
  *******************************************************************************/
 static void rw_mfc_process_error() {
-  tRW_READ_DATA evt_data;
+  tRW_READ_DATA evt_data = tRW_READ_DATA();
   tRW_EVENT rw_event = RW_MFC_NDEF_DETECT_EVT;
   NFC_HDR* p_cmd_buf;
   tRW_MFC_CB* p_mfc = &rw_cb.tcb.mfc;
diff --git a/src/nfc/tags/rw_t3t.cc b/src/nfc/tags/rw_t3t.cc
index dce6ba8..26f9c1d 100644
--- a/src/nfc/tags/rw_t3t.cc
+++ b/src/nfc/tags/rw_t3t.cc
@@ -1235,7 +1235,7 @@
   uint32_t temp;
   uint8_t i;
   uint16_t checksum_calc, checksum_rx;
-  tRW_DETECT_NDEF_DATA evt_data;
+  tRW_DETECT_NDEF_DATA evt_data = tRW_DETECT_NDEF_DATA();
   uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
 
   evt_data.status = NFC_STATUS_FAILED;
@@ -1330,15 +1330,28 @@
             p_cb->ndef_attrib.nbr, p_cb->ndef_attrib.nbw,
             p_cb->ndef_attrib.nmaxb, p_cb->ndef_attrib.writef,
             p_cb->ndef_attrib.rwflag, p_cb->ndef_attrib.ln);
-
-        /* Set data for RW_T3T_NDEF_DETECT_EVT */
-        evt_data.status = p_cb->ndef_attrib.status;
-        evt_data.cur_size = p_cb->ndef_attrib.ln;
-        evt_data.max_size = (uint32_t)p_cb->ndef_attrib.nmaxb * 16;
-        evt_data.protocol = NFC_PROTOCOL_T3T;
-        evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
-        if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
-          evt_data.flags |= RW_NDEF_FL_READ_ONLY;
+        if (p_cb->ndef_attrib.nbr > T3T_MSG_NUM_BLOCKS_CHECK_MAX ||
+            p_cb->ndef_attrib.nbw > T3T_MSG_NUM_BLOCKS_UPDATE_MAX) {
+          /* It would result in CHECK Responses exceeding the maximum length
+           * of an NFC-F Frame */
+          LOG(ERROR) << StringPrintf(
+              "Unsupported NDEF Attributes value: Nbr=%i, Nbw=%i, Nmaxb=%i,"
+              "WriteF=%i, RWFlag=%i, Ln=%i",
+              p_cb->ndef_attrib.nbr, p_cb->ndef_attrib.nbw,
+              p_cb->ndef_attrib.nmaxb, p_cb->ndef_attrib.writef,
+              p_cb->ndef_attrib.rwflag, p_cb->ndef_attrib.ln);
+          p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
+          evt_data.status = NFC_STATUS_BAD_RESP;
+        } else {
+          /* Set data for RW_T3T_NDEF_DETECT_EVT */
+          evt_data.status = p_cb->ndef_attrib.status;
+          evt_data.cur_size = p_cb->ndef_attrib.ln;
+          evt_data.max_size = (uint32_t)p_cb->ndef_attrib.nmaxb * 16;
+          evt_data.protocol = NFC_PROTOCOL_T3T;
+          evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
+          if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
+            evt_data.flags |= RW_NDEF_FL_READ_ONLY;
+        }
       }
     }
   }
@@ -1418,7 +1431,7 @@
 *****************************************************************************/
 void rw_t3t_act_handle_update_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
   uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
-  tRW_READ_DATA evt_data;
+  tRW_READ_DATA evt_data = tRW_READ_DATA();
 
   /* Validate response from tag */
   if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
diff --git a/utils/Android.bp b/utils/Android.bp
index 04053a4..4a35cc0 100644
--- a/utils/Android.bp
+++ b/utils/Android.bp
@@ -48,3 +48,17 @@
         "libbase",
     ],
 }
+
+cc_fuzz {
+    name: "nfc_utils_ringbuffer_fuzzer",
+    host_supported: true,
+    srcs: [
+        "test/ringbuffer_fuzzer/ringbuffer_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libnfcutils",
+    ],
+    corpus: [
+        "test/ringbuffer_fuzzer/corpus/*",
+    ],
+}
\ No newline at end of file
diff --git a/utils/config.cc b/utils/config.cc
index 48bee61..6354a2e 100644
--- a/utils/config.cc
+++ b/utils/config.cc
@@ -41,13 +41,17 @@
 
 }  // namespace
 
-ConfigValue::ConfigValue() {}
+ConfigValue::ConfigValue() {
+  type_ = UNSIGNED;
+  value_unsigned_ = 0;
+}
 
 ConfigValue::ConfigValue(std::string value) {
   // Don't allow empty strings
   CHECK(!(value.empty()));
   type_ = STRING;
   value_string_ = value;
+  value_unsigned_ = 0;
 }
 
 ConfigValue::ConfigValue(unsigned value) {
@@ -59,6 +63,7 @@
   CHECK(!(value.empty()));
   type_ = BYTES;
   value_bytes_ = value;
+  value_unsigned_ = 0;
 }
 
 ConfigValue::Type ConfigValue::getType() const { return type_; }
diff --git a/utils/ringbuffer.cc b/utils/ringbuffer.cc
index e130afd..7b494a3 100644
--- a/utils/ringbuffer.cc
+++ b/utils/ringbuffer.cc
@@ -30,9 +30,11 @@
 };
 
 ringbuffer_t* ringbuffer_init(const size_t size) {
+  if (size == 0) return nullptr;
+
   ringbuffer_t* p = static_cast<ringbuffer_t*>(calloc(1, sizeof(ringbuffer_t)));
 
-  if (p == nullptr) return p;
+  if (p == nullptr) return nullptr;
 
   p->base = static_cast<uint8_t*>(calloc(size, sizeof(uint8_t)));
   p->head = p->tail = p->base;
diff --git a/utils/test/ringbuffer_fuzzer/corpus/zero_size_ringbuffer_fpe b/utils/test/ringbuffer_fuzzer/corpus/zero_size_ringbuffer_fpe
new file mode 100644
index 0000000..b9f6f03
--- /dev/null
+++ b/utils/test/ringbuffer_fuzzer/corpus/zero_size_ringbuffer_fpe
Binary files differ
diff --git a/utils/test/ringbuffer_fuzzer/ringbuffer_fuzzer.cpp b/utils/test/ringbuffer_fuzzer/ringbuffer_fuzzer.cpp
new file mode 100644
index 0000000..9523fe5
--- /dev/null
+++ b/utils/test/ringbuffer_fuzzer/ringbuffer_fuzzer.cpp
@@ -0,0 +1,83 @@
+#include <sys/types.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+
+#include "ringbuffer.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
+  if (Size < 2) {
+    return 0;
+  }
+
+  // Only allocate up to 1 << 16 bytes of memory. We shouldn't ever be
+  // exercising more than this.
+  uint16_t buffer_size = *((const uint16_t*)Data);
+  ringbuffer_t* buffer = ringbuffer_init(buffer_size);
+
+  if (buffer == nullptr) {
+    return 0;
+  }
+
+  for (size_t i = 2; i < Size;) {
+    size_t bytes_left = Size - i - 1;
+    switch (Data[i++] % 6) {
+      case 0: {
+        ringbuffer_available(buffer);
+        break;
+      }
+      case 1: {
+        ringbuffer_size(buffer);
+        break;
+      }
+      case 2: {
+        if (bytes_left < 2) {
+          break;
+        }
+
+        size_t bytes_to_insert = std::min(bytes_left - 1, (size_t)Data[i++]);
+        ringbuffer_insert(buffer, &Data[i], bytes_to_insert);
+        i += bytes_to_insert;
+        break;
+      }
+      case 3: {
+        if (bytes_left < 2) {
+          break;
+        }
+
+        size_t bytes_to_grab = Data[i++];
+        uint8_t* copy_buffer = (uint8_t*)malloc(bytes_to_grab);
+        off_t offset = 0;
+        if (ringbuffer_size(buffer) != 0) {
+          offset = Data[i++] % ringbuffer_size(buffer);
+        }
+
+        ringbuffer_peek(buffer, offset, copy_buffer, (size_t)bytes_to_grab);
+        free(copy_buffer);
+        break;
+      }
+      case 4: {
+        if (bytes_left < 1) {
+          break;
+        }
+
+        size_t bytes_to_grab = Data[i++];
+        uint8_t* copy_buffer = (uint8_t*)malloc(bytes_to_grab);
+        ringbuffer_pop(buffer, copy_buffer, bytes_to_grab);
+        free(copy_buffer);
+        break;
+      }
+      case 5: {
+        if (bytes_left < 1) {
+          break;
+        }
+        ringbuffer_delete(buffer, (size_t)Data[i++]);
+      }
+    }
+  }
+
+  ringbuffer_free(buffer);
+  return 0;
+}