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