[automerger skipped] Implement the retry mechanism for S-Block (IFS request) am: 16fb2ed7a4 -s ours

am skip reason: Change-Id I615a1520abc746f53f56d96f7769c463b9f81542 with SHA-1 e2b915a1f3 is in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/st/secure_element/+/13041058

Change-Id: I486183776b1a11615e644a0ccf8603e12f445330
diff --git a/1.2/SecureElement.cpp b/1.2/SecureElement.cpp
index 0276ae6..0ec90ae 100644
--- a/1.2/SecureElement.cpp
+++ b/1.2/SecureElement.cpp
@@ -17,11 +17,16 @@
  *
  ******************************************************************************/
 #define LOG_TAG "StEse-SecureElement"
+#include "SecureElement.h"
+#include <android-base/properties.h>
 #include <android_logmsg.h>
-
+#include <dlfcn.h>
 #include <stdlib.h>
 #include <string.h>
-#include "SecureElement.h"
+
+#define VENDOR_LIB_PATH "/vendor/lib64/"
+#define VENDOR_LIB_EXT ".so"
+typedef int (*STEseReset)(void);
 
 extern bool ese_debug_enabled;
 static bool OpenLogicalChannelProcessing = false;
@@ -517,14 +522,35 @@
 
 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
 SecureElement::reset() {
+  int ret = 0;
   ESESTATUS status = ESESTATUS_SUCCESS;
   SecureElementStatus sestatus = SecureElementStatus::FAILED;
+  std::string valueStr =
+      android::base::GetProperty("persist.vendor.se.streset", "");
 
   STLOG_HAL_D("%s: Enter", __func__);
   if (!isSeInitialized()) {
     ESESTATUS status = seHalInit();
     if (status != ESESTATUS_SUCCESS) {
       STLOG_HAL_E("%s: seHalInit Failed!!!", __func__);
+      if (valueStr.length() > 0) {
+        valueStr = VENDOR_LIB_PATH + valueStr + VENDOR_LIB_EXT;
+        void* stdll = dlopen(valueStr.c_str(), RTLD_NOW);
+        if (stdll) {
+          STEseReset fn = (STEseReset)dlsym(stdll, "direct_reset");
+          if (fn) {
+            STLOG_HAL_E("STReset direct reset");
+            ret = fn();
+            STLOG_HAL_E("STReset result=%d", ret);
+            if (ret == 0) {
+              STLOG_HAL_E("STReset pass, retry seHalInit()");
+              status = seHalInit();
+            }
+          }
+        } else {
+          STLOG_HAL_D("%s not found, do nothing.", valueStr.c_str());
+        }
+      }
     }
   }
 
diff --git a/1.2/android.hardware.secure_element@1.2-service.st.rc b/1.2/android.hardware.secure_element@1.2-service.st.rc
index 2e40811..3f94a31 100644
--- a/1.2/android.hardware.secure_element@1.2-service.st.rc
+++ b/1.2/android.hardware.secure_element@1.2-service.st.rc
@@ -1,4 +1,4 @@
 service secure_element_hal_service /vendor/bin/hw/android.hardware.secure_element@1.2-service.st
     class hal
     user secure_element
-    group secure_element
+    group secure_element nfc
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+  license_type: NOTICE
+}
diff --git a/ese-spi-driver/SpiLayerInterface.cc b/ese-spi-driver/SpiLayerInterface.cc
index 2803078..4d35152 100644
--- a/ese-spi-driver/SpiLayerInterface.cc
+++ b/ese-spi-driver/SpiLayerInterface.cc
@@ -156,10 +156,13 @@
 **
 *******************************************************************************/
 int SpiLayerInterface_setup() {
+  const char ese_reset_property[] = "persist.vendor.se.reset";
   // First of all, read the ATP from the slave
   if (SpiLayerComm_readAtp() != 0) {
     // Error reading the ATP
     STLOG_HAL_E("Error reading the ATP.");
+    // eSE needs cold reset.
+    property_set(ese_reset_property, "needed");
     return -1;
   }
   T1protocol_resetSequenceNumbers();
@@ -173,6 +176,8 @@
     free(pRsp);
     return -1;
   }
+  // Set noneed if SPI worked normally.
+  property_set(ese_reset_property, "noneed");
 
   free(pRsp);
   return 0;
diff --git a/ese-spi-driver/StEseApi.cc b/ese-spi-driver/StEseApi.cc
index e474ee8..894c190 100644
--- a/ese-spi-driver/StEseApi.cc
+++ b/ese-spi-driver/StEseApi.cc
@@ -101,6 +101,9 @@
   /* Initialize SPI Driver layer */
   if (T1protocol_init(&tSpiDriver) != ESESTATUS_SUCCESS) {
     STLOG_HAL_E("T1protocol_init Failed");
+    if (intptr_t(tSpiDriver.pDevHandle) > 0) {
+      ese_ctxt.pDevHandle = tSpiDriver.pDevHandle;
+    }
     goto clean_and_return;
   }
   /* Copying device handle to ESE Lib context*/