Snap for 8564071 from 509d161c208c6aaea62a66fd3481235efce2cf31 to mainline-wifi-release

Change-Id: I0a7a71139ad6e361a6a66217749ec0bb9201792d
diff --git a/1.0/Android.bp b/1.0/Android.bp
index 2cacd47..547e72a 100644
--- a/1.0/Android.bp
+++ b/1.0/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_st_secure_element_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_st_secure_element_license"],
+}
+
 cc_binary {
     name: "android.hardware.secure_element@1.0-service.st",
     relative_install_path: "hw",
@@ -19,4 +28,8 @@
         "liblog",
         "libutils",
     ],
+
+    sanitize: {
+        memtag_heap: true,
+    },
 }
diff --git a/1.1/Android.bp b/1.1/Android.bp
index 753f922..43ced91 100644
--- a/1.1/Android.bp
+++ b/1.1/Android.bp
@@ -12,6 +12,15 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_st_secure_element_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_st_secure_element_license"],
+}
+
 cc_binary {
     name: "android.hardware.secure_element@1.1-service.st",
     defaults: ["hidl_defaults"],
@@ -34,4 +43,8 @@
         "liblog",
         "libutils",
     ],
+
+    sanitize: {
+        memtag_heap: true,
+    },
 }
diff --git a/1.2/Android.bp b/1.2/Android.bp
index 2ac911d..414762a 100644
--- a/1.2/Android.bp
+++ b/1.2/Android.bp
@@ -12,6 +12,15 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_st_secure_element_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_st_secure_element_license"],
+}
+
 cc_binary {
     name: "android.hardware.secure_element@1.2-service.st",
     defaults: ["hidl_defaults"],
@@ -35,4 +44,8 @@
         "liblog",
         "libutils",
     ],
+
+    sanitize: {
+        memtag_heap: true,
+    },
 }
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/Android.bp b/Android.bp
new file mode 100644
index 0000000..b8e7f2f
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_st_secure_element_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "hardware_st_secure_element_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "LICENSE",
+    ],
+}
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/Android.bp b/ese-spi-driver/Android.bp
index 3cc9ebc..6503586 100644
--- a/ese-spi-driver/Android.bp
+++ b/ese-spi-driver/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_st_secure_element_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_st_secure_element_license"],
+}
+
 cc_library_shared {
 
     name: "ese_spi_st",
diff --git a/ese-spi-driver/SpiLayerComm.cc b/ese-spi-driver/SpiLayerComm.cc
index a6e4008..a922234 100644
--- a/ese-spi-driver/SpiLayerComm.cc
+++ b/ese-spi-driver/SpiLayerComm.cc
@@ -35,6 +35,21 @@
 
 /*******************************************************************************
 **
+** Function         SpiLayerComm_init
+**
+** Description      Initialize
+**
+** Parameters       spiDevPath - Spi device path.
+**
+** Returns          null
+**
+*******************************************************************************/
+void SpiLayerComm_init(SpiDriver_config_t* tSpiDriver) {
+  pollInterval = tSpiDriver->polling_interval;
+  STLOG_HAL_D("SpiLayerDriver_init  pollInterval=  %d us", pollInterval);
+}
+/*******************************************************************************
+**
 ** Function         SpiLayerComm_waitForAtpLength
 **
 ** Description      Starts the polling mechanism to read the length of the ATP.
@@ -236,7 +251,8 @@
   // Start the polling mechanism
   while (true) {
     // Wait between each polling sequence
-    usleep(1000);
+    usleep(pollInterval);
+
     // Read the slave response by sending three null bytes
     if (SpiLayerDriver_read(&pollingRxByte, 1) != 1) {
       STLOG_HAL_E("Error reading a valid NAD from the slave.");
@@ -255,7 +271,7 @@
       unsigned int elapsedTimeInMs =
           Utils_getElapsedTimeInMs(startTime, currentTime);
       if (elapsedTimeInMs > maxWaitingTime) {
-        STLOG_HAL_D("BWT timed out after %d ms before receiving a valid NAD",
+        STLOG_HAL_E("BWT timed out after %d ms before receiving a valid NAD",
                     elapsedTimeInMs);
         return -2;
       }
@@ -268,7 +284,6 @@
   if (SpiLayerDriver_read(buffer, 2) != 2) {
     return -1;
   }
-
   // Save the prologue read into the tpduRx
   respTpdu->nad = pollingRxByte;
   respTpdu->pcb = buffer[0];
diff --git a/ese-spi-driver/SpiLayerComm.h b/ese-spi-driver/SpiLayerComm.h
index 442f30f..fa06586 100644
--- a/ese-spi-driver/SpiLayerComm.h
+++ b/ese-spi-driver/SpiLayerComm.h
@@ -19,6 +19,7 @@
 #ifndef SPILAYERCOMM_H_
 #define SPILAYERCOMM_H_
 
+#include "SpiLayerInterface.h"
 #include "utils-lib/Tpdu.h"
 
 #define NAD_HOST_TO_SLAVE 0x21
@@ -29,6 +30,13 @@
 // Global variables
 
 /**
+ * Initialize internal variables.
+ *
+ * @return  null
+ */
+
+void SpiLayerComm_init(SpiDriver_config_t* tSpiDriver);
+/**
  * Starts the polling mechanism to read the length of the ATP.
  *
  * @returns 0 if everything is ok, -1 otherwise.
diff --git a/ese-spi-driver/SpiLayerDriver.cc b/ese-spi-driver/SpiLayerDriver.cc
index d2a1509..757fde8 100644
--- a/ese-spi-driver/SpiLayerDriver.cc
+++ b/ese-spi-driver/SpiLayerDriver.cc
@@ -28,9 +28,25 @@
 int currentMode;
 struct timeval lastRxTxTime;
 #define LINUX_DBGBUFFER_SIZE 300
+int BGT = 1000;  // in us
 
 /*******************************************************************************
 **
+** Function         SpiLayerDriver_init
+**
+** Description      Initialize
+**
+** Parameters       spiDevPath - Spi device path.
+**
+** Returns          null
+**
+*******************************************************************************/
+void SpiLayerDriver_init(SpiDriver_config_t* tSpiDriver) {
+  BGT = tSpiDriver->bgt;
+  STLOG_HAL_D("SpiLayerDriver_init  BGT=  %d us", BGT);
+}
+/*******************************************************************************
+**
 ** Function         SpiLayerDriver_open
 **
 ** Description      Open the spi device driver.
@@ -95,11 +111,12 @@
     struct timeval currentTime;
     gettimeofday(&currentTime, 0);
     STLOG_HAL_V("     Now: %ld,%ld", currentTime.tv_sec, currentTime.tv_usec);
-    int elapsedTime = Utils_getElapsedTimeInMs(lastRxTxTime, currentTime);
-    if (elapsedTime < MIN_TIME_BETWEEN_MODE_SWITCH) {
-      int waitTime = MIN_TIME_BETWEEN_MODE_SWITCH - elapsedTime;
-      STLOG_HAL_V("Waiting %d ms to switch from TX to RX", waitTime);
-      usleep(waitTime * 1000);
+
+    int elapsedTimeUs = Utils_getElapsedTimeInUs(lastRxTxTime, currentTime);
+    if (elapsedTimeUs < BGT) {
+      int waitTime = BGT - elapsedTimeUs;
+      STLOG_HAL_V("Waiting %d us to switch from TX to RX", waitTime);
+      usleep(waitTime);
     }
     gettimeofday(&currentTime, 0);
     STLOG_HAL_V("Start RX: %ld,%ld", currentTime.tv_sec, currentTime.tv_usec);
@@ -162,12 +179,12 @@
     STLOG_HAL_V(" Last RX: %ld,%ld", lastRxTxTime.tv_sec, lastRxTxTime.tv_usec);
     struct timeval currentTime;
     gettimeofday(&currentTime, 0);
-    STLOG_HAL_V("     Now: %ld,%ld", currentTime.tv_sec, currentTime.tv_usec);
-    int elapsedTime = Utils_getElapsedTimeInMs(lastRxTxTime, currentTime);
-    if (elapsedTime < MIN_TIME_BETWEEN_MODE_SWITCH) {
-      int waitTime = MIN_TIME_BETWEEN_MODE_SWITCH - elapsedTime;
-      STLOG_HAL_V("Waiting %d ms to switch from RX to TX", waitTime);
-      usleep(waitTime * 1000);
+
+    int elapsedTimeUs = Utils_getElapsedTimeInUs(lastRxTxTime, currentTime);
+    if (elapsedTimeUs < BGT) {
+      int waitTime = BGT - elapsedTimeUs;
+      STLOG_HAL_V("Waiting %d us to switch from RX to TX", waitTime);
+      usleep(waitTime);
     }
     gettimeofday(&currentTime, 0);
     STLOG_HAL_V("Start TX: %ld,%ld", currentTime.tv_sec, currentTime.tv_usec);
diff --git a/ese-spi-driver/SpiLayerDriver.h b/ese-spi-driver/SpiLayerDriver.h
index 5da1ab6..61b75cc 100644
--- a/ese-spi-driver/SpiLayerDriver.h
+++ b/ese-spi-driver/SpiLayerDriver.h
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
+#include "SpiLayerInterface.h"
 
 #define ATP_FILE_PATH "/data/vendor/ese/atp.bin"
 
@@ -35,6 +36,14 @@
 #define ST54J_SE_PULSE_RESET _IOR(ST54J_SE_MAGIC, 0x01, unsigned int)
 
 /**
+ * Initialize internal variables.
+ *
+ * @return  null
+ */
+
+void SpiLayerDriver_init(SpiDriver_config_t* tSpiDriver);
+
+/**
  * Open the spi device driver.
  *
  * @return  -1 if an error occurred, file descriptor if success.
diff --git a/ese-spi-driver/SpiLayerInterface.cc b/ese-spi-driver/SpiLayerInterface.cc
index 11b9f65..4d35152 100644
--- a/ese-spi-driver/SpiLayerInterface.cc
+++ b/ese-spi-driver/SpiLayerInterface.cc
@@ -51,6 +51,9 @@
   // Configure the SPI before start the data exchange with the eSE
   char* spiDevPath = tSpiDriver->pDevName;
 
+  SpiLayerComm_init(tSpiDriver);
+  SpiLayerDriver_init(tSpiDriver);
+
   int DevHandle = SpiLayerDriver_open(spiDevPath);
   tSpiDriver->pDevHandle = (void*)((intptr_t)DevHandle);
   if (DevHandle == -1) {
@@ -153,16 +156,29 @@
 **
 *******************************************************************************/
 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();
-  // Negotiate IFS value
-  if (T1protocol_doRequestIFS() != 0) {
+
+  uint8_t* pRsp = (uint8_t*)malloc(ATP.ifsc * sizeof(uint8_t));
+  int rc =
+      T1protocol_transcieveApduPart(0, 0, false, (StEse_data*)pRsp, S_IFS_REQ);
+
+  if (rc < 0) {
+    STLOG_HAL_E(" %s ESE - Error transmitting IFS request\n", __FUNCTION__);
+    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/SpiLayerInterface.h b/ese-spi-driver/SpiLayerInterface.h
index 01c0cf9..c6ed047 100644
--- a/ese-spi-driver/SpiLayerInterface.h
+++ b/ese-spi-driver/SpiLayerInterface.h
@@ -30,6 +30,10 @@
    * e.g. On Linux based systems this would be /dev/p73
    */
 
+  int bgt;
+
+  int polling_interval;
+
   uint32_t devMaxFreq;
   /*!< Communication speed between DH and ESE
    *
diff --git a/ese-spi-driver/StEseApi.cc b/ese-spi-driver/StEseApi.cc
index 9f046d7..e7c25d9 100644
--- a/ese-spi-driver/StEseApi.cc
+++ b/ese-spi-driver/StEseApi.cc
@@ -18,11 +18,11 @@
  ******************************************************************************/
 #define LOG_TAG "StEse_HalApi"
 
-#include <pthread.h>
 #include "StEseApi.h"
-#include "SpiLayerComm.h"
 #include <cutils/properties.h>
 #include <ese_config.h>
+#include <pthread.h>
+#include "SpiLayerComm.h"
 #include "T1protocol.h"
 #include "android_logmsg.h"
 
@@ -31,10 +31,14 @@
 /* ESE Context structure */
 ese_Context_t ese_ctxt;
 
-const char* halVersion = "ST54-SE HAL1.0 Version 1.0.20";
+const char* halVersion = "ST54-SE HAL1.0 Version 1.0.22";
 
 pthread_mutex_t mutex;
 
+bool ConfRead = 0;
+unsigned int PollInt_confvalue = 1000;
+unsigned int BGT_confvalue = 1000;
+
 /******************************************************************************
  * Function         StEseLog_InitializeLogLevel
  *
@@ -84,9 +88,22 @@
   strcpy(ese_dev_node, ese_node.c_str());
   tSpiDriver.pDevName = ese_dev_node;
 
+  if (!ConfRead) {
+    PollInt_confvalue =
+        EseConfig::getUnsigned(NAME_ST_ESE_DEV_POLLING_INTERVAL, 1000);
+    BGT_confvalue = EseConfig::getUnsigned(NAME_ST_ESE_DEV_BGT, 1000);
+    ConfRead = true;
+  }
+
+  tSpiDriver.polling_interval = PollInt_confvalue;
+  tSpiDriver.bgt = BGT_confvalue;
+
   /* 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*/
@@ -134,6 +151,7 @@
 ESESTATUS StEse_Transceive(StEse_data* pCmd, StEse_data* pRsp) {
   ESESTATUS status = ESESTATUS_SUCCESS;
   static int pTxBlock_len = 0;
+  int retry_count = 0;
   uint16_t pCmdlen = pCmd->len;
 
   STLOG_HAL_D("%s : Enter EseLibStatus = %d ", __func__, ese_ctxt.EseLibStatus);
@@ -155,33 +173,51 @@
 
   uint8_t* CmdPart = pCmd->p_data;
 
+retry:
   while (pCmdlen > ATP.ifsc) {
     pTxBlock_len = ATP.ifsc;
 
     int rc = T1protocol_transcieveApduPart(CmdPart, pTxBlock_len, false,
-                                           (StEse_data*) pRsp);
-    if (rc < 0) {
+                                           (StEse_data*)pRsp, I_block);
+
+    if ((rc == -2) && (retry_count < 3)) {
+      retry_count++;
+      STLOG_HAL_E(" %s ESE - resync was needed, resend the whole frame retry"
+                  " = %d\n", __FUNCTION__, retry_count);
+      pCmdlen = pCmd->len;
+      CmdPart = pCmd->p_data;
+      goto retry;
+    } else if (rc < 0) {
       STLOG_HAL_E(" %s ESE - Error, release access \n", __FUNCTION__);
       status = ESESTATUS_FAILED;
-
+      retry_count = 0;
       pthread_mutex_unlock(&mutex);
 
       return status;
+    } else {
+      retry_count = 0;
     }
+
     pCmdlen -= pTxBlock_len;
     CmdPart = CmdPart + pTxBlock_len;
-    if (ESESTATUS_SUCCESS != status) {
-      STLOG_HAL_E(" %s T1protocol_transcieveApduPart- Failed \n", __FUNCTION__);
-    }
   }
+
   int rc = T1protocol_transcieveApduPart(CmdPart, pCmdlen, true,
-                                         (StEse_data*) pRsp);
-  if (rc < 0) status = ESESTATUS_FAILED;
+                                         (StEse_data*)pRsp, I_block);
+  if ((rc == -2) && (retry_count < 3)) {
+    retry_count++;
+    STLOG_HAL_E(" %s ESE - resync was needed, resend retry = %d\n",
+                __FUNCTION__, retry_count);
+    pCmdlen = pCmd->len;
+    CmdPart = pCmd->p_data;
+    goto retry;
+  } else if (rc < 0)
+    status = ESESTATUS_FAILED;
 
   if (ESESTATUS_SUCCESS != status) {
     STLOG_HAL_E(" %s T1protocol_transcieveApduPart- Failed \n", __FUNCTION__);
   }
-
+  retry_count = 0;
   STLOG_HAL_D(" %s ESE - Processing complete, release access \n", __FUNCTION__);
 
   pthread_mutex_unlock(&mutex);
diff --git a/ese-spi-driver/T1protocol.cc b/ese-spi-driver/T1protocol.cc
index c9db707..c955a37 100644
--- a/ese-spi-driver/T1protocol.cc
+++ b/ese-spi-driver/T1protocol.cc
@@ -32,6 +32,7 @@
 uint8_t SEQ_NUM_SLAVE;
 uint8_t recoveryStatus;
 T1TProtocol_TransceiveState gNextCmd = Idle;
+T1TProtocol_TransceiveState gOriginalCmd = Idle;
 
 /*******************************************************************************
 **
@@ -476,8 +477,12 @@
     // retransmission of the original IBlock, otherwise do resend request.
     if (T1protocol_isSequenceNumberOk(originalCmdTpdu, lastRespTpduReceived) ==
         true) {
-      STLOG_HAL_D("%s : Need retransmissiom :", __func__);
-      gNextCmd = I_block;
+      STLOG_HAL_E("%s : Need retransmissiom :", __func__);
+      if (gOriginalCmd == S_IFS_REQ) {
+        gNextCmd = S_IFS_REQ;
+      } else {
+        gNextCmd = I_block;
+      }
     } else {
       gNextCmd = S_Resync_REQ;
     }
@@ -576,15 +581,16 @@
 ** Returns          0 If all went is ok, -1 otherwise.
 **
 *******************************************************************************/
-int T1protocol_processSBlock(Tpdu* originalCmdTpdu, Tpdu* lastCmdTpduSent,
+int T1protocol_processSBlock(__attribute((unused)) Tpdu* originalCmdTpdu,
+                             __attribute((unused)) Tpdu* lastCmdTpduSent,
                              Tpdu* lastRespTpduReceived) {
-  int rc;
   if (lastRespTpduReceived->pcb == (uint8_t)SBLOCK_WTX_REQUEST_MASK) {
     gNextCmd = S_WTX_RES;
   } else if (lastRespTpduReceived->pcb == (uint8_t)SBLOCK_IFS_REQUEST_MASK) {
     gNextCmd = S_IFS_RES;
   } else if (lastRespTpduReceived->pcb == (uint8_t)SBLOCK_IFS_RESPONSE_MASK) {
     ATP.ifsc = (uint8_t)lastRespTpduReceived->data[0];
+    gNextCmd = Idle;
     return 0;
   } else if (lastRespTpduReceived->pcb ==
              (uint8_t)SBLOCK_RESYNCH_REQUEST_MASK) {
@@ -593,20 +599,9 @@
   } else if (lastRespTpduReceived->pcb ==
              (uint8_t)SBLOCK_RESYNCH_RESPONSE_MASK) {
     T1protocol_resetSequenceNumbers();
-    // Reset the sequence number of the original Tpdu if needed
-    if ((originalCmdTpdu->pcb & IBLOCK_NS_BIT_MASK) > 0) {
-      originalCmdTpdu->pcb &= ~IBLOCK_NS_BIT_MASK;
 
-      rc = Tpdu_formTpdu(originalCmdTpdu->nad, originalCmdTpdu->pcb,
-                         originalCmdTpdu->len, originalCmdTpdu->data,
-                         originalCmdTpdu);
-      if (rc < 0) {
-        return rc;
-      }
-    }
-
-    Tpdu_copy(lastCmdTpduSent, originalCmdTpdu);
-    gNextCmd = I_block;
+    STLOG_HAL_E("RESYNCH response - resend the whole frame");
+    return -2;
 
   } else if (lastRespTpduReceived->pcb == (uint8_t)SBLOCK_ABORT_REQUEST_MASK) {
     // TODO
@@ -700,22 +695,22 @@
 void T1protocol_updateRecoveryStatus() {
   switch (recoveryStatus) {
     case RECOVERY_STATUS_OK:
-      STLOG_HAL_D("recoveryStatus: OK -> RESEND 1");
+      STLOG_HAL_E("recoveryStatus: OK -> RESEND 1");
       recoveryStatus = RECOVERY_STATUS_RESEND_1;
       break;
 
     case RECOVERY_STATUS_RESEND_1:
-        STLOG_HAL_D("recoveryStatus: RESEND 1 -> RESYNC 1");
-        recoveryStatus = RECOVERY_STATUS_RESYNC_1;
+      STLOG_HAL_E("recoveryStatus: RESEND 1 -> RESYNC 1");
+      recoveryStatus = RECOVERY_STATUS_RESYNC_1;
       break;
 
     case RECOVERY_STATUS_RESYNC_1:
-      STLOG_HAL_D("recoveryStatus: RESYNC 1 -> WARM RESET");
+      STLOG_HAL_E("recoveryStatus: RESYNC 1 -> WARM RESET");
       recoveryStatus = RECOVERY_STATUS_WARM_RESET;
       break;
 
     case RECOVERY_STATUS_WARM_RESET:
-      STLOG_HAL_D("recoveryStatus: WARM_RESET (recovery completed)");
+      STLOG_HAL_E("recoveryStatus: WARM_RESET (recovery completed)");
       recoveryStatus = RECOVERY_STATUS_KO;
       break;
   }
@@ -974,7 +969,7 @@
   // If the last transmission ends without response from the slave, do
   // recovery mechanism.
   if (*bytesRead == 0) {
-    STLOG_HAL_D("bytesRead = 0 -> Going into recovery.");
+    STLOG_HAL_E("bytesRead = 0 -> Going into recovery.");
     rc = T1protocol_doRecovery();
     return rc;
   }
@@ -982,7 +977,7 @@
   // Check the consistency of the last received tpdu
   rc = T1protocol_checkTpduConsistency(lastCmdTpduSent, lastRespTpduReceived);
   if (rc < 0) {
-    STLOG_HAL_D("%s : TPDU consistency check failed -> Going into recovery.",
+    STLOG_HAL_E("%s : TPDU consistency check failed -> Going into recovery.",
                 __func__);
     rc = T1protocol_doRecovery();
     return rc;
@@ -1066,38 +1061,33 @@
 ** Returns         0 if everything went fine, -1 if something failed.
 **
 *******************************************************************************/
-int T1protocol_doRequestIFS() {
-  Tpdu originalCmdTpdu, lastCmdTpduSent, lastRespTpduReceived;
-  originalCmdTpdu.data = (uint8_t*)malloc(ATP.ifsc * sizeof(uint8_t));
-  lastCmdTpduSent.data = (uint8_t*)malloc(ATP.ifsc * sizeof(uint8_t));
-  lastRespTpduReceived.data = (uint8_t*)malloc(ATP.ifsc * sizeof(uint8_t));
+int T1protocol_doRequestIFS(Tpdu* lastRespTpduReceived) {
+  Tpdu* TempTpdu = (Tpdu*)malloc(sizeof(Tpdu));
+  TempTpdu->data = (uint8_t*)malloc(ATP.ifsc * sizeof(uint8_t));
 
   STLOG_HAL_D("%s : Enter ", __func__);
-  // Form a SBlock Resynch request Tpdu to sent.
+
+  // Form a SBlock IFS request Tpdu to sent.
   int result = Tpdu_formTpdu(NAD_HOST_TO_SLAVE, SBLOCK_IFS_REQUEST_MASK, 1,
-                             &ATP.ifsc, &originalCmdTpdu);
-  if (result) {
-    return result;
-  }
-
-  Tpdu_copy(&lastCmdTpduSent, &originalCmdTpdu);
-
-  // Send the SBlock and read the response from the slave.
-  result = SpiLayerInterface_transcieveTpdu(
-      &lastCmdTpduSent, &lastRespTpduReceived, DEFAULT_NBWT);
-  if (result <= 0) {
+                             &ATP.ifsc, TempTpdu);
+  if (result == -1) {
+    free(TempTpdu->data);
+    free(TempTpdu);
     return -1;
   }
 
-  result = T1protocol_handleTpduResponse(&originalCmdTpdu, &lastCmdTpduSent,
-                                         &lastRespTpduReceived, &result);
+  // Send the SBlock and read the response from the secondary (eSE).
+  result = SpiLayerInterface_transcieveTpdu(TempTpdu, lastRespTpduReceived,
+                                            DEFAULT_NBWT);
 
-  free(originalCmdTpdu.data);
-  originalCmdTpdu.data = NULL;
-  free(lastCmdTpduSent.data);
-  lastCmdTpduSent.data = NULL;
-  free(lastRespTpduReceived.data);
-  lastRespTpduReceived.data = NULL;
+  if (result < 0) {
+    free(TempTpdu->data);
+    free(TempTpdu);
+    return -1;
+  }
+
+  free(TempTpdu->data);
+  free(TempTpdu);
   return result;
 }
 
@@ -1136,7 +1126,8 @@
 **
 *******************************************************************************/
 int T1protocol_transcieveApduPart(uint8_t* cmdApduPart, uint8_t cmdLength,
-                                  bool isLast, StEse_data* pRsp) {
+                                  bool isLast, StEse_data* pRsp,
+                                  T1TProtocol_TransceiveState Block_type) {
   Tpdu originalCmdTpdu, lastCmdTpduSent, lastRespTpduReceived;
   originalCmdTpdu.data = (uint8_t*)malloc(ATP.ifsc * sizeof(uint8_t));
   lastCmdTpduSent.data = (uint8_t*)malloc(ATP.ifsc * sizeof(uint8_t));
@@ -1144,7 +1135,7 @@
   StEse_data pRes;
 
   memset(&pRes, 0x00, sizeof(StEse_data));
-  STLOG_HAL_D("%s : Enter", __func__);
+  STLOG_HAL_E("%s : Enter cmdLength = 0x%02X", __func__, cmdLength);
 
   // Form the cmdTpdu according to the cmdApduPart, cmdLength and isLast
   // fields.
@@ -1158,7 +1149,8 @@
   recoveryStatus = RECOVERY_STATUS_OK;
   Tpdu_copy(&lastCmdTpduSent, &originalCmdTpdu);
 
-  gNextCmd = I_block;
+  gOriginalCmd = Block_type;
+  gNextCmd = Block_type;
   while (gNextCmd != 0) {
     switch (gNextCmd) {
       case I_block:
@@ -1203,6 +1195,13 @@
         }
         break;
 
+      case S_IFS_REQ:
+        rc = T1protocol_doRequestIFS(&lastRespTpduReceived);
+        if (rc < 0) {
+          return rc;
+        }
+        break;
+
       default:
         return -1;
         break;
diff --git a/ese-spi-driver/T1protocol.h b/ese-spi-driver/T1protocol.h
index 517c91c..e165a88 100644
--- a/ese-spi-driver/T1protocol.h
+++ b/ese-spi-driver/T1protocol.h
@@ -331,7 +331,7 @@
  *
  * @return 0 if everything went fine, -1 if an error occurred.
  */
-int T1protocol_doRequestIFS();
+int T1protocol_doRequestIFS(Tpdu* lastRespTpduReceived);
 
 /**
  * Handles any TPDU response iteratively.
@@ -396,7 +396,8 @@
  *          - 1 if there are more response parts
  *          - -1 if an error occurred.
  */
-int T1protocol_transcieveApduPart(uint8_t *cmdApduPart, uint8_t cmdLength,
-                                  bool isLast, StEse_data *pRsp);
+int T1protocol_transcieveApduPart(uint8_t* cmdApduPart, uint8_t cmdLength,
+                                  bool isLast, StEse_data* pRsp,
+                                  T1TProtocol_TransceiveState Block_type);
 
 #endif /* _T1PROTOCOL_H_ */
diff --git a/ese-spi-driver/utils-lib/Utils.cc b/ese-spi-driver/utils-lib/Utils.cc
index c444b2b..7c411cd 100644
--- a/ese-spi-driver/utils-lib/Utils.cc
+++ b/ese-spi-driver/utils-lib/Utils.cc
@@ -62,6 +62,22 @@
 

 /*******************************************************************************

 **

+** Function        Utils_getElapsedTimeInUs

+**

+** Description     Returns the difference of time (in Us) between t1 and t2.

+**

+** Parameters      t1  - initial time.

+**                 t2  - final time.

+**

+** Returns       The difference t2 - t1 in ms.

+**

+*******************************************************************************/

+int Utils_getElapsedTimeInUs(struct timeval t1, struct timeval t2) {

+  return (t2.tv_sec - t1.tv_sec) * 1000000 + (t2.tv_usec - t1.tv_usec);

+}

+

+/*******************************************************************************

+**

 ** Function        Utils_printCurrentTime

 **

 ** Description     Prints current time to standard log.

diff --git a/ese-spi-driver/utils-lib/Utils.h b/ese-spi-driver/utils-lib/Utils.h
index 16bded2..3c74beb 100644
--- a/ese-spi-driver/utils-lib/Utils.h
+++ b/ese-spi-driver/utils-lib/Utils.h
@@ -45,6 +45,16 @@
 int Utils_getElapsedTimeInMs(struct timeval t1, struct timeval t2);

 

 /**

+ * Returns the difference of time (in us) between t1 and t2.

+ *

+ * @param t1 The initial time.

+ * @param t2 The final time.

+ *

+ * @return The difference t2 - t1 in ms.

+ */

+int Utils_getElapsedTimeInUs(struct timeval t1, struct timeval t2);

+

+/**

  * Prints current time to standard log.

  *

  * @param prefix The prefix to be printed before the time.

diff --git a/ese-spi-driver/utils-lib/ese_config.h b/ese-spi-driver/utils-lib/ese_config.h
index 84624e5..5fd41a4 100644
--- a/ese-spi-driver/utils-lib/ese_config.h
+++ b/ese-spi-driver/utils-lib/ese_config.h
@@ -28,6 +28,8 @@
  * ########################## */
 #define NAME_STESE_HAL_LOGLEVEL "STESE_HAL_LOGLEVEL"
 #define NAME_ST_ESE_DEV_NODE "ST_ESE_DEV_NODE"
+#define NAME_ST_ESE_DEV_BGT "ST_ESE_DEV_BGT"
+#define NAME_ST_ESE_DEV_POLLING_INTERVAL "ST_ESE_DEV_POLLING_INTERVAL"
 
 class EseConfig {
  public:
diff --git a/libese-hal-st.conf b/libese-hal-st.conf
index a650760..c43e0e1 100644
--- a/libese-hal-st.conf
+++ b/libese-hal-st.conf
@@ -5,6 +5,15 @@
 # ST HAL trace log level
 STESE_HAL_LOGLEVEL=4
 
-ST_ESE_DEV_NODE="/dev/st54j"
+###############################################################################
+# Configure the device node
+ST_ESE_DEV_NODE="/dev/st54j_se"
 
+###############################################################################
+# Configure the polling interval (in us)
+ST_ESE_DEV_POLLING_INTERVAL=1500
+
+###############################################################################
+# Configure the BGT timing (in us)
+ST_ESE_DEV_BGT=1000