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 * Tests a very simple end to end T=1 using the echo backend.
17 */
18
19 #include <string.h>
20
21 #include <vector>
22 #include <gtest/gtest.h>
23
24 #include <ese/ese.h>
25 #include <ese/teq1.h>
26 #define LOG_TAG "TEQ1_UNITTESTS"
27 #include <ese/log.h>
28
29 #include "ese_operations_interface.h"
30 #include "ese_operations_wrapper.h"
31
32 #include "teq1_private.h"
33
34 #define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
35
36 using ::testing::Test;
37
38 // TODO:
39 // - Unittests of each function
40 // - teq1_rules matches Annex A of ISO 7816-3
41
42 // Tests teq1_frame_error_check to avoid testing every combo that
43 // ends in 255 in the rule engine.
44 class Teq1FrameErrorCheck : public virtual Test {
45 public:
Teq1FrameErrorCheck()46 Teq1FrameErrorCheck() { }
~Teq1FrameErrorCheck()47 virtual ~Teq1FrameErrorCheck() { }
48
49 struct Teq1Frame tx_frame_, rx_frame_;
50 struct Teq1State state_;
51 struct Teq1CardState card_state_;
52 };
53
TEST_F(Teq1FrameErrorCheck,info_parity)54 TEST_F(Teq1FrameErrorCheck, info_parity) {
55 static const uint8_t kRxPCBs[] = {
56 TEQ1_I(0, 0),
57 TEQ1_I(1, 0),
58 TEQ1_I(0, 1),
59 TEQ1_I(1, 1),
60 255,
61 };
62 const uint8_t *pcb = &kRxPCBs[0];
63 /* The PCBs above are all valid for a sent unchained I block with advancing
64 * sequence #s.
65 */
66 tx_frame_.header.PCB = TEQ1_I(0, 0);
67 state_.card_state = &card_state_;
68 state_.card_state->seq.card = 1;
69 while (*pcb != 255) {
70 rx_frame_.header.PCB = *pcb;
71 rx_frame_.header.LEN = 2;
72 rx_frame_.INF[0] = 'A';
73 rx_frame_.INF[1] = 'B';
74 rx_frame_.INF[2] = teq1_compute_LRC(&rx_frame_);
75 EXPECT_EQ(0, teq1_frame_error_check(&state_, &tx_frame_, &rx_frame_)) << teq1_pcb_to_name(rx_frame_.header.PCB);
76 rx_frame_.INF[2] = teq1_compute_LRC(&rx_frame_) - 1;
77 // Reset so we check the LRC error instead of a wrong seq.
78 state_.card_state->seq.card = !state_.card_state->seq.card;
79 EXPECT_EQ(TEQ1_R(0, 0, 1), teq1_frame_error_check(&state_, &tx_frame_, &rx_frame_));
80 state_.card_state->seq.card = !state_.card_state->seq.card;
81 pcb++;
82 }
83 };
84
TEST_F(Teq1FrameErrorCheck,length_mismatch)85 TEST_F(Teq1FrameErrorCheck, length_mismatch) {
86 };
87
TEST_F(Teq1FrameErrorCheck,unchained_r_block)88 TEST_F(Teq1FrameErrorCheck, unchained_r_block) {
89 };
90
TEST_F(Teq1FrameErrorCheck,unexpected_seq)91 TEST_F(Teq1FrameErrorCheck, unexpected_seq) {
92 };
93
94 class Teq1RulesTest : public virtual Test {
95 public:
Teq1RulesTest()96 Teq1RulesTest() :
97 tx_data_(INF_LEN, 'A'),
98 rx_data_(INF_LEN, 'B'),
99 tx_sg_({ .base = tx_data_.data(), .len = INF_LEN }),
100 rx_sg_({ .base = rx_data_.data(), .len = INF_LEN }),
101 card_state_({ .seq = { .card = 1, .interface = 1, }, }),
102 state_(TEQ1_INIT_STATE(&tx_sg_, 1, INF_LEN,
103 &rx_sg_, 1, INF_LEN,
104 &card_state_)) {
105 memset(&tx_frame_, 0, sizeof(struct Teq1Frame));
106 memset(&tx_next_, 0, sizeof(struct Teq1Frame));
107 memset(&rx_frame_, 0, sizeof(struct Teq1Frame));
108 }
~Teq1RulesTest()109 virtual ~Teq1RulesTest() { }
SetUp()110 virtual void SetUp() {}
TearDown()111 virtual void TearDown() { }
112
113 struct Teq1Frame tx_frame_;
114 struct Teq1Frame tx_next_;
115 struct Teq1Frame rx_frame_;
116 std::vector<uint8_t> tx_data_;
117 std::vector<uint8_t> rx_data_;
118 struct EseSgBuffer tx_sg_;
119 struct EseSgBuffer rx_sg_;
120 struct Teq1CardState card_state_;
121 struct Teq1State state_;
122 };
123
124 class Teq1ErrorFreeTest : public Teq1RulesTest {
125 };
126
127 class Teq1ErrorHandlingTest : public Teq1RulesTest {
128 };
129
130 class Teq1CompleteTest : public Teq1ErrorFreeTest {
131 public:
SetUp()132 virtual void SetUp() {
133 tx_frame_.header.PCB = TEQ1_I(0, 0);
134 teq1_fill_info_block(&state_, &tx_frame_);
135 // Check that the tx_data was fully consumed.
136 EXPECT_EQ(0UL, state_.app_data.tx_total);
137
138 rx_frame_.header.PCB = TEQ1_I(0, 0);
139 rx_frame_.header.LEN = INF_LEN;
140 ASSERT_EQ(static_cast<unsigned long>(INF_LEN), tx_data_.size()); // Catch fixture changes.
141 // Supply TX data and make sure it overwrites RX data on consumption.
142 memcpy(rx_frame_.INF, tx_data_.data(), INF_LEN);
143 rx_frame_.INF[INF_LEN] = teq1_compute_LRC(&rx_frame_);
144 }
145
RunRules()146 virtual void RunRules() {
147 teq1_trace_header();
148 teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
149 teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
150
151 enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
152 EXPECT_EQ(0, state_.errors);
153 EXPECT_EQ(NULL, state_.last_error_message)
154 << "Last error: " << state_.last_error_message;
155 EXPECT_EQ(0, tx_next_.header.PCB)
156 << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
157 EXPECT_EQ(kRuleResultComplete, result)
158 << "Actual result name: " << teq1_rule_result_to_name(result);
159 }
160 };
161
TEST_F(Teq1CompleteTest,I00_I00_empty)162 TEST_F(Teq1CompleteTest, I00_I00_empty) {
163 // No data.
164 state_.app_data.tx_total = 0;
165 state_.app_data.rx_total = 0;
166 // Re-zero the prepared frames.
167 teq1_fill_info_block(&state_, &tx_frame_);
168 rx_frame_.header.LEN = 0;
169 rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
170 RunRules();
171 EXPECT_EQ(0U, rx_frame_.header.LEN);
172 };
173
TEST_F(Teq1CompleteTest,I00_I00_data)174 TEST_F(Teq1CompleteTest, I00_I00_data) {
175 RunRules();
176 // Ensure that the rx_frame data was copied out to rx_data.
177 EXPECT_EQ(0UL, state_.app_data.rx_total);
178 EXPECT_EQ(tx_data_, rx_data_);
179 };
180
TEST_F(Teq1CompleteTest,I10_I10_data)181 TEST_F(Teq1CompleteTest, I10_I10_data) {
182 tx_frame_.header.PCB = TEQ1_I(1, 0);
183 rx_frame_.header.PCB = TEQ1_I(0, 0);
184 rx_frame_.INF[INF_LEN] = teq1_compute_LRC(&rx_frame_);
185 RunRules();
186 // Ensure that the rx_frame data was copied out to rx_data.
187 EXPECT_EQ(INF_LEN, rx_frame_.header.LEN);
188 EXPECT_EQ(0UL, state_.app_data.rx_total);
189 EXPECT_EQ(tx_data_, rx_data_);
190 };
191
192 // Note, IFS is not tested as it is not supported on current hardware.
193
TEST_F(Teq1ErrorFreeTest,I00_WTX0_WTX1_data)194 TEST_F(Teq1ErrorFreeTest, I00_WTX0_WTX1_data) {
195 tx_frame_.header.PCB = TEQ1_I(0, 0);
196 teq1_fill_info_block(&state_, &tx_frame_);
197 // Check that the tx_data was fully consumed.
198 EXPECT_EQ(0UL, state_.app_data.tx_total);
199
200 rx_frame_.header.PCB = TEQ1_S_WTX(0);
201 rx_frame_.header.LEN = 1;
202 rx_frame_.INF[0] = 2; /* Wait x 2 */
203 rx_frame_.INF[1] = teq1_compute_LRC(&rx_frame_);
204
205 teq1_trace_header();
206 teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
207 teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
208
209 enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
210 teq1_trace_transmit(tx_next_.header.PCB, tx_next_.header.LEN);
211
212 EXPECT_EQ(0, state_.errors);
213 EXPECT_EQ(NULL, state_.last_error_message)
214 << "Last error: " << state_.last_error_message;
215 EXPECT_EQ(TEQ1_S_WTX(1), tx_next_.header.PCB)
216 << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
217 EXPECT_EQ(state_.wait_mult, 2);
218 EXPECT_EQ(state_.wait_mult, rx_frame_.INF[0]);
219 // Ensure the next call will use the original TX frame.
220 EXPECT_EQ(kRuleResultSingleShot, result)
221 << "Actual result name: " << teq1_rule_result_to_name(result);
222 };
223
224 class Teq1ErrorFreeChainingTest : public Teq1ErrorFreeTest {
225 public:
RunRules()226 virtual void RunRules() {
227 tx_data_.resize(oversized_data_len_, 'C');
228 const_cast<struct EseSgBuffer *>(state_.app_data.tx)->base = tx_data_.data();
229 const_cast<struct EseSgBuffer *>(state_.app_data.tx)->len = oversized_data_len_;
230 state_.app_data.tx_total = oversized_data_len_;
231 teq1_fill_info_block(&state_, &tx_frame_);
232 // Ensure More bit was set.
233 EXPECT_EQ(1, bs_get(PCB.I.more_data, tx_frame_.header.PCB));
234 // Check that the tx_data was fully consumed.
235 EXPECT_EQ(static_cast<uint32_t>(oversized_data_len_ - INF_LEN),
236 state_.app_data.tx_total);
237 // No one is checking the TX LRC since there is no card present.
238
239 rx_frame_.header.LEN = 0;
240 rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
241
242 teq1_trace_header();
243 teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
244 teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
245
246 enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
247 teq1_trace_transmit(tx_next_.header.PCB, tx_next_.header.LEN);
248 EXPECT_EQ(0, state_.errors);
249 EXPECT_EQ(NULL, state_.last_error_message)
250 << "Last error: " << state_.last_error_message;
251 EXPECT_EQ(kRuleResultContinue, result)
252 << "Actual result name: " << teq1_rule_result_to_name(result);
253 // Check that the tx_buf was drained already for the next frame.
254 // ...
255 EXPECT_EQ(static_cast<uint32_t>(oversized_data_len_ - (2 * INF_LEN)),
256 state_.app_data.tx_total);
257 // Belt and suspenders: make sure no RX buf was used.
258 EXPECT_EQ(rx_data_.size(), state_.app_data.rx_total);
259 }
260 int oversized_data_len_;
261 };
262
TEST_F(Teq1ErrorFreeChainingTest,I01_R1_I11_chaining)263 TEST_F(Teq1ErrorFreeChainingTest, I01_R1_I11_chaining) {
264 oversized_data_len_ = INF_LEN * 3;
265 tx_frame_.header.PCB = TEQ1_I(0, 0);
266 rx_frame_.header.PCB = TEQ1_R(1, 0, 0);
267 RunRules();
268 EXPECT_EQ(TEQ1_I(1, 1), tx_next_.header.PCB)
269 << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
270 };
271
TEST_F(Teq1ErrorFreeChainingTest,I11_R0_I01_chaining)272 TEST_F(Teq1ErrorFreeChainingTest, I11_R0_I01_chaining) {
273 oversized_data_len_ = INF_LEN * 3;
274 tx_frame_.header.PCB = TEQ1_I(1, 0);
275 rx_frame_.header.PCB = TEQ1_R(0, 0, 0);
276 RunRules();
277 EXPECT_EQ(TEQ1_I(0, 1), tx_next_.header.PCB)
278 << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
279 };
280
TEST_F(Teq1ErrorFreeChainingTest,I11_R0_I00_chaining)281 TEST_F(Teq1ErrorFreeChainingTest, I11_R0_I00_chaining) {
282 oversized_data_len_ = INF_LEN * 2; // Exactly 2 frames worth.
283 tx_frame_.header.PCB = TEQ1_I(1, 0);
284 rx_frame_.header.PCB = TEQ1_R(0, 0, 0);
285 RunRules();
286 EXPECT_EQ(TEQ1_I(0, 0), tx_next_.header.PCB)
287 << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
288 };
289
290 //
291 // Error handling tests
292 //
293 //
294
295 class Teq1Retransmit : public Teq1ErrorHandlingTest {
296 public:
SetUp()297 virtual void SetUp() {
298 // No data.
299 state_.app_data.rx_total = 0;
300 state_.app_data.tx_total = 0;
301
302 tx_frame_.header.PCB = TEQ1_I(0, 0);
303 teq1_fill_info_block(&state_, &tx_frame_);
304 // No one is checking the TX LRC since there is no card present.
305
306 // Assume the card may not even set the error bit.
307 rx_frame_.header.LEN = 0;
308 rx_frame_.header.PCB = TEQ1_R(0, 0, 0);
309 rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
310 }
TearDown()311 virtual void TearDown() {
312 teq1_trace_header();
313 teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
314 teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
315
316 enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
317 // Not counted as an error as it was on the card-side.
318 EXPECT_EQ(0, state_.errors);
319 const char *kNull = NULL;
320 EXPECT_EQ(kNull, state_.last_error_message) << state_.last_error_message;
321 EXPECT_EQ(kRuleResultRetransmit, result)
322 << "Actual result name: " << teq1_rule_result_to_name(result);
323 }
324 };
325
TEST_F(Teq1Retransmit,I00_R000_I00)326 TEST_F(Teq1Retransmit, I00_R000_I00) {
327 rx_frame_.header.PCB = TEQ1_R(0, 0, 0);
328 rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
329 };
330
TEST_F(Teq1Retransmit,I00_R001_I00)331 TEST_F(Teq1Retransmit, I00_R001_I00) {
332 rx_frame_.header.PCB = TEQ1_R(0, 0, 1);
333 rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
334 };
335
TEST_F(Teq1Retransmit,I00_R010_I00)336 TEST_F(Teq1Retransmit, I00_R010_I00) {
337 rx_frame_.header.PCB = TEQ1_R(0, 1, 0);
338 rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
339 };
340
TEST_F(Teq1Retransmit,I00_R011_I00)341 TEST_F(Teq1Retransmit, I00_R011_I00) {
342 rx_frame_.header.PCB = TEQ1_R(0, 1, 1);
343 rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
344 }
345
TEST_F(Teq1ErrorHandlingTest,I00_I00_bad_lrc)346 TEST_F(Teq1ErrorHandlingTest, I00_I00_bad_lrc) {
347 // No data.
348 state_.app_data.rx_total = 0;
349 state_.app_data.tx_total = 0;
350
351 tx_frame_.header.PCB = TEQ1_I(0, 0);
352 teq1_fill_info_block(&state_, &tx_frame_);
353 // No one is checking the TX LRC since there is no card present.
354
355 rx_frame_.header.PCB = TEQ1_I(0, 0);
356 rx_frame_.header.LEN = 0;
357 rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_) - 1;
358
359 teq1_trace_header();
360 teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
361 teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
362
363 enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
364 EXPECT_EQ(1, state_.errors);
365 const char *kNull = NULL;
366 EXPECT_NE(kNull, state_.last_error_message);
367 EXPECT_STREQ("Invalid frame received", state_.last_error_message);
368 EXPECT_EQ(TEQ1_R(0, 0, 1), tx_next_.header.PCB)
369 << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
370 EXPECT_EQ(kRuleResultSingleShot, result)
371 << "Actual result name: " << teq1_rule_result_to_name(result);
372 };
373
374 static const struct Teq1ProtocolOptions kTeq1Options = {
375 .host_address = 0xA5,
376 .node_address = 0x5A,
377 .bwt = 1.624f,
378 .etu = 0.00015f, /* elementary time unit, in seconds */
379 .preprocess = NULL,
380 };
381
to_hex(const std::vector<uint8_t> & data)382 std::string to_hex(const std::vector<uint8_t>& data) {
383 static constexpr char hex[] = "0123456789ABCDEF";
384 std::string out;
385 out.reserve(data.size() * 2);
386 for (uint8_t c : data) {
387 out.push_back(hex[c / 16]);
388 out.push_back(hex[c % 16]);
389 }
390 return out;
391 }
392
393 class EseWireFake : public EseOperationsInterface {
394 public:
EseWireFake()395 EseWireFake() : tx_cursor_(0), rx_cursor_(0) { }
396 virtual ~EseWireFake() = default;
397
EseOpen(struct EseInterface * UNUSED (ese),void * UNUSED (data))398 virtual int EseOpen(struct EseInterface *UNUSED(ese), void *UNUSED(data)) {
399 return 0;
400 }
EseReset(struct EseInterface * UNUSED (ese))401 virtual int EseReset(struct EseInterface *UNUSED(ese)) {
402 ALOGI("EseReset called!"); // Add to invocations
403 // Using the RX cursor, check for a reset expected.
404 // This is on RX because the s(resync) global counter is on session resets.
405 EXPECT_EQ(1, invocations.at(tx_cursor_).expect_reset);
406 return 0;
407 }
EsePoll(struct EseInterface * UNUSED (ese),uint8_t UNUSED (poll_for),float UNUSED (timeout),int UNUSED (complete))408 virtual int EsePoll(struct EseInterface *UNUSED(ese), uint8_t UNUSED(poll_for),
409 float UNUSED(timeout), int UNUSED(complete)) {
410 return 0;
411 }
EseClose(struct EseInterface * UNUSED (ese))412 virtual void EseClose(struct EseInterface *UNUSED(ese)) { };
413
EseTransceive(struct EseInterface * ese,const struct EseSgBuffer * tx_sg,uint32_t tx_nsg,struct EseSgBuffer * rx_sg,uint32_t rx_nsg)414 virtual uint32_t EseTransceive(struct EseInterface *ese, const struct EseSgBuffer *tx_sg, uint32_t tx_nsg,
415 struct EseSgBuffer *rx_sg, uint32_t rx_nsg) {
416 rx_cursor_ = 0;
417 return teq1_transceive(ese, &kTeq1Options, tx_sg, tx_nsg, rx_sg, rx_nsg);
418 }
419
EseHwTransmit(struct EseInterface * UNUSED (ese),const uint8_t * data,uint32_t len,int UNUSED (complete))420 virtual uint32_t EseHwTransmit(struct EseInterface *UNUSED(ese), const uint8_t *data,
421 uint32_t len, int UNUSED(complete)) {
422 EXPECT_GT(invocations.size(), tx_cursor_);
423 if (invocations.size() <= tx_cursor_) {
424 return 0;
425 }
426 if (!len) {
427 return 0;
428 }
429 if (!invocations.size()) {
430 return 0;
431 }
432 // Just called once per teq1_transmit -- no partials.
433 const struct Invocation &invocation = invocations.at(tx_cursor_++);
434
435 EXPECT_EQ(invocation.expected_tx.size(), len);
436 int eq = memcmp(data, invocation.expected_tx.data(), len);
437 const std::vector<uint8_t> vec_data(data, data + len);
438 EXPECT_EQ(0, eq)
439 << "Got: '" << to_hex(vec_data) << "' "
440 << "Expected: '" << to_hex(invocation.expected_tx) << "'";
441
442 return len;
443 }
444
EseHwReceive(struct EseInterface * UNUSED (ese),uint8_t * data,uint32_t len,int UNUSED (complete))445 virtual uint32_t EseHwReceive(struct EseInterface *UNUSED(ese), uint8_t *data,
446 uint32_t len, int UNUSED(complete)) {
447 if (!len) {
448 return 0;
449 }
450 // Get this calls expected data.
451 EXPECT_GT(invocations.size(), rx_cursor_);
452 if (!invocations.size())
453 return 0;
454 struct Invocation &invocation = invocations.at(rx_cursor_);
455
456 // Supply the golden return data and pop off the invocation.
457 // Allows partial reads from the invocation stack.
458 uint32_t rx_total = 0;
459 if (len <= invocation.rx.size()) {
460 rx_total = len;
461 memcpy(data, invocation.rx.data(), invocation.rx.size());
462 }
463 uint32_t remaining = invocation.rx.size() - rx_total;
464 if (remaining && rx_total) {
465 invocation.rx.erase(invocation.rx.begin(),
466 invocation.rx.begin() + rx_total);
467 } else {
468 rx_cursor_++;
469 // RX shouldn't get ahead of TX.
470 EXPECT_GE(tx_cursor_, rx_cursor_);
471 // We could delete, but this make test bugs a little easier to see.
472 }
473 return rx_total;
474 }
475
476 struct Invocation {
477 std::vector<uint8_t> rx;
478 std::vector<uint8_t> expected_tx;
479 int expect_reset;
480 };
481
482 std::vector<Invocation> invocations;
483 private:
484 uint32_t tx_cursor_;
485 uint32_t rx_cursor_;
486 };
487
488 class Teq1TransceiveTest : public virtual Test {
489 public:
Teq1TransceiveTest()490 Teq1TransceiveTest() { }
~Teq1TransceiveTest()491 virtual ~Teq1TransceiveTest() { }
492
SetUp()493 void SetUp() {
494 // Configure ese with our internal ops.
495 EseOperationsWrapper::InitializeEse(&ese_, &wire_);
496 // Start with normal seq's.
497 TEQ1_INIT_CARD_STATE((struct Teq1CardState *)(&(ese_.pad[0])));
498 }
499
TearDown()500 void TearDown() {
501 wire_.invocations.resize(0);
502 }
503
504 protected:
505 EseWireFake wire_;
506 EseInterface ese_;
507 };
508
509
TEST_F(Teq1TransceiveTest,NormalTransceiveUnchained)510 TEST_F(Teq1TransceiveTest, NormalTransceiveUnchained) {
511 EXPECT_EQ(0, ese_open(&ese_, NULL));
512
513 // I(0,0) ->
514 // <- I(0, 0)
515 wire_.invocations.resize(1);
516 struct Teq1Frame frame;
517 size_t frame_size = 0;
518 frame.header.NAD = kTeq1Options.node_address;
519 frame.header.PCB = TEQ1_I(0, 0);
520 frame.header.LEN = 4;
521 frame.INF[0] = 'A';
522 frame.INF[1] = 'B';
523 frame.INF[2] = 'C';
524 frame.INF[3] = 'D';
525 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
526 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
527 wire_.invocations[0].expected_tx.resize(frame_size);
528 memcpy(wire_.invocations[0].expected_tx.data(), &frame.val[0], frame_size);
529 ALOGI("Planning to send:");
530 teq1_trace_transmit(frame.header.PCB, frame.header.LEN);
531
532 frame.header.LEN = 0;
533 frame.header.NAD = kTeq1Options.host_address;
534 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
535 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
536 wire_.invocations[0].rx.resize(frame_size);
537 memcpy(wire_.invocations[0].rx.data(), &frame, frame_size);
538 ALOGI("Expecting to receive:");
539 teq1_trace_receive(frame.header.PCB, frame.header.LEN);
540
541 const uint8_t payload[] = { 'A', 'B', 'C', 'D' };
542 uint8_t reply[5]; // Should stay empty.
543 EXPECT_EQ(0, ese_transceive(&ese_, payload, sizeof(payload), reply, sizeof(reply)));
544 };
545
546
TEST_F(Teq1TransceiveTest,NormalUnchainedRetransmitRecovery)547 TEST_F(Teq1TransceiveTest, NormalUnchainedRetransmitRecovery) {
548 EXPECT_EQ(0, ese_open(&ese_, NULL));
549
550 // I(0,0) [4] ->
551 // <- R(0, 1, 0)
552 // I(0,0) [4] ->
553 // <- I(0, 0)
554 wire_.invocations.resize(2);
555 struct Teq1Frame frame;
556 size_t frame_size = 0;
557 frame.header.NAD = kTeq1Options.node_address;
558 frame.header.PCB = TEQ1_I(0, 0);
559 frame.header.LEN = 4;
560 frame.INF[0] = 'A';
561 frame.INF[1] = 'B';
562 frame.INF[2] = 'C';
563 frame.INF[3] = 'D';
564 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
565 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
566 wire_.invocations[0].expected_tx.resize(frame_size);
567 memcpy(wire_.invocations[0].expected_tx.data(), &frame.val[0], frame_size);
568 wire_.invocations[1].expected_tx.resize(frame_size);
569 memcpy(wire_.invocations[1].expected_tx.data(), &frame.val[0], frame_size);
570
571 frame.header.LEN = 0;
572 frame.header.NAD = kTeq1Options.host_address;
573 frame.header.PCB = TEQ1_R(0, 1, 0);
574 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
575 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
576 wire_.invocations[0].rx.resize(frame_size);
577 memcpy(wire_.invocations[0].rx.data(), &frame, frame_size);
578
579 frame.header.LEN = 0;
580 frame.header.NAD = kTeq1Options.host_address;
581 frame.header.PCB = TEQ1_I(0, 0);
582 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
583 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
584 wire_.invocations[1].rx.resize(frame_size);
585 memcpy(wire_.invocations[1].rx.data(), &frame, frame_size);
586
587 const uint8_t payload[] = { 'A', 'B', 'C', 'D' };
588 uint8_t reply[5]; // Should stay empty.
589 EXPECT_EQ(0, ese_transceive(&ese_, payload, sizeof(payload), reply, sizeof(reply)));
590 };
591
TEST_F(Teq1TransceiveTest,RetransmitResyncRecovery)592 TEST_F(Teq1TransceiveTest, RetransmitResyncRecovery) {
593 EXPECT_EQ(0, ese_open(&ese_, NULL));
594
595 // I(0,0) [4] ->
596 // <- R(0, 1, 0)
597 // I(0,0) [4] ->
598 // <- R(0, 1, 0)
599 // I(0,0) [4] ->
600 // <- R(0, 1, 0)
601 // I(0,0) [4] ->
602 // <- R(0, 1, 0)
603 // S(RESYNC, REQUEST) -> (retran this is another case)
604 // <- S(RESYNC, RESPONSE)
605 // I(0, 0) [4] ->
606 // <- I(0, 0) [0]
607 wire_.invocations.resize(6);
608 struct Teq1Frame frame;
609 size_t frame_size = 0;
610 frame.header.NAD = kTeq1Options.node_address;
611 frame.header.PCB = TEQ1_I(0, 0);
612 frame.header.LEN = 4;
613 frame.INF[0] = 'A';
614 frame.INF[1] = 'B';
615 frame.INF[2] = 'C';
616 frame.INF[3] = 'D';
617 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
618 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
619 wire_.invocations[0].expected_tx.resize(frame_size);
620 memcpy(wire_.invocations[0].expected_tx.data(), &frame.val[0], frame_size);
621 wire_.invocations[1].expected_tx.resize(frame_size);
622 memcpy(wire_.invocations[1].expected_tx.data(), &frame.val[0], frame_size);
623 wire_.invocations[2].expected_tx.resize(frame_size);
624 memcpy(wire_.invocations[2].expected_tx.data(), &frame.val[0], frame_size);
625 wire_.invocations[3].expected_tx.resize(frame_size);
626 memcpy(wire_.invocations[3].expected_tx.data(), &frame.val[0], frame_size);
627 wire_.invocations[5].expected_tx.resize(frame_size);
628 memcpy(wire_.invocations[5].expected_tx.data(), &frame.val[0], frame_size);
629
630 frame.header.LEN = 0;
631 frame.header.NAD = kTeq1Options.node_address;
632 frame.header.PCB = TEQ1_S_RESYNC(0);
633 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
634 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
635 wire_.invocations[4].expected_tx.resize(frame_size);
636 memcpy(wire_.invocations[4].expected_tx.data(), &frame, frame_size);
637
638 frame.header.LEN = 0;
639 frame.header.NAD = kTeq1Options.host_address;
640 frame.header.PCB = TEQ1_R(0, 1, 0);
641 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
642 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
643 wire_.invocations[0].rx.resize(frame_size);
644 memcpy(wire_.invocations[0].rx.data(), &frame, frame_size);
645 wire_.invocations[1].rx.resize(frame_size);
646 memcpy(wire_.invocations[1].rx.data(), &frame, frame_size);
647 wire_.invocations[2].rx.resize(frame_size);
648 memcpy(wire_.invocations[2].rx.data(), &frame, frame_size);
649 wire_.invocations[3].rx.resize(frame_size);
650 memcpy(wire_.invocations[3].rx.data(), &frame, frame_size);
651
652 frame.header.LEN = 0;
653 frame.header.NAD = kTeq1Options.host_address;
654 frame.header.PCB = TEQ1_S_RESYNC(1);
655 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
656 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
657 wire_.invocations[4].rx.resize(frame_size);
658 memcpy(wire_.invocations[4].rx.data(), &frame, frame_size);
659
660 frame.header.LEN = 0;
661 frame.header.NAD = kTeq1Options.host_address;
662 frame.header.PCB = TEQ1_I(0, 0);
663 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
664 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
665 wire_.invocations[5].rx.resize(frame_size);
666 memcpy(wire_.invocations[5].rx.data(), &frame, frame_size);
667
668 const uint8_t payload[] = { 'A', 'B', 'C', 'D' };
669 uint8_t reply[5]; // Should stay empty.
670 EXPECT_EQ(0, ese_transceive(&ese_, payload, sizeof(payload), reply, sizeof(reply)));
671 };
672
673 // Error case described in b/63546784
TEST_F(Teq1TransceiveTest,RetransmitResyncLoop)674 TEST_F(Teq1TransceiveTest, RetransmitResyncLoop) {
675 EXPECT_EQ(0, ese_open(&ese_, NULL));
676
677 // I(0,0) [4] ->
678 // <- R(0, 1, 0)
679 // I(0,0) [4] ->
680 // <- R(0, 1, 0)
681 // I(0,0) [4] ->
682 // <- R(0, 1, 0)
683 // I(0,0) [4] ->
684 // <- R(0, 1, 0)
685 // S(RESYNC, REQUEST) ->
686 // <- S(RESYNC, RESPONSE)
687 // I(0,0) [4] ->
688 // <- R(0, 1, 0)
689 // I(0,0) [4] ->
690 // <- R(0, 1, 0)
691 // I(0,0) [4] ->
692 // <- R(0, 1, 0)
693 // I(0,0) [4] ->
694 // <- R(0, 1, 0)
695 // S(RESYNC, REQUEST) ->
696 // <- S(RESYNC, RESPONSE)
697 // ...
698 // 6 failure loops before a reset then 6 more before a hard failure.
699 wire_.invocations.resize(5 * 12);
700 struct Teq1Frame frame;
701 size_t frame_size = 0;
702
703 frame.header.NAD = kTeq1Options.node_address;
704 frame.header.PCB = TEQ1_I(0, 0);
705 frame.header.LEN = 4;
706 frame.INF[0] = 'A';
707 frame.INF[1] = 'B';
708 frame.INF[2] = 'C';
709 frame.INF[3] = 'D';
710 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
711 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
712 // Initialize all invocations to I/R then overwrite with resyncs.
713 for (auto &invocation : wire_.invocations) {
714 invocation.expected_tx.resize(frame_size);
715 memcpy(invocation.expected_tx.data(), &frame.val[0], frame_size);
716 }
717
718 frame.header.LEN = 0;
719 frame.header.NAD = kTeq1Options.host_address;
720 frame.header.PCB = TEQ1_R(0, 1, 0);
721 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
722 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
723 for (auto &invocation : wire_.invocations) {
724 invocation.rx.resize(frame_size);
725 memcpy(invocation.rx.data(), &frame.val[0], frame_size);
726 }
727
728 frame.header.LEN = 0;
729 frame.header.NAD = kTeq1Options.node_address;
730 frame.header.PCB = TEQ1_S_RESYNC(0);
731 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
732 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
733 int count = 0;
734 for (auto &invocation : wire_.invocations) {
735 if (++count % 5 == 0) {
736 invocation.expected_tx.resize(frame_size);
737 memcpy(invocation.expected_tx.data(), &frame, frame_size);
738 }
739 }
740
741 frame.header.LEN = 0;
742 frame.header.NAD = kTeq1Options.host_address;
743 frame.header.PCB = TEQ1_S_RESYNC(1);
744 frame.INF[frame.header.LEN] = teq1_compute_LRC(&frame);
745 frame_size = sizeof(frame.header) + frame.header.LEN + 1;
746 count = 0;
747 for (auto &invocation : wire_.invocations) {
748 if (++count % 5 == 0) {
749 invocation.rx.resize(frame_size);
750 memcpy(invocation.rx.data(), &frame, frame_size);
751 }
752 }
753
754 wire_.invocations[30].expect_reset = 1;
755
756 const uint8_t payload[] = { 'A', 'B', 'C', 'D' };
757 uint8_t reply[5]; // Should stay empty.
758 EXPECT_EQ(-1, ese_transceive(&ese_, payload, sizeof(payload), reply, sizeof(reply)));
759 EXPECT_NE(0, ese_error(&ese_));
760 };
761
762
763