libese-teq1: global resync maximum

Set a global maximum for software resyncs before powering the device
on and off.

This also implies a global maximum of attempts as only one physical
reset is allowed prior to a hard reset.

(Note, this pulls in the fake hw hack from libese-boot-app which
 should be migrated to libese-cpp in the future as libese-boot is
 likely to go away.)

Bug: 63546784
Test: boots; normal functions work; teq1_unittests with the error case
passes.
Change-Id: I403bd90875c08372f043d765497640c216592216
diff --git a/libese-teq1/teq1.c b/libese-teq1/teq1.c
index e17fbb1..84b7f0f 100644
--- a/libese-teq1/teq1.c
+++ b/libese-teq1/teq1.c
@@ -280,11 +280,13 @@
   case kPcbTypeSupervisory:
     if (rx_frame->header.PCB != S(RESYNC, RESPONSE) &&
         rx_frame->header.LEN != 1) {
+      ALOGE("Invalid supervisory RX frame.");
       return R(0, 1, 0);
     }
     break;
   case kPcbTypeReceiveReady:
     if (rx_frame->header.LEN != 0) {
+      ALOGE("Invalid ReceiveReady RX frame.");
       return R(0, 1, 0);
     }
     break;
@@ -296,6 +298,7 @@
       ALOGW("Got seq %d expected %d",
             bs_get(PCB.I.send_seq, rx_frame->header.PCB),
             state->card_state->seq.card);
+      ALOGE("Invalid Info RX frame.");
       return R(0, 1, 0);
     }
     /* Update the card's last I-block seq. */
@@ -564,6 +567,8 @@
   struct Teq1Frame *tx = &tx_frame[0];
   int active = 0;
   bool was_reset = false;
+  bool needs_hw_reset = false;
+  int session_resets = 0;
   bool done = false;
   enum RuleResult result = kRuleResultComplete;
   uint32_t rx_total = ese_sg_length(rx_bufs, rx_segs);
@@ -623,6 +628,7 @@
       }
       ALOGE("More than three retransmits have occurred");
       if (tx->header.PCB == S(RESYNC, REQUEST)) {
+        /* More than three RESYNC retranmits have occurred. */
         ese_set_error(ese, kTeq1ErrorHardFail);
         return 0;
       }
@@ -632,8 +638,9 @@
     case kRuleResultContinue:
       active = !active;
       tx = &tx_frame[active];
+      /* Reset this to 0 to use the counter for RESYNC transmits. */
       state.retransmits = 0;
-      state.errors = 0;
+      /* Errors are not reset until the session is reset. */
       continue;
     case kRuleResultHardFail:
       ese_set_error(ese, kTeq1ErrorHardFail);
@@ -650,14 +657,25 @@
       tx = &tx_frame[!active];
       continue;
     case kRuleResultResetDevice:
-      if (was_reset || !ese->ops->hw_reset || ese->ops->hw_reset(ese) == -1) {
-        ese_set_error(ese, kTeq1ErrorDeviceReset);
-        return 0; /* Don't keep resetting -- hard fail. */
-      }
-      was_reset = true;
+      needs_hw_reset = true;
     /* Fall through to session reset. */
     case kRuleResultResetSession:
-      /* Roll back state and reset. */
+      /* Reset to initial state and possibly do hw reset */
+      if (session_resets++ > 4) {
+        /* If there have been more than 4 resyncs without a
+         * physical reset, we should pull the plug.
+         */
+        needs_hw_reset = true;
+      }
+      if (needs_hw_reset) {
+        needs_hw_reset = false;
+        if (was_reset || !ese->ops->hw_reset || ese->ops->hw_reset(ese) == -1) {
+          ese_set_error(ese, kTeq1ErrorDeviceReset);
+          return 0; /* Don't keep resetting -- hard fail. */
+        }
+        was_reset = true;
+        session_resets = 0;
+      }
       state = init_state;
       TEQ1_INIT_CARD_STATE(state.card_state);
       /* Reset the active frame. */