Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
dcc_test_utils.hxx
1#ifndef _DCC_DCC_TEST_UTILS_HXX_
2#define _DCC_DCC_TEST_UTILS_HXX_
3
4#include "dcc/DccDebug.hxx"
5#include "dcc/Packet.hxx"
6
7void PrintTo(const DCCPacket &pkt, ::std::ostream *os)
8{
9 *os << dcc::packet_to_string(pkt);
10}
11
12namespace dcc
13{
14void PrintTo(const Packet &pkt, ::std::ostream *os)
15{
16 *os << packet_to_string(pkt);
17}
18}
19
20string PrintToString(const dcc::Packet &pkt)
21{
22 return dcc::packet_to_string(pkt);
23}
24
25std::vector<uint8_t> dcc_from(uint8_t d0, uint8_t d1, int d2 = -1, int d3 = -1, int d4 = -1)
26{
27 std::vector<uint8_t> ret;
28 ret.push_back(d0);
29 ret.push_back(d1);
30 if (d2 >= 0)
31 {
32 ret.push_back(d2);
33 }
34 else if (d2 == -2)
35 {
36 ret.push_back(d0 ^ d1);
37 }
38 if (d3 >= 0)
39 {
40 ret.push_back(d3);
41 }
42 else if (d3 == -2)
43 {
44 ret.push_back(d0 ^ d1 ^ ret[2]);
45 }
46 if (d4 >= 0)
47 {
48 ret.push_back(d4);
49 }
50 else if (d4 == -2)
51 {
52 ret.push_back(d0 ^ d1 ^ ret[2] ^ ret[3]);
53 }
54 return ret;
55}
56
57dcc::Packet packet_from(uint8_t hdr, std::vector<uint8_t> payload)
58{
59 dcc::Packet pkt;
60 pkt.header_raw_data = hdr;
61 pkt.dlc = payload.size();
62 memcpy(pkt.payload, &payload[0], pkt.dlc);
63 return pkt;
64}
65
66MATCHER_P2(PacketIs, hdr, payload, PrintToString(packet_from(hdr, payload)))
67{
68 dcc::Packet pkt = packet_from(hdr, payload);
69 dcc::Packet argc = arg;
70 vector<uint8_t> exp_bytes(pkt.payload, pkt.payload + pkt.dlc);
71 vector<uint8_t> act_bytes(arg.payload, arg.payload + arg.dlc);
72 if (pkt.packet_header.is_pkt == 0 && pkt.packet_header.is_marklin == 0 &&
73 arg.packet_header.is_pkt == 0 && arg.packet_header.is_marklin == 0 &&
74 pkt.packet_header.skip_ec != arg.packet_header.skip_ec)
75 {
76 // Mismatch in whether the EC byte is there. We fix this by adding the
77 // EC byte to the place where it is missing. This avoids test failures
78 // where the packets really are equivalent.
79 if (pkt.packet_header.skip_ec == 0)
80 {
81 uint8_t ec = 0;
82 for (uint8_t b : exp_bytes)
83 {
84 ec ^= b;
85 }
86 exp_bytes.push_back(ec);
87 pkt.packet_header.skip_ec = 1;
88 }
89 if (arg.packet_header.skip_ec == 0)
90 {
91 uint8_t ec = 0;
92 for (uint8_t b : act_bytes)
93 {
94 ec ^= b;
95 }
96 act_bytes.push_back(ec);
97 argc.packet_header.skip_ec = 1;
98 }
99 return (pkt.header_raw_data == argc.header_raw_data &&
100 exp_bytes == act_bytes);
101 }
102 return (pkt.header_raw_data == arg.header_raw_data && pkt.dlc == arg.dlc &&
103 memcmp(pkt.payload, arg.payload, pkt.dlc) == 0);
104}
105
106#endif // _DCC_DCC_TEST_UTILS_HXX_
string packet_to_string(const DCCPacket &pkt, bool bin_payload)
Renders a DCC packet as a debug string.
Definition DccDebug.cxx:43
uint8_t skip_ec
typically for DCC packets: 1: do NOT append an EC byte to the end of the packet.
Definition packet.h:66
uint8_t is_marklin
0: DCC packet, 1: motorola packet.
Definition packet.h:62
uint8_t is_pkt
Always 0.
Definition packet.h:60
Stores a DCC packet in memory.
Definition packet.h:55
uint8_t payload[DCC_PACKET_MAX_PAYLOAD]
Packet payload bytes.
Definition packet.h:97
uint8_t dlc
Specifies the number of used payload bytes.
Definition packet.h:95
Represents a command to be sent to the track driver.
Definition Packet.hxx:52