Skip to content

Commit e67f33a

Browse files
committed
test: cover ISO-DEP response chaining block sync
Signed-off-by: Zhibin (Ryan) Wen <wenzhibin@espressif.com>
1 parent 7c54e97 commit e67f33a

1 file changed

Lines changed: 116 additions & 0 deletions

File tree

test/isodep_test.cpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,98 @@
99
#include <gtest/gtest.h>
1010
#include <M5Unified.h>
1111
#include "nfc/isoDEP/isoDEP.hpp"
12+
#include "nfc/layer/nfc_layer.hpp"
13+
14+
#include <array>
15+
#include <cstdint>
16+
#include <cstring>
17+
#include <utility>
18+
#include <vector>
1219

1320
using namespace m5::nfc::isodep;
1421
using namespace m5::nfc::isodep::detail;
1522

23+
namespace {
24+
25+
class ScriptedLayer : public m5::nfc::NFCLayerInterface {
26+
public:
27+
explicit ScriptedLayer(std::vector<std::vector<uint8_t>> responses) : _responses{std::move(responses)}
28+
{
29+
}
30+
31+
uint16_t maximum_fifo_depth() const override
32+
{
33+
return MAX_FRAME_SIZE;
34+
}
35+
36+
bool transceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len, const uint32_t) override
37+
{
38+
_requests.emplace_back(tx, tx + tx_len);
39+
if (_response_index >= _responses.size() || rx_len < _responses[_response_index].size()) {
40+
return false;
41+
}
42+
const auto& response = _responses[_response_index++];
43+
memcpy(rx, response.data(), response.size());
44+
rx_len = static_cast<uint16_t>(response.size());
45+
return true;
46+
}
47+
48+
bool receive(uint8_t*, uint16_t&, const uint32_t) override
49+
{
50+
return false;
51+
}
52+
bool read(uint8_t*, uint16_t&, const uint16_t) override
53+
{
54+
return false;
55+
}
56+
bool write(const uint16_t, const uint8_t*, const uint16_t) override
57+
{
58+
return false;
59+
}
60+
uint16_t first_user_block() const override
61+
{
62+
return 0;
63+
}
64+
uint16_t last_user_block() const override
65+
{
66+
return 0;
67+
}
68+
uint16_t user_area_size() const override
69+
{
70+
return 0;
71+
}
72+
uint16_t unit_size_read() const override
73+
{
74+
return 0;
75+
}
76+
uint16_t unit_size_write() const override
77+
{
78+
return 0;
79+
}
80+
81+
const std::vector<std::vector<uint8_t>>& requests() const
82+
{
83+
return _requests;
84+
}
85+
86+
private:
87+
std::vector<std::vector<uint8_t>> _responses;
88+
std::vector<std::vector<uint8_t>> _requests;
89+
size_t _response_index{};
90+
};
91+
92+
config_t test_config()
93+
{
94+
config_t cfg{};
95+
cfg.fsc = 64;
96+
cfg.pcd_max_frame_tx = 64;
97+
cfg.pcd_max_frame_rx = 64;
98+
cfg.rx_crc = false;
99+
return cfg;
100+
}
101+
102+
} // namespace
103+
16104
TEST(IsoDEP, FsciToFsc)
17105
{
18106
EXPECT_EQ(fsci_to_fsc(0), 16u);
@@ -104,3 +192,31 @@ TEST(IsoDEP, FwiToMs)
104192
EXPECT_GT(fwi_to_ms(0, 13.56e6f), 0u);
105193
EXPECT_GT(fwi_to_ms(5, 13.56e6f), 0u);
106194
}
195+
196+
TEST(IsoDEP, ResponseChainingUsesNextExpectedBlockNumberAndSyncsSession)
197+
{
198+
ScriptedLayer layer({{make_i_pcb(0, true, false, false), 0xAA},
199+
{make_i_pcb(1, false, false, false), 0xBB},
200+
{make_i_pcb(1, false, false, false), 0xCC}});
201+
IsoDEP iso_dep{layer, test_config()};
202+
203+
std::array<uint8_t, 8> rx{};
204+
uint16_t rx_len = rx.size();
205+
const std::array<uint8_t, 1> first_tx{0xCA};
206+
207+
ASSERT_TRUE(iso_dep.transceiveINF(rx.data(), rx_len, first_tx.data(), first_tx.size()));
208+
ASSERT_EQ(rx_len, 2u);
209+
EXPECT_EQ(rx[0], 0xAA);
210+
EXPECT_EQ(rx[1], 0xBB);
211+
212+
ASSERT_EQ(layer.requests().size(), 2u);
213+
EXPECT_EQ(layer.requests()[0][0], make_i_pcb(0, false, false, false));
214+
EXPECT_EQ(layer.requests()[1][0], make_r_ack(1, false));
215+
216+
rx_len = rx.size();
217+
const std::array<uint8_t, 1> second_tx{0xCB};
218+
ASSERT_TRUE(iso_dep.transceiveINF(rx.data(), rx_len, second_tx.data(), second_tx.size()));
219+
220+
ASSERT_EQ(layer.requests().size(), 3u);
221+
EXPECT_EQ(layer.requests()[2][0], make_i_pcb(0, false, false, false));
222+
}

0 commit comments

Comments
 (0)