libese-teq1: fix S(RESYNC, REQUEST) retransmission
When a device is non-response, T=1 will send
resynchronization requests. After three attempts
it should either warm reset the device or deactivate.
The error path was not checking if the triggering
transmission was a resync requests and was clobbering
the error and retransmission counters resulting in
infinite re-attempts.
Test: replace/dev/pn81a with /dev/zero and ensure that it eventually
times out and returns a hard failure.
Bug: none
Change-Id: Iac512bb37f7f04deefe91570547840a7704542d9
diff --git a/libese-teq1/teq1.c b/libese-teq1/teq1.c
index be0011c..e17fbb1 100644
--- a/libese-teq1/teq1.c
+++ b/libese-teq1/teq1.c
@@ -331,9 +331,11 @@
/* Rule 7.4.2 */
if (state->errors >= 3) {
/* Rule 7.4.1: state should start with error count = 2 */
- next_tx->header.PCB = S(RESYNC, REQUEST);
- /* Resync result in a fresh session, so we should just continue here. */
- return kRuleResultContinue;
+ if (tx_frame->header.PCB != S(RESYNC, REQUEST)) {
+ next_tx->header.PCB = S(RESYNC, REQUEST);
+ return kRuleResultContinue;
+ }
+ return kRuleResultRetransmit;
}
}
@@ -619,11 +621,13 @@
if (state.retransmits++ < 3) {
continue;
}
+ ALOGE("More than three retransmits have occurred");
if (tx->header.PCB == S(RESYNC, REQUEST)) {
ese_set_error(ese, kTeq1ErrorHardFail);
return 0;
}
/* Fall through */
+ ALOGE("Triggering resynchronization.");
tx_frame[!active].header.PCB = S(RESYNC, REQUEST);
case kRuleResultContinue:
active = !active;