Implement the retry mechanism for S-Block (IFS request)

Bug: 166546406
Bug: 169131089
Test: stress reboot/reflash tests
Merged-In: I615a1520abc746f53f56d96f7769c463b9f81542
Change-Id: I615a1520abc746f53f56d96f7769c463b9f81542
diff --git a/ese-spi-driver/SpiLayerInterface.cc b/ese-spi-driver/SpiLayerInterface.cc
index 11a7065..2803078 100644
--- a/ese-spi-driver/SpiLayerInterface.cc
+++ b/ese-spi-driver/SpiLayerInterface.cc
@@ -163,9 +163,17 @@
     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;
   }
+
+  free(pRsp);
   return 0;
 }
diff --git a/ese-spi-driver/StEseApi.cc b/ese-spi-driver/StEseApi.cc
index f47ede6..e474ee8 100644
--- a/ese-spi-driver/StEseApi.cc
+++ b/ese-spi-driver/StEseApi.cc
@@ -175,7 +175,7 @@
     pTxBlock_len = ATP.ifsc;
 
     int rc = T1protocol_transcieveApduPart(CmdPart, pTxBlock_len, false,
-                                           (StEse_data*)pRsp);
+                                           (StEse_data*)pRsp, I_block);
 
     if ((rc == -2) && (retry_count < 3)) {
       retry_count++;
@@ -199,8 +199,8 @@
     CmdPart = CmdPart + pTxBlock_len;
   }
 
-  int rc =
-      T1protocol_transcieveApduPart(CmdPart, pCmdlen, true, (StEse_data*)pRsp);
+  int rc = T1protocol_transcieveApduPart(CmdPart, pCmdlen, true,
+                                         (StEse_data*)pRsp, I_block);
   if ((rc == -2) && (retry_count < 3)) {
     retry_count++;
     STLOG_HAL_E(" %s ESE - resync was needed, resend\n", __FUNCTION__);
diff --git a/ese-spi-driver/T1protocol.cc b/ese-spi-driver/T1protocol.cc
index 7b84790..551f2a2 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;
 
 /*******************************************************************************
 **
@@ -477,7 +478,11 @@
     if (T1protocol_isSequenceNumberOk(originalCmdTpdu, lastRespTpduReceived) ==
         true) {
       STLOG_HAL_D("%s : Need retransmissiom :", __func__);
-      gNextCmd = I_block;
+      if (gOriginalCmd == S_IFS_REQ) {
+        gNextCmd = S_IFS_REQ;
+      } else {
+        gNextCmd = I_block;
+      }
     } else {
       gNextCmd = S_Resync_REQ;
     }
@@ -585,6 +590,7 @@
     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) {
@@ -1055,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;
 }
 
@@ -1125,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));
@@ -1147,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:
@@ -1192,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_ */