• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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