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_len; 189 if (len > inf_len) { 190 len = inf_len; 191 } 192 ese_memcpy(frame->INF, state->app_data.tx_buf, len); 193 frame->header.LEN = (len & 0xff); 194 ALOGV("Copying %x bytes of app data for transmission", frame->header.LEN); 195 /* Incrementing here means the caller MUST handle retransmit with prepared 196 * data. */ 197 state->app_data.tx_len -= len; 198 state->app_data.tx_buf += len; 199 /* Perform chained transmission if needed. */ 200 bs_assign(&frame->header.PCB, PCB.I.more_data, 0); 201 if (state->app_data.tx_len > 0) { 202 frame->header.PCB |= bs_mask(PCB.I.more_data, 1); 203 } 204 return len; 205 } 206 case kPcbTypeSupervisory: 207 case kPcbTypeReceiveReady: 208 default: 209 break; 210 } 211 return 255; /* Invalid block type. */ 212 } 213 214 void teq1_get_app_data(struct Teq1State *state, struct Teq1Frame *frame) { 215 switch (bs_get(PCB.type, frame->header.PCB)) { 216 case kPcbTypeInfo0: 217 case kPcbTypeInfo1: { 218 uint8_t len = frame->header.LEN; 219 /* TODO(wad): Some data will be left on the table. Should this error out? */ 220 if (len > state->app_data.rx_len) { 221 len = state->app_data.rx_len; 222 } 223 ese_memcpy(state->app_data.rx_buf, frame->INF, len); 224 /* The original caller must retain the starting pointer to determine 225 * actual available data. 226 */ 227 state->app_data.rx_len -= len; 228 state->app_data.rx_buf += len; 229 return; 230 } 231 case kPcbTypeReceiveReady: 232 case kPcbTypeSupervisory: 233 default: 234 break; 235 } 236 return; 237 } 238 239 /* Returns an R(0) frame with error bits set. */ 240 uint8_t teq1_frame_error_check(struct Teq1State *state, 241 struct Teq1Frame *tx_frame, 242 struct Teq1Frame *rx_frame) { 243 uint8_t lrc = 0; 244 int chained = 0; 245 if (rx_frame->header.PCB == 255) { 246 return R(0, 1, 0); /* Other error */ 247 } 248 249 lrc = teq1_compute_LRC(rx_frame); 250 if (rx_frame->INF[rx_frame->header.LEN] != lrc) { 251 ALOGE("Invalid LRC %x instead of %x", rx_frame->INF[rx_frame->header.LEN], 252 lrc); 253 return R(0, 0, 1); /* Parity error */ 254 } 255 256 /* Check if we were chained and increment the last sent sequence. */ 257 switch (bs_get(PCB.type, tx_frame->header.PCB)) { 258 case kPcbTypeInfo0: 259 case kPcbTypeInfo1: 260 chained = bs_get(PCB.I.more_data, tx_frame->header.PCB); 261 state->card_state->seq.interface = 262 bs_get(PCB.I.send_seq, tx_frame->header.PCB); 263 } 264 265 /* Check if we've gone down an easy to catch error hole. The rest will turn up 266 * on the 267 * txrx switch. 268 */ 269 switch (bs_get(PCB.type, rx_frame->header.PCB)) { 270 case kPcbTypeSupervisory: 271 if (rx_frame->header.PCB != S(RESYNC, RESPONSE) && 272 rx_frame->header.LEN != 1) { 273 return R(0, 1, 0); 274 } 275 break; 276 case kPcbTypeReceiveReady: 277 if (rx_frame->header.LEN != 0) { 278 return R(0, 1, 0); 279 } 280 break; 281 case kPcbTypeInfo0: 282 case kPcbTypeInfo1: 283 /* I-blocks must always alternate for each endpoint. */ 284 if ((bs_get(PCB.I.send_seq, rx_frame->header.PCB)) == 285 state->card_state->seq.card) { 286 ALOGW("Got seq %d expected %d", 287 bs_get(PCB.I.send_seq, rx_frame->header.PCB), 288 state->card_state->seq.card); 289 return R(0, 1, 0); 290 } 291 /* Update the card's last I-block seq. */ 292 state->card_state->seq.card = bs_get(PCB.I.send_seq, rx_frame->header.PCB); 293 default: 294 break; 295 }; 296 return 0; 297 } 298 299 enum RuleResult teq1_rules(struct Teq1State *state, struct Teq1Frame *tx_frame, 300 struct Teq1Frame *rx_frame, 301 struct Teq1Frame *next_tx) { 302 /* Rule 1 is enforced by first call Start with I(0,M). */ 303 /* 0 = TX, 1 = RX */ 304 /* msb = tx pcb, lsb = rx pcb */ 305 /* BUG_ON(!rx_frame && !tx_frame && !next_tx); */ 306 uint16_t txrx = TEQ1_RULE(tx_frame->header.PCB, rx_frame->header.PCB); 307 uint8_t R_err; 308 309 while (1) { 310 /* Timeout errors come like invalid frames: 255. */ 311 if ((R_err = teq1_frame_error_check(state, tx_frame, rx_frame)) != 0) { 312 ALOGW("incoming frame failed the error check"); 313 state->last_error_message = "Invalid frame received"; 314 /* Mark the frame as bad for our rule evaluation. */ 315 txrx = TEQ1_RULE(tx_frame->header.PCB, 255); 316 state->errors++; 317 /* Rule 6.4 */ 318 if (state->errors >= 6) { 319 return kRuleResultResetDevice; 320 } 321 /* Rule 7.4.2 */ 322 if (state->errors >= 3) { 323 /* Rule 7.4.1: state should start with error count = 2 */ 324 next_tx->header.PCB = S(RESYNC, REQUEST); 325 /* Resync result in a fresh session, so we should just continue here. */ 326 return kRuleResultContinue; 327 } 328 } 329 330 /* Specific matches */ 331 switch (txrx) { 332 /*** Rule 2.1: I() -> I() ***/ 333 /* Error check will determine if the card seq is right. */ 334 case TEQ1_RULE(I(0, 0), I(0, 0)): 335 case TEQ1_RULE(I(0, 0), I(1, 0)): 336 case TEQ1_RULE(I(1, 0), I(1, 0)): 337 case TEQ1_RULE(I(1, 0), I(0, 0)): 338 /* Read app data & return. */ 339 teq1_get_app_data(state, rx_frame); 340 return kRuleResultComplete; 341 342 /* Card begins chained response. */ 343 case TEQ1_RULE(I(0, 0), I(0, 1)): 344 case TEQ1_RULE(I(1, 0), I(1, 1)): 345 /* Prep R(N(S)) */ 346 teq1_get_app_data(state, rx_frame); 347 next_tx->header.PCB = 348 TEQ1_R(!bs_get(PCB.I.send_seq, rx_frame->header.PCB), 0, 0); 349 next_tx->header.LEN = 0; 350 return kRuleResultContinue; 351 352 /*** Rule 2.2, Rule 5: Chained transmission ***/ 353 case TEQ1_RULE(I(0, 1), R(1, 0, 0)): 354 case TEQ1_RULE(I(1, 1), R(0, 0, 0)): 355 /* Send next block -- error-checking assures the R seq is our next seq. */ 356 next_tx->header.PCB = 357 TEQ1_I(bs_get(PCB.R.next_seq, rx_frame->header.PCB), 0); 358 teq1_fill_info_block(state, next_tx); /* Sets M-bit and LEN. */ 359 return kRuleResultContinue; 360 361 /*** Rule 3 ***/ 362 case TEQ1_RULE(I(0, 0), S(WTX, REQUEST)): 363 case TEQ1_RULE(I(1, 0), S(WTX, REQUEST)): 364 /* Note: Spec is unclear on if WTX can occur during chaining so we make it 365 an error for now. 366 case TEQ1_RULE(I(0, 1), S(WTX, REQUEST)): 367 case TEQ1_RULE(I(1, 1), S(WTX, REQUEST)): 368 */ 369 /* Send S(WTX, RESPONSE) with same INF */ 370 next_tx->header.PCB = S(WTX, RESPONSE); 371 next_tx->header.LEN = 1; 372 next_tx->INF[0] = rx_frame->INF[0]; 373 state->wait_mult = rx_frame->INF[0]; 374 /* Then wait BWT*INF[0] after transmission. */ 375 return kRuleResultSingleShot; /* Send then call back in with same tx_frame 376 and new rx_frame. */ 377 378 /*** Rule 4 ***/ 379 case TEQ1_RULE(S(IFS, REQUEST), S(IFS, RESPONSE)): 380 /* XXX: Check INFs match. */ 381 return kRuleResultComplete; /* This is treated as an unique operation. */ 382 case TEQ1_RULE(I(0, 0), S(IFS, REQUEST)): 383 case TEQ1_RULE(I(0, 1), S(IFS, REQUEST)): 384 case TEQ1_RULE(I(1, 0), S(IFS, REQUEST)): 385 case TEQ1_RULE(I(1, 1), S(IFS, REQUEST)): 386 /* Don't support a IFS_REQUEST if we sent an error R-block. */ 387 case TEQ1_RULE(R(0, 0, 0), S(IFS, REQUEST)): 388 case TEQ1_RULE(R(1, 0, 0), S(IFS, REQUEST)): 389 next_tx->header.PCB = S(IFS, RESPONSE); 390 next_tx->header.LEN = 1; 391 next_tx->INF[0] = rx_frame->INF[0]; 392 state->ifs = rx_frame->INF[0]; 393 return kRuleResultSingleShot; 394 395 /*** Rule 5 (see Rule 2.2 for the chained-tx side. ) ***/ 396 case TEQ1_RULE(R(0, 0, 0), I(0, 0)): 397 case TEQ1_RULE(R(1, 0, 0), I(1, 0)): 398 /* Chaining ended with terminal I-block. */ 399 teq1_get_app_data(state, rx_frame); 400 return kRuleResultComplete; 401 case TEQ1_RULE(R(0, 0, 0), I(0, 1)): 402 case TEQ1_RULE(R(1, 0, 0), I(1, 1)): 403 /* Chaining continued; consume partial data and send R(N(S)) */ 404 teq1_get_app_data(state, rx_frame); 405 /* The card seq bit will be tracked/validated earlier. */ 406 next_tx->header.PCB = 407 TEQ1_R(!bs_get(PCB.I.send_seq, rx_frame->header.PCB), 0, 0); 408 return kRuleResultContinue; 409 410 /* Rule 6: Interface can send a RESYNC */ 411 /* Rule 6.1: timeout BWT right. No case here. */ 412 /* Rule 6.2, 6.3 */ 413 case TEQ1_RULE(S(RESYNC, REQUEST), S(RESYNC, RESPONSE)): 414 /* Rule 6.5: indicates that the card should assume its prior 415 * block was lost _and_ the interface gets transmit privilege, 416 * so we just start fresh. 417 */ 418 return kRuleResultResetSession; /* Start a new exchange (rule 6.3) */ 419 case TEQ1_RULE(S(RESYNC, REQUEST), 255): 420 /* Retransmit the same frame up to 3 times. */ 421 return kRuleResultRetransmit; 422 423 /* Rule 7.1, 7.5, 7.6 */ 424 case TEQ1_RULE(I(0, 0), 255): 425 case TEQ1_RULE(I(1, 0), 255): 426 case TEQ1_RULE(I(0, 1), 255): 427 case TEQ1_RULE(I(1, 1), 255): 428 next_tx->header.PCB = R_err; 429 bs_assign(&next_tx->header.PCB, PCB.R.next_seq, 430 bs_get(PCB.I.send_seq, tx_frame->header.PCB)); 431 ALOGW("Rule 7.1,7.5,7.6: bad rx - sending error R: %x = %s", 432 next_tx->header.PCB, teq1_pcb_to_name(next_tx->header.PCB)); 433 return kRuleResultSingleShot; /* So we still can retransmit the original. 434 */ 435 436 /* Caught in the error check. */ 437 case TEQ1_RULE(I(0, 0), R(1, 0, 0)): 438 case TEQ1_RULE(I(0, 0), R(1, 0, 1)): 439 case TEQ1_RULE(I(0, 0), R(1, 1, 0)): 440 case TEQ1_RULE(I(0, 0), R(1, 1, 1)): 441 case TEQ1_RULE(I(1, 0), R(0, 0, 0)): 442 case TEQ1_RULE(I(1, 0), R(0, 0, 1)): 443 case TEQ1_RULE(I(1, 0), R(0, 1, 0)): 444 case TEQ1_RULE(I(1, 0), R(0, 1, 1)): 445 next_tx->header.PCB = 446 TEQ1_R(bs_get(PCB.I.send_seq, tx_frame->header.PCB), 0, 0); 447 ALOGW("Rule 7.1,7.5,7.6: weird rx - sending error R: %x = %s", 448 next_tx->header.PCB, teq1_pcb_to_name(next_tx->header.PCB)); 449 return kRuleResultSingleShot; 450 451 /* Rule 7.2: Retransmit the _same_ R-block. */ 452 /* The remainder of this rule is implemented in the next switch. */ 453 case TEQ1_RULE(R(0, 0, 0), 255): 454 case TEQ1_RULE(R(0, 0, 1), 255): 455 case TEQ1_RULE(R(0, 1, 0), 255): 456 case TEQ1_RULE(R(0, 1, 1), 255): 457 case TEQ1_RULE(R(1, 0, 0), 255): 458 case TEQ1_RULE(R(1, 0, 1), 255): 459 case TEQ1_RULE(R(1, 1, 0), 255): 460 case TEQ1_RULE(R(1, 1, 1), 255): 461 return kRuleResultRetransmit; 462 463 /* Rule 7.3 request */ 464 /* Note, 7.3 for transmission of S(*, RESPONSE) won't be seen because they 465 * are 466 * single shots. 467 * Instead, the invalid block will be handled as invalid for the prior TX. 468 * This should yield the correct R-block. 469 */ 470 case TEQ1_RULE(I(0, 0), R(0, 0, 0)): 471 case TEQ1_RULE(I(0, 0), R(0, 0, 1)): 472 case TEQ1_RULE(I(0, 0), R(0, 1, 0)): 473 case TEQ1_RULE(I(0, 0), R(0, 1, 1)): 474 case TEQ1_RULE(I(1, 0), R(1, 0, 0)): 475 case TEQ1_RULE(I(1, 0), R(1, 1, 0)): 476 case TEQ1_RULE(I(1, 0), R(1, 0, 1)): 477 case TEQ1_RULE(I(1, 0), R(1, 1, 1)): 478 case TEQ1_RULE(I(0, 1), R(0, 0, 0)): 479 case TEQ1_RULE(I(0, 1), R(0, 1, 0)): 480 case TEQ1_RULE(I(0, 1), R(0, 0, 1)): 481 case TEQ1_RULE(I(0, 1), R(0, 1, 1)): 482 case TEQ1_RULE(I(1, 1), R(1, 0, 0)): 483 case TEQ1_RULE(I(1, 1), R(1, 1, 0)): 484 case TEQ1_RULE(I(1, 1), R(1, 0, 1)): 485 case TEQ1_RULE(I(1, 1), R(1, 1, 1)): 486 /* Retransmit I-block */ 487 return kRuleResultRetransmit; 488 489 /* Rule 8 is card only. */ 490 /* Rule 9: aborting a chain. 491 * If a S(ABORT) is injected into this engine, then we may have sent an 492 * abort. 493 */ 494 case TEQ1_RULE(S(ABORT, REQUEST), S(ABORT, RESPONSE)): 495 /* No need to send back a R() because we want to keep transmit. */ 496 return kRuleResultComplete; /* If we sent it, then we are complete. */ 497 case TEQ1_RULE(S(ABORT, RESPONSE), R(0, 0, 0)): 498 case TEQ1_RULE(S(ABORT, RESPONSE), R(1, 0, 0)): 499 /* Card triggered abortion complete but we can resume sending. */ 500 return kRuleResultAbort; 501 /* An abort request can interrupt a chain anywhere and could occur 502 * after a failure path too. 503 */ 504 case TEQ1_RULE(I(0, 1), S(ABORT, REQUEST)): 505 case TEQ1_RULE(I(1, 1), S(ABORT, REQUEST)): 506 case TEQ1_RULE(R(0, 0, 0), S(ABORT, REQUEST)): 507 case TEQ1_RULE(R(0, 0, 1), S(ABORT, REQUEST)): 508 case TEQ1_RULE(R(0, 1, 0), S(ABORT, REQUEST)): 509 case TEQ1_RULE(R(0, 1, 1), S(ABORT, REQUEST)): 510 case TEQ1_RULE(R(1, 0, 0), S(ABORT, REQUEST)): 511 case TEQ1_RULE(R(1, 0, 1), S(ABORT, REQUEST)): 512 case TEQ1_RULE(R(1, 1, 0), S(ABORT, REQUEST)): 513 case TEQ1_RULE(R(1, 1, 1), S(ABORT, REQUEST)): 514 next_tx->header.PCB = S(ABORT, REQUEST); 515 return kRuleResultContinue; /* Takes over prior flow. */ 516 case TEQ1_RULE(S(ABORT, RESPONSE), 255): 517 return kRuleResultRetransmit; 518 /* Note, other blocks should be caught below. */ 519 default: 520 break; 521 } 522 523 /* Note, only S(ABORT, REQUEST) and S(IFS, REQUEST) are supported 524 * for transmitting to the card. Others will result in error 525 * flows. 526 * 527 * For supported flows: If an operation was paused to 528 * send it, the caller may then switch to that state and resume. 529 */ 530 if (rx_frame->header.PCB != 255) { 531 ALOGW("Unexpected frame. Marking error and re-evaluating."); 532 rx_frame->header.PCB = 255; 533 continue; 534 } 535 536 return kRuleResultHardFail; 537 } 538 } 539 540 /* 541 * TODO(wad): Consider splitting teq1_transcieve() into 542 * teq1_transcieve_init() and teq1_transceive_process_one() 543 * if testing becomes onerous given the loop below. 544 */ 545 546 API uint32_t teq1_transceive(struct EseInterface *ese, 547 const struct Teq1ProtocolOptions *opts, 548 const uint8_t *const tx_buf, uint32_t tx_len, 549 uint8_t *rx_buf, uint32_t rx_len) { 550 struct Teq1Frame tx_frame[2]; 551 struct Teq1Frame rx_frame; 552 struct Teq1Frame *tx = &tx_frame[0]; 553 int active = 0; 554 bool was_reset = false; 555 bool done = false; 556 enum RuleResult result = kRuleResultComplete; 557 struct Teq1CardState *card_state = (struct Teq1CardState *)(&ese->pad[0]); 558 struct Teq1State init_state = 559 TEQ1_INIT_STATE(tx_buf, tx_len, rx_buf, rx_len, card_state); 560 struct Teq1State state = 561 TEQ1_INIT_STATE(tx_buf, tx_len, rx_buf, rx_len, card_state); 562 563 _static_assert(TEQ1HEADER_SIZE == sizeof(struct Teq1Header), 564 "Ensure compiler alignment/padding matches wire protocol."); 565 _static_assert(TEQ1FRAME_SIZE == sizeof(struct Teq1Frame), 566 "Ensure compiler alignment/padding matches wire protocol."); 567 568 /* First I-block is always I(0, M). After that, modulo 2. */ 569 tx->header.PCB = TEQ1_I(!card_state->seq.interface, 0); 570 teq1_fill_info_block(&state, tx); 571 572 teq1_trace_header(); 573 while (!done) { 574 /* Populates the node address and LRC prior to attempting to transmit. */ 575 teq1_transmit(ese, opts, tx); 576 577 /* If tx was pointed to the inactive frame for a single shot, restore it 578 * now. */ 579 tx = &tx_frame[active]; 580 581 /* Clear the RX frame. */ 582 ese_memset(&rx_frame, 0xff, sizeof(rx_frame)); 583 584 /* -1 indicates a timeout or failure from hardware. */ 585 if (teq1_receive(ese, opts, opts->bwt * (float)state.wait_mult, &rx_frame) < 586 0) { 587 /* TODO(wad): If the ese_error(ese) == 1, should this go ahead and fail? 588 */ 589 /* Failures are considered invalid blocks in the rule engine below. */ 590 rx_frame.header.PCB = 255; 591 } 592 /* Always reset |wait_mult| once we have calculated the timeout. */ 593 state.wait_mult = 1; 594 595 /* Clear the inactive frame header for use as |next_tx|. */ 596 ese_memset(&tx_frame[!active].header, 0, sizeof(tx_frame[!active].header)); 597 598 result = teq1_rules(&state, tx, &rx_frame, &tx_frame[!active]); 599 ALOGV("[ %s ]", teq1_rule_result_to_name(result)); 600 switch (result) { 601 case kRuleResultComplete: 602 done = true; 603 break; 604 case kRuleResultRetransmit: 605 /* TODO(wad) Find a clean way to move into teq1_rules(). */ 606 if (state.retransmits++ < 3) { 607 continue; 608 } 609 if (tx->header.PCB == S(RESYNC, REQUEST)) { 610 ese_set_error(ese, kTeq1ErrorHardFail); 611 return 0; 612 } 613 /* Fall through */ 614 tx_frame[!active].header.PCB = S(RESYNC, REQUEST); 615 case kRuleResultContinue: 616 active = !active; 617 tx = &tx_frame[active]; 618 state.retransmits = 0; 619 state.errors = 0; 620 continue; 621 case kRuleResultHardFail: 622 ese_set_error(ese, kTeq1ErrorHardFail); 623 return 0; 624 case kRuleResultAbort: 625 ese_set_error(ese, kTeq1ErrorAbort); 626 return 0; 627 case kRuleResultSingleShot: 628 /* 629 * Send the next_tx on loop, but tell the rule engine that 630 * the last sent state hasn't changed. This allows for easy error 631 * and supervisory block paths without nesting state. 632 */ 633 tx = &tx_frame[!active]; 634 continue; 635 case kRuleResultResetDevice: 636 if (was_reset || !ese->ops->hw_reset || ese->ops->hw_reset(ese) == -1) { 637 ese_set_error(ese, kTeq1ErrorDeviceReset); 638 return 0; /* Don't keep resetting -- hard fail. */ 639 } 640 was_reset = true; 641 /* Fall through to session reset. */ 642 case kRuleResultResetSession: 643 /* Roll back state and reset. */ 644 state = init_state; 645 TEQ1_INIT_CARD_STATE(state.card_state); 646 /* Reset the active frame. */ 647 ese_memset(tx, 0, sizeof(*tx)); 648 /* Load initial I-block. */ 649 tx->header.PCB = I(0, 0); 650 teq1_fill_info_block(&state, tx); 651 continue; 652 } 653 } 654 /* Return the number of bytes used in rx_buf. */ 655 return rx_len - state.app_data.rx_len; 656 } 657 658 API uint8_t teq1_compute_LRC(const struct Teq1Frame *frame) { 659 uint8_t lrc = 0; 660 const uint8_t *buffer = frame->val; 661 const uint8_t *end = buffer + frame->header.LEN + sizeof(frame->header); 662 while (buffer < end) { 663 lrc ^= *buffer++; 664 } 665 return lrc; 666 } 667