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