Home | History | Annotate | Download | only in libese-teq1
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "include/ese/teq1.h"
     18 #include "../libese/include/ese/ese.h"
     19 #include "../libese/include/ese/log.h"
     20 
     21 #include "teq1_private.h"
     22 
     23 const char *teq1_rule_result_to_name(enum RuleResult result) {
     24   switch (result) {
     25   case kRuleResultComplete:
     26     return "Complete";
     27   case kRuleResultAbort:
     28     return "Abort";
     29   case kRuleResultContinue:
     30     return "Continue";
     31   case kRuleResultHardFail:
     32     return "Hard failure";
     33   case kRuleResultResetDevice:
     34     return "Reset device";
     35   case kRuleResultResetSession:
     36     return "Reset session";
     37   case kRuleResultRetransmit:
     38     return "Retransmit";
     39   case kRuleResultSingleShot:
     40     return "Single shot";
     41   };
     42 }
     43 
     44 const char *teq1_pcb_to_name(uint8_t pcb) {
     45   switch (pcb) {
     46   case I(0, 0):
     47     return "I(0, 0)";
     48   case I(0, 1):
     49     return "I(0, 1)";
     50   case I(1, 0):
     51     return "I(1, 0)";
     52   case I(1, 1):
     53     return "I(1, 1)";
     54   case R(0, 0, 0):
     55     return "R(0, 0, 0)";
     56   case R(0, 0, 1):
     57     return "R(0, 0, 1)";
     58   case R(0, 1, 0):
     59     return "R(0, 1, 0)";
     60   case R(0, 1, 1):
     61     return "R(0, 1, 1)";
     62   case R(1, 0, 0):
     63     return "R(1, 0, 0)";
     64   case R(1, 0, 1):
     65     return "R(1, 0, 1)";
     66   case R(1, 1, 0):
     67     return "R(1, 1, 0)";
     68   case R(1, 1, 1):
     69     return "R(1, 1, 1)";
     70   case S(RESYNC, REQUEST):
     71     return "S(RESYNC, REQUEST)";
     72   case S(RESYNC, RESPONSE):
     73     return "S(RESYNC, RESPONSE)";
     74   case S(IFS, REQUEST):
     75     return "S(IFS, REQUEST)";
     76   case S(IFS, RESPONSE):
     77     return "S(IFS, RESPONSE)";
     78   case S(ABORT, REQUEST):
     79     return "S(ABORT, REQUEST)";
     80   case S(ABORT, RESPONSE):
     81     return "S(ABORT, RESPONSE)";
     82   case S(WTX, REQUEST):
     83     return "S(WTX, REQUEST)";
     84   case S(WTX, RESPONSE):
     85     return "S(WTX, RESPONSE)";
     86   case 255:
     87     return "INTERNAL-ERROR";
     88   default:
     89     return "???";
     90   }
     91 }
     92 
     93 void teq1_dump_buf(const char *prefix, const uint8_t *buf, uint32_t len) {
     94   uint32_t recvd = 0;
     95   for (recvd = 0; recvd < len; ++recvd)
     96     ALOGV("%s[%u]: %.2X", prefix, recvd, buf[recvd]);
     97 }
     98 
     99 int teq1_transmit(struct EseInterface *ese,
    100                   const struct Teq1ProtocolOptions *opts,
    101                   struct Teq1Frame *frame) {
    102   /* Set correct node address. */
    103   frame->header.NAD = opts->node_address;
    104 
    105   /* Compute the LRC */
    106   frame->INF[frame->header.LEN] = teq1_compute_LRC(frame);
    107 
    108   /*
    109    * If the card does something weird, like expect an CRC/LRC based on a
    110    * different header value, the preprocessing can handle it.
    111    */
    112   if (opts->preprocess) {
    113     opts->preprocess(opts, frame, 1);
    114   }
    115 
    116   /*
    117    * Begins transmission and ignore errors.
    118    * Failed transmissions will result eventually in a resync then reset.
    119    */
    120   teq1_trace_transmit(frame->header.PCB, frame->header.LEN);
    121   teq1_dump_transmit(frame->val, sizeof(frame->header) + frame->header.LEN + 1);
    122   ese->ops->hw_transmit(ese, frame->val,
    123                         sizeof(frame->header) + frame->header.LEN + 1, 1);
    124   /*
    125    * Even though in practice any WTX BWT extension starts when the above
    126    * transmit ends, it is easier to implement it in the polling timeout of
    127    * receive.
    128    */
    129   return 0;
    130 }
    131 
    132 int teq1_receive(struct EseInterface *ese,
    133                  const struct Teq1ProtocolOptions *opts, float timeout,
    134                  struct Teq1Frame *frame) {
    135   /* Poll the bus until we see the start of frame indicator, the interface NAD.
    136    */
    137   int bytes_consumed = ese->ops->poll(ese, opts->host_address, timeout, 0);
    138   if (bytes_consumed < 0 || bytes_consumed > 1) {
    139     /* Timed out or comm error. */
    140     ALOGV("%s: comm error: %d", __func__, bytes_consumed);
    141     return -1;
    142   }
    143   /* We polled for the NAD above -- if it was consumed, set it here. */
    144   if (bytes_consumed) {
    145     frame->header.NAD = opts->host_address;
    146   }
    147   /* Get the remainder of the header, but keep the line &open. */
    148   ese->ops->hw_receive(ese, (uint8_t *)(&frame->header.NAD + bytes_consumed),
    149                        sizeof(frame->header) - bytes_consumed, 0);
    150   teq1_dump_receive((uint8_t *)(&frame->header.NAD + bytes_consumed),
    151                     sizeof(frame->header) - bytes_consumed);
    152   if (frame->header.LEN == 255) {
    153     ALOGV("received invalid LEN of 255");
    154     /* Close the receive window and return failure. */
    155     ese->ops->hw_receive(ese, NULL, 0, 1);
    156     return -1;
    157   }
    158   /*
    159    * Get the data and the first byte of CRC data.
    160    * Note, CRC support is not implemented. Only a single LRC byte is expected.
    161    */
    162   ese->ops->hw_receive(ese, (uint8_t *)(&(frame->INF[0])),
    163                        frame->header.LEN + 1, 1);
    164   teq1_dump_receive((uint8_t *)(&(frame->INF[0])), frame->header.LEN + 1);
    165   teq1_trace_receive(frame->header.PCB, frame->header.LEN);
    166 
    167   /*
    168    * If the card does something weird, like expect an CRC/LRC based on a
    169    * different
    170    * header value, the preprocessing should fix up here prior to the LRC check.
    171    */
    172   if (opts->preprocess) {
    173     opts->preprocess(opts, frame, 0);
    174   }
    175 
    176   /* LRC and other protocol goodness checks are not done here. */
    177   return frame->header.LEN; /* Return data bytes read. */
    178 }
    179 
    180 uint8_t teq1_fill_info_block(struct Teq1State *state, struct Teq1Frame *frame) {
    181   uint32_t inf_len = INF_LEN;
    182   if (state->ifs < inf_len) {
    183     inf_len = state->ifs;
    184   }
    185   switch (bs_get(PCB.type, frame->header.PCB)) {
    186   case kPcbTypeInfo0:
    187   case kPcbTypeInfo1: {
    188     uint32_t len = state->app_data.tx_total;
    189     uint32_t copied = 0;
    190     if (len > inf_len) {
    191       len = inf_len;
    192     }
    193     copied = ese_sg_to_buf(state->app_data.tx, state->app_data.tx_count,
    194                            state->app_data.tx_offset, len, frame->INF);
    195     if (copied != len) {
    196       ALOGE("Failed to copy %x bytes of app data for transmission",
    197             frame->header.LEN);
    198       /* TODO(wad): This return code is largely ignored. Is the precondition
    199        * checking elsewhere enough? */
    200       return 255;
    201     }
    202     frame->header.LEN = (len & 0xff);
    203     ALOGV("Copying %x bytes of app data for transmission", frame->header.LEN);
    204     /* Incrementing here means the caller MUST handle retransmit with prepared
    205      * data. */
    206     state->app_data.tx_offset += copied;
    207     state->app_data.tx_total -= copied;
    208     /* Perform chained transmission if needed. */
    209     bs_assign(&frame->header.PCB, PCB.I.more_data, 0);
    210     if (state->app_data.tx_total > 0) {
    211       frame->header.PCB |= bs_mask(PCB.I.more_data, 1);
    212     }
    213     return len;
    214   }
    215   case kPcbTypeSupervisory:
    216   case kPcbTypeReceiveReady:
    217   default:
    218     break;
    219   }
    220   return 255; /* Invalid block type. */
    221 }
    222 
    223 void teq1_get_app_data(struct Teq1State *state, const struct Teq1Frame *frame) {
    224   switch (bs_get(PCB.type, frame->header.PCB)) {
    225   case kPcbTypeInfo0:
    226   case kPcbTypeInfo1: {
    227     uint32_t len = frame->header.LEN;
    228     /* TODO(wad): Some data will be left on the table. Should this error out? */
    229     if (len > state->app_data.rx_total) {
    230       len = state->app_data.rx_total;
    231     }
    232     ese_sg_from_buf(state->app_data.rx, state->app_data.rx_count,
    233                     state->app_data.rx_offset, len, frame->INF);
    234     /* The original caller must retain the starting pointer to determine
    235      * actual available data.
    236      */
    237     state->app_data.rx_total -= len;
    238     state->app_data.rx_offset += len;
    239     return;
    240   }
    241   case kPcbTypeReceiveReady:
    242   case kPcbTypeSupervisory:
    243   default:
    244     break;
    245   }
    246   return;
    247 }
    248 
    249 /* Returns an R(0) frame with error bits set. */
    250 uint8_t teq1_frame_error_check(struct Teq1State *state,
    251                                struct Teq1Frame *tx_frame,
    252                                struct Teq1Frame *rx_frame) {
    253   uint8_t lrc = 0;
    254   int chained = 0;
    255   if (rx_frame->header.PCB == 255) {
    256     return R(0, 1, 0); /* Other error */
    257   }
    258 
    259   lrc = teq1_compute_LRC(rx_frame);
    260   if (rx_frame->INF[rx_frame->header.LEN] != lrc) {
    261     ALOGE("Invalid LRC %x instead of %x", rx_frame->INF[rx_frame->header.LEN],
    262           lrc);
    263     return R(0, 0, 1); /* Parity error */
    264   }
    265 
    266   /* Check if we were chained and increment the last sent sequence. */
    267   switch (bs_get(PCB.type, tx_frame->header.PCB)) {
    268   case kPcbTypeInfo0:
    269   case kPcbTypeInfo1:
    270     chained = bs_get(PCB.I.more_data, tx_frame->header.PCB);
    271     state->card_state->seq.interface =
    272         bs_get(PCB.I.send_seq, tx_frame->header.PCB);
    273   }
    274 
    275   /* Check if we've gone down an easy to catch error hole. The rest will turn up
    276    * on the
    277    * txrx switch.
    278    */
    279   switch (bs_get(PCB.type, rx_frame->header.PCB)) {
    280   case kPcbTypeSupervisory:
    281     if (rx_frame->header.PCB != S(RESYNC, RESPONSE) &&
    282         rx_frame->header.LEN != 1) {
    283       ALOGE("Invalid supervisory RX frame.");
    284       return R(0, 1, 0);
    285     }
    286     break;
    287   case kPcbTypeReceiveReady:
    288     if (rx_frame->header.LEN != 0) {
    289       ALOGE("Invalid ReceiveReady RX frame.");
    290       return R(0, 1, 0);
    291     }
    292     break;
    293   case kPcbTypeInfo0:
    294   case kPcbTypeInfo1:
    295     /* I-blocks must always alternate for each endpoint. */
    296     if ((bs_get(PCB.I.send_seq, rx_frame->header.PCB)) ==
    297         state->card_state->seq.card) {
    298       ALOGW("Got seq %d expected %d",
    299             bs_get(PCB.I.send_seq, rx_frame->header.PCB),
    300             state->card_state->seq.card);
    301       ALOGE("Invalid Info RX frame.");
    302       return R(0, 1, 0);
    303     }
    304     /* Update the card's last I-block seq. */
    305     state->card_state->seq.card = bs_get(PCB.I.send_seq, rx_frame->header.PCB);
    306   default:
    307     break;
    308   };
    309   return 0;
    310 }
    311 
    312 enum RuleResult teq1_rules(struct Teq1State *state, struct Teq1Frame *tx_frame,
    313                            struct Teq1Frame *rx_frame,
    314                            struct Teq1Frame *next_tx) {
    315   /* Rule 1 is enforced by first call Start with I(0,M). */
    316   /* 0 = TX, 1 = RX */
    317   /* msb = tx pcb, lsb = rx pcb */
    318   /* BUG_ON(!rx_frame && !tx_frame && !next_tx); */
    319   uint16_t txrx = TEQ1_RULE(tx_frame->header.PCB, rx_frame->header.PCB);
    320   uint8_t R_err;
    321 
    322   while (1) {
    323     /* Timeout errors come like invalid frames: 255. */
    324     if ((R_err = teq1_frame_error_check(state, tx_frame, rx_frame)) != 0) {
    325       ALOGW("incoming frame failed the error check");
    326       state->last_error_message = "Invalid frame received";
    327       /* Mark the frame as bad for our rule evaluation. */
    328       txrx = TEQ1_RULE(tx_frame->header.PCB, 255);
    329       state->errors++;
    330       /* Rule 6.4 */
    331       if (state->errors >= 6) {
    332         return kRuleResultResetDevice;
    333       }
    334       /* Rule 7.4.2 */
    335       if (state->errors >= 3) {
    336         /* Rule 7.4.1: state should start with error count = 2 */
    337         if (tx_frame->header.PCB != S(RESYNC, REQUEST)) {
    338           next_tx->header.PCB = S(RESYNC, REQUEST);
    339           return kRuleResultContinue;
    340         }
    341         return kRuleResultRetransmit;
    342       }
    343     }
    344 
    345     /* Specific matches */
    346     switch (txrx) {
    347     /*** Rule 2.1: I() -> I() ***/
    348     /* Error check will determine if the card seq is right. */
    349     case TEQ1_RULE(I(0, 0), I(0, 0)):
    350     case TEQ1_RULE(I(0, 0), I(1, 0)):
    351     case TEQ1_RULE(I(1, 0), I(1, 0)):
    352     case TEQ1_RULE(I(1, 0), I(0, 0)):
    353       /* Read app data & return. */
    354       teq1_get_app_data(state, rx_frame);
    355       return kRuleResultComplete;
    356 
    357     /* Card begins chained response. */
    358     case TEQ1_RULE(I(0, 0), I(0, 1)):
    359     case TEQ1_RULE(I(1, 0), I(1, 1)):
    360       /* Prep R(N(S)) */
    361       teq1_get_app_data(state, rx_frame);
    362       next_tx->header.PCB =
    363           TEQ1_R(!bs_get(PCB.I.send_seq, rx_frame->header.PCB), 0, 0);
    364       next_tx->header.LEN = 0;
    365       return kRuleResultContinue;
    366 
    367     /*** Rule 2.2, Rule 5: Chained transmission ***/
    368     case TEQ1_RULE(I(0, 1), R(1, 0, 0)):
    369     case TEQ1_RULE(I(1, 1), R(0, 0, 0)):
    370       /* Send next block -- error-checking assures the R seq is our next seq. */
    371       next_tx->header.PCB =
    372           TEQ1_I(bs_get(PCB.R.next_seq, rx_frame->header.PCB), 0);
    373       teq1_fill_info_block(state, next_tx); /* Sets M-bit and LEN. */
    374       return kRuleResultContinue;
    375 
    376     /*** Rule 3 ***/
    377     case TEQ1_RULE(I(0, 0), S(WTX, REQUEST)):
    378     case TEQ1_RULE(I(1, 0), S(WTX, REQUEST)):
    379       /* Note: Spec is unclear on if WTX can occur during chaining so we make it
    380       an error for now.
    381       case TEQ1_RULE(I(0, 1), S(WTX, REQUEST)):
    382       case TEQ1_RULE(I(1, 1), S(WTX, REQUEST)):
    383       */
    384       /* Send S(WTX, RESPONSE) with same INF */
    385       next_tx->header.PCB = S(WTX, RESPONSE);
    386       next_tx->header.LEN = 1;
    387       next_tx->INF[0] = rx_frame->INF[0];
    388       state->wait_mult = rx_frame->INF[0];
    389       /* Then wait BWT*INF[0] after transmission. */
    390       return kRuleResultSingleShot; /* Send then call back in with same tx_frame
    391                                        and new rx_frame. */
    392 
    393     /*** Rule 4 ***/
    394     case TEQ1_RULE(S(IFS, REQUEST), S(IFS, RESPONSE)):
    395       /* XXX: Check INFs match. */
    396       return kRuleResultComplete; /* This is treated as an unique operation. */
    397     case TEQ1_RULE(I(0, 0), S(IFS, REQUEST)):
    398     case TEQ1_RULE(I(0, 1), S(IFS, REQUEST)):
    399     case TEQ1_RULE(I(1, 0), S(IFS, REQUEST)):
    400     case TEQ1_RULE(I(1, 1), S(IFS, REQUEST)):
    401     /* Don't support a IFS_REQUEST if we sent an error R-block. */
    402     case TEQ1_RULE(R(0, 0, 0), S(IFS, REQUEST)):
    403     case TEQ1_RULE(R(1, 0, 0), S(IFS, REQUEST)):
    404       next_tx->header.PCB = S(IFS, RESPONSE);
    405       next_tx->header.LEN = 1;
    406       next_tx->INF[0] = rx_frame->INF[0];
    407       state->ifs = rx_frame->INF[0];
    408       return kRuleResultSingleShot;
    409 
    410     /*** Rule 5  (see Rule 2.2 for the chained-tx side. ) ***/
    411     case TEQ1_RULE(R(0, 0, 0), I(0, 0)):
    412     case TEQ1_RULE(R(1, 0, 0), I(1, 0)):
    413       /* Chaining ended with terminal I-block. */
    414       teq1_get_app_data(state, rx_frame);
    415       return kRuleResultComplete;
    416     case TEQ1_RULE(R(0, 0, 0), I(0, 1)):
    417     case TEQ1_RULE(R(1, 0, 0), I(1, 1)):
    418       /* Chaining continued; consume partial data and send R(N(S)) */
    419       teq1_get_app_data(state, rx_frame);
    420       /* The card seq bit will be tracked/validated earlier. */
    421       next_tx->header.PCB =
    422           TEQ1_R(!bs_get(PCB.I.send_seq, rx_frame->header.PCB), 0, 0);
    423       return kRuleResultContinue;
    424 
    425     /* Rule 6: Interface can send a RESYNC */
    426     /* Rule 6.1: timeout BWT right. No case here. */
    427     /* Rule 6.2, 6.3 */
    428     case TEQ1_RULE(S(RESYNC, REQUEST), S(RESYNC, RESPONSE)):
    429       /* Rule 6.5: indicates that the card should assume its prior
    430        * block was lost _and_ the interface gets transmit privilege,
    431        * so we just start fresh.
    432        */
    433       return kRuleResultResetSession; /* Start a new exchange (rule 6.3) */
    434     case TEQ1_RULE(S(RESYNC, REQUEST), 255):
    435       /* Retransmit the same frame up to 3 times. */
    436       return kRuleResultRetransmit;
    437 
    438     /* Rule 7.1, 7.5, 7.6 */
    439     case TEQ1_RULE(I(0, 0), 255):
    440     case TEQ1_RULE(I(1, 0), 255):
    441     case TEQ1_RULE(I(0, 1), 255):
    442     case TEQ1_RULE(I(1, 1), 255):
    443       next_tx->header.PCB = R_err;
    444       bs_assign(&next_tx->header.PCB, PCB.R.next_seq,
    445                 bs_get(PCB.I.send_seq, tx_frame->header.PCB));
    446       ALOGW("Rule 7.1,7.5,7.6: bad rx - sending error R: %x = %s",
    447             next_tx->header.PCB, teq1_pcb_to_name(next_tx->header.PCB));
    448       return kRuleResultSingleShot; /* So we still can retransmit the original.
    449                                        */
    450 
    451     /* Caught in the error check. */
    452     case TEQ1_RULE(I(0, 0), R(1, 0, 0)):
    453     case TEQ1_RULE(I(0, 0), R(1, 0, 1)):
    454     case TEQ1_RULE(I(0, 0), R(1, 1, 0)):
    455     case TEQ1_RULE(I(0, 0), R(1, 1, 1)):
    456     case TEQ1_RULE(I(1, 0), R(0, 0, 0)):
    457     case TEQ1_RULE(I(1, 0), R(0, 0, 1)):
    458     case TEQ1_RULE(I(1, 0), R(0, 1, 0)):
    459     case TEQ1_RULE(I(1, 0), R(0, 1, 1)):
    460       next_tx->header.PCB =
    461           TEQ1_R(bs_get(PCB.I.send_seq, tx_frame->header.PCB), 0, 0);
    462       ALOGW("Rule 7.1,7.5,7.6: weird rx - sending error R: %x = %s",
    463             next_tx->header.PCB, teq1_pcb_to_name(next_tx->header.PCB));
    464       return kRuleResultSingleShot;
    465 
    466     /* Rule 7.2: Retransmit the _same_ R-block. */
    467     /* The remainder of this rule is implemented in the next switch. */
    468     case TEQ1_RULE(R(0, 0, 0), 255):
    469     case TEQ1_RULE(R(0, 0, 1), 255):
    470     case TEQ1_RULE(R(0, 1, 0), 255):
    471     case TEQ1_RULE(R(0, 1, 1), 255):
    472     case TEQ1_RULE(R(1, 0, 0), 255):
    473     case TEQ1_RULE(R(1, 0, 1), 255):
    474     case TEQ1_RULE(R(1, 1, 0), 255):
    475     case TEQ1_RULE(R(1, 1, 1), 255):
    476       return kRuleResultRetransmit;
    477 
    478     /* Rule 7.3 request */
    479     /* Note, 7.3 for transmission of S(*, RESPONSE) won't be seen because they
    480      * are
    481      * single shots.
    482      * Instead, the invalid block will be handled as invalid for the prior TX.
    483      * This should yield the correct R-block.
    484      */
    485     case TEQ1_RULE(I(0, 0), R(0, 0, 0)):
    486     case TEQ1_RULE(I(0, 0), R(0, 0, 1)):
    487     case TEQ1_RULE(I(0, 0), R(0, 1, 0)):
    488     case TEQ1_RULE(I(0, 0), R(0, 1, 1)):
    489     case TEQ1_RULE(I(1, 0), R(1, 0, 0)):
    490     case TEQ1_RULE(I(1, 0), R(1, 1, 0)):
    491     case TEQ1_RULE(I(1, 0), R(1, 0, 1)):
    492     case TEQ1_RULE(I(1, 0), R(1, 1, 1)):
    493     case TEQ1_RULE(I(0, 1), R(0, 0, 0)):
    494     case TEQ1_RULE(I(0, 1), R(0, 1, 0)):
    495     case TEQ1_RULE(I(0, 1), R(0, 0, 1)):
    496     case TEQ1_RULE(I(0, 1), R(0, 1, 1)):
    497     case TEQ1_RULE(I(1, 1), R(1, 0, 0)):
    498     case TEQ1_RULE(I(1, 1), R(1, 1, 0)):
    499     case TEQ1_RULE(I(1, 1), R(1, 0, 1)):
    500     case TEQ1_RULE(I(1, 1), R(1, 1, 1)):
    501       /* Retransmit I-block */
    502       return kRuleResultRetransmit;
    503 
    504     /* Rule 8 is card only. */
    505     /* Rule 9: aborting a chain.
    506      * If a S(ABORT) is injected into this engine, then we may have sent an
    507      * abort.
    508      */
    509     case TEQ1_RULE(S(ABORT, REQUEST), S(ABORT, RESPONSE)):
    510       /* No need to send back a R() because we want to keep transmit. */
    511       return kRuleResultComplete; /* If we sent it, then we are complete. */
    512     case TEQ1_RULE(S(ABORT, RESPONSE), R(0, 0, 0)):
    513     case TEQ1_RULE(S(ABORT, RESPONSE), R(1, 0, 0)):
    514       /* Card triggered abortion complete but we can resume sending. */
    515       return kRuleResultAbort;
    516     /* An abort request can interrupt a chain anywhere and could occur
    517      * after a failure path too.
    518      */
    519     case TEQ1_RULE(I(0, 1), S(ABORT, REQUEST)):
    520     case TEQ1_RULE(I(1, 1), S(ABORT, REQUEST)):
    521     case TEQ1_RULE(R(0, 0, 0), S(ABORT, REQUEST)):
    522     case TEQ1_RULE(R(0, 0, 1), S(ABORT, REQUEST)):
    523     case TEQ1_RULE(R(0, 1, 0), S(ABORT, REQUEST)):
    524     case TEQ1_RULE(R(0, 1, 1), S(ABORT, REQUEST)):
    525     case TEQ1_RULE(R(1, 0, 0), S(ABORT, REQUEST)):
    526     case TEQ1_RULE(R(1, 0, 1), S(ABORT, REQUEST)):
    527     case TEQ1_RULE(R(1, 1, 0), S(ABORT, REQUEST)):
    528     case TEQ1_RULE(R(1, 1, 1), S(ABORT, REQUEST)):
    529       next_tx->header.PCB = S(ABORT, REQUEST);
    530       return kRuleResultContinue; /* Takes over prior flow. */
    531     case TEQ1_RULE(S(ABORT, RESPONSE), 255):
    532       return kRuleResultRetransmit;
    533     /* Note, other blocks should be caught below. */
    534     default:
    535       break;
    536     }
    537 
    538     /* Note, only S(ABORT, REQUEST) and S(IFS, REQUEST) are supported
    539      * for transmitting to the card. Others will result in error
    540      * flows.
    541      *
    542      * For supported flows: If an operation was paused to
    543      * send it, the caller may then switch to that state and resume.
    544      */
    545     if (rx_frame->header.PCB != 255) {
    546       ALOGW("Unexpected frame. Marking error and re-evaluating.");
    547       rx_frame->header.PCB = 255;
    548       continue;
    549     }
    550 
    551     return kRuleResultHardFail;
    552   }
    553 }
    554 
    555 /*
    556  * TODO(wad): Consider splitting teq1_transcieve() into
    557  *   teq1_transcieve_init() and teq1_transceive_process_one()
    558  *   if testing becomes onerous given the loop below.
    559  */
    560 ESE_API uint32_t teq1_transceive(struct EseInterface *ese,
    561                                  const struct Teq1ProtocolOptions *opts,
    562                                  const struct EseSgBuffer *tx_bufs,
    563                                  uint8_t tx_segs, struct EseSgBuffer *rx_bufs,
    564                                  uint8_t rx_segs) {
    565   struct Teq1Frame tx_frame[2];
    566   struct Teq1Frame rx_frame;
    567   struct Teq1Frame *tx = &tx_frame[0];
    568   int active = 0;
    569   bool was_reset = false;
    570   bool needs_hw_reset = false;
    571   int session_resets = 0;
    572   bool done = false;
    573   enum RuleResult result = kRuleResultComplete;
    574   uint32_t rx_total = ese_sg_length(rx_bufs, rx_segs);
    575   struct Teq1CardState *card_state = (struct Teq1CardState *)(&ese->pad[0]);
    576   struct Teq1State init_state = TEQ1_INIT_STATE(
    577       tx_bufs, tx_segs, ese_sg_length(tx_bufs, tx_segs), rx_bufs, rx_segs,
    578       ese_sg_length(rx_bufs, rx_segs), card_state);
    579   struct Teq1State state = TEQ1_INIT_STATE(
    580       tx_bufs, tx_segs, ese_sg_length(tx_bufs, tx_segs), rx_bufs, rx_segs,
    581       ese_sg_length(rx_bufs, rx_segs), card_state);
    582 
    583   _static_assert(TEQ1HEADER_SIZE == sizeof(struct Teq1Header),
    584                  "Ensure compiler alignment/padding matches wire protocol.");
    585   _static_assert(TEQ1FRAME_SIZE == sizeof(struct Teq1Frame),
    586                  "Ensure compiler alignment/padding matches wire protocol.");
    587 
    588   /* First I-block is always I(0, M). After that, modulo 2. */
    589   tx->header.PCB = TEQ1_I(!card_state->seq.interface, 0);
    590   teq1_fill_info_block(&state, tx);
    591 
    592   teq1_trace_header();
    593   while (!done) {
    594     /* Populates the node address and LRC prior to attempting to transmit. */
    595     teq1_transmit(ese, opts, tx);
    596 
    597     /* If tx was pointed to the inactive frame for a single shot, restore it
    598      * now. */
    599     tx = &tx_frame[active];
    600 
    601     /* Clear the RX frame. */
    602     ese_memset(&rx_frame, 0xff, sizeof(rx_frame));
    603 
    604     /* -1 indicates a timeout or failure from hardware. */
    605     if (teq1_receive(ese, opts, opts->bwt * (float)state.wait_mult, &rx_frame) <
    606         0) {
    607       /* TODO(wad): If the ese_error(ese) == 1, should this go ahead and fail?
    608        */
    609       /* Failures are considered invalid blocks in the rule engine below. */
    610       rx_frame.header.PCB = 255;
    611     }
    612     /* Always reset |wait_mult| once we have calculated the timeout. */
    613     state.wait_mult = 1;
    614 
    615     /* Clear the inactive frame header for use as |next_tx|. */
    616     ese_memset(&tx_frame[!active].header, 0, sizeof(tx_frame[!active].header));
    617 
    618     result = teq1_rules(&state, tx, &rx_frame, &tx_frame[!active]);
    619     ALOGV("[ %s ]", teq1_rule_result_to_name(result));
    620     switch (result) {
    621     case kRuleResultComplete:
    622       done = true;
    623       break;
    624     case kRuleResultRetransmit:
    625       /* TODO(wad) Find a clean way to move into teq1_rules(). */
    626       if (state.retransmits++ < 3) {
    627         continue;
    628       }
    629       ALOGE("More than three retransmits have occurred");
    630       if (tx->header.PCB == S(RESYNC, REQUEST)) {
    631         /* More than three RESYNC retranmits have occurred. */
    632         ese_set_error(ese, kTeq1ErrorHardFail);
    633         return 0;
    634       }
    635       /* Fall through */
    636       ALOGE("Triggering resynchronization.");
    637       tx_frame[!active].header.PCB = S(RESYNC, REQUEST);
    638     case kRuleResultContinue:
    639       active = !active;
    640       tx = &tx_frame[active];
    641       /* Reset this to 0 to use the counter for RESYNC transmits. */
    642       state.retransmits = 0;
    643       /* Errors are not reset until the session is reset. */
    644       continue;
    645     case kRuleResultHardFail:
    646       ese_set_error(ese, kTeq1ErrorHardFail);
    647       return 0;
    648     case kRuleResultAbort:
    649       ese_set_error(ese, kTeq1ErrorAbort);
    650       return 0;
    651     case kRuleResultSingleShot:
    652       /*
    653        * Send the next_tx on loop, but tell the rule engine that
    654        * the last sent state hasn't changed. This allows for easy error
    655        * and supervisory block paths without nesting state.
    656        */
    657       tx = &tx_frame[!active];
    658       continue;
    659     case kRuleResultResetDevice:
    660       needs_hw_reset = true;
    661     /* Fall through to session reset. */
    662     case kRuleResultResetSession:
    663       /* Reset to initial state and possibly do hw reset */
    664       if (session_resets++ > 4) {
    665         /* If there have been more than 4 resyncs without a
    666          * physical reset, we should pull the plug.
    667          */
    668         needs_hw_reset = true;
    669       }
    670       if (needs_hw_reset) {
    671         needs_hw_reset = false;
    672         if (was_reset || !ese->ops->hw_reset || ese->ops->hw_reset(ese) == -1) {
    673           ese_set_error(ese, kTeq1ErrorDeviceReset);
    674           return 0; /* Don't keep resetting -- hard fail. */
    675         }
    676         was_reset = true;
    677         session_resets = 0;
    678       }
    679       state = init_state;
    680       TEQ1_INIT_CARD_STATE(state.card_state);
    681       /* Reset the active frame. */
    682       ese_memset(tx, 0, sizeof(*tx));
    683       /* Load initial I-block. */
    684       tx->header.PCB = I(0, 0);
    685       teq1_fill_info_block(&state, tx);
    686       continue;
    687     }
    688   }
    689   /* Return the number of bytes used in the RX buffers. */
    690   return rx_total - state.app_data.rx_total;
    691 }
    692 
    693 ESE_API uint8_t teq1_compute_LRC(const struct Teq1Frame *frame) {
    694   uint8_t lrc = 0;
    695   const uint8_t *buffer = frame->val;
    696   const uint8_t *end = buffer + frame->header.LEN + sizeof(frame->header);
    697   while (buffer < end) {
    698     lrc ^= *buffer++;
    699   }
    700   return lrc;
    701 }
    702