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
teq1_rule_result_to_name(enum RuleResult result)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
teq1_pcb_to_name(uint8_t pcb)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
teq1_dump_buf(const char * prefix,const uint8_t * buf,uint32_t len)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
teq1_transmit(struct EseInterface * ese,const struct Teq1ProtocolOptions * opts,struct Teq1Frame * frame)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
teq1_receive(struct EseInterface * ese,const struct Teq1ProtocolOptions * opts,float timeout,struct Teq1Frame * frame)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
teq1_fill_info_block(struct Teq1State * state,struct Teq1Frame * frame)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
teq1_get_app_data(struct Teq1State * state,struct Teq1Frame * frame)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. */
teq1_frame_error_check(struct Teq1State * state,struct Teq1Frame * tx_frame,struct Teq1Frame * rx_frame)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
teq1_rules(struct Teq1State * state,struct Teq1Frame * tx_frame,struct Teq1Frame * rx_frame,struct Teq1Frame * next_tx)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
teq1_transceive(struct EseInterface * ese,const struct Teq1ProtocolOptions * opts,const uint8_t * const tx_buf,uint32_t tx_len,uint8_t * rx_buf,uint32_t rx_len)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
teq1_compute_LRC(const struct Teq1Frame * frame)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