1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker *
4*84e33947SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker *
8*84e33947SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker *
10*84e33947SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker */
16*84e33947SAndroid Build Coastguard Worker
17*84e33947SAndroid Build Coastguard Worker #include "packet_util.h"
18*84e33947SAndroid Build Coastguard Worker
19*84e33947SAndroid Build Coastguard Worker #include "chpp/app.h"
20*84e33947SAndroid Build Coastguard Worker
21*84e33947SAndroid Build Coastguard Worker #include <cstring>
22*84e33947SAndroid Build Coastguard Worker
23*84e33947SAndroid Build Coastguard Worker namespace chpp::test {
24*84e33947SAndroid Build Coastguard Worker
25*84e33947SAndroid Build Coastguard Worker // Utilities for packet creation -----------------------------------------------
26*84e33947SAndroid Build Coastguard Worker
generateEmptyPacket(uint8_t ackSeq,uint8_t seq,uint8_t error)27*84e33947SAndroid Build Coastguard Worker ChppEmptyPacket generateEmptyPacket(uint8_t ackSeq, uint8_t seq,
28*84e33947SAndroid Build Coastguard Worker uint8_t error) {
29*84e33947SAndroid Build Coastguard Worker // clang-format off
30*84e33947SAndroid Build Coastguard Worker ChppEmptyPacket pkt = {
31*84e33947SAndroid Build Coastguard Worker .preamble = kPreamble,
32*84e33947SAndroid Build Coastguard Worker .header = {
33*84e33947SAndroid Build Coastguard Worker .flags = CHPP_TRANSPORT_FLAG_FINISHED_DATAGRAM,
34*84e33947SAndroid Build Coastguard Worker .packetCode = static_cast<uint8_t>(CHPP_ATTR_AND_ERROR_TO_PACKET_CODE(
35*84e33947SAndroid Build Coastguard Worker CHPP_TRANSPORT_ATTR_NONE, error)),
36*84e33947SAndroid Build Coastguard Worker .ackSeq = ackSeq,
37*84e33947SAndroid Build Coastguard Worker .seq = seq,
38*84e33947SAndroid Build Coastguard Worker .length = 0,
39*84e33947SAndroid Build Coastguard Worker .reserved = 0,
40*84e33947SAndroid Build Coastguard Worker },
41*84e33947SAndroid Build Coastguard Worker };
42*84e33947SAndroid Build Coastguard Worker // clang-format on
43*84e33947SAndroid Build Coastguard Worker pkt.footer.checksum = computeCrc(pkt);
44*84e33947SAndroid Build Coastguard Worker return pkt;
45*84e33947SAndroid Build Coastguard Worker }
46*84e33947SAndroid Build Coastguard Worker
generateResetPacket(uint8_t ackSeq,uint8_t seq)47*84e33947SAndroid Build Coastguard Worker ChppResetPacket generateResetPacket(uint8_t ackSeq, uint8_t seq) {
48*84e33947SAndroid Build Coastguard Worker // clang-format off
49*84e33947SAndroid Build Coastguard Worker ChppResetPacket pkt = {
50*84e33947SAndroid Build Coastguard Worker .preamble = kPreamble,
51*84e33947SAndroid Build Coastguard Worker .header = {
52*84e33947SAndroid Build Coastguard Worker .flags = CHPP_TRANSPORT_FLAG_FINISHED_DATAGRAM,
53*84e33947SAndroid Build Coastguard Worker .packetCode = static_cast<uint8_t>(CHPP_ATTR_AND_ERROR_TO_PACKET_CODE(
54*84e33947SAndroid Build Coastguard Worker CHPP_TRANSPORT_ATTR_RESET,
55*84e33947SAndroid Build Coastguard Worker CHPP_TRANSPORT_ERROR_NONE
56*84e33947SAndroid Build Coastguard Worker )),
57*84e33947SAndroid Build Coastguard Worker .ackSeq = ackSeq,
58*84e33947SAndroid Build Coastguard Worker .seq = seq,
59*84e33947SAndroid Build Coastguard Worker .length = sizeof(ChppTransportConfiguration),
60*84e33947SAndroid Build Coastguard Worker .reserved = 0,
61*84e33947SAndroid Build Coastguard Worker },
62*84e33947SAndroid Build Coastguard Worker .config = {
63*84e33947SAndroid Build Coastguard Worker .version = {
64*84e33947SAndroid Build Coastguard Worker .major = 1,
65*84e33947SAndroid Build Coastguard Worker .minor = 0,
66*84e33947SAndroid Build Coastguard Worker .patch = 0,
67*84e33947SAndroid Build Coastguard Worker },
68*84e33947SAndroid Build Coastguard Worker .reserved1 = 0,
69*84e33947SAndroid Build Coastguard Worker .reserved2 = 0,
70*84e33947SAndroid Build Coastguard Worker .reserved3 = 0,
71*84e33947SAndroid Build Coastguard Worker }
72*84e33947SAndroid Build Coastguard Worker };
73*84e33947SAndroid Build Coastguard Worker // clang-format on
74*84e33947SAndroid Build Coastguard Worker pkt.footer.checksum = computeCrc(pkt);
75*84e33947SAndroid Build Coastguard Worker return pkt;
76*84e33947SAndroid Build Coastguard Worker }
77*84e33947SAndroid Build Coastguard Worker
generateResetAckPacket(uint8_t ackSeq,uint8_t seq)78*84e33947SAndroid Build Coastguard Worker ChppResetPacket generateResetAckPacket(uint8_t ackSeq, uint8_t seq) {
79*84e33947SAndroid Build Coastguard Worker ChppResetPacket pkt = generateResetPacket(ackSeq, seq);
80*84e33947SAndroid Build Coastguard Worker pkt.header.packetCode =
81*84e33947SAndroid Build Coastguard Worker static_cast<uint8_t>(CHPP_ATTR_AND_ERROR_TO_PACKET_CODE(
82*84e33947SAndroid Build Coastguard Worker CHPP_TRANSPORT_ATTR_RESET_ACK, CHPP_TRANSPORT_ERROR_NONE));
83*84e33947SAndroid Build Coastguard Worker pkt.footer.checksum = computeCrc(pkt);
84*84e33947SAndroid Build Coastguard Worker return pkt;
85*84e33947SAndroid Build Coastguard Worker }
86*84e33947SAndroid Build Coastguard Worker
generateAck(const std::vector<uint8_t> & pkt)87*84e33947SAndroid Build Coastguard Worker ChppEmptyPacket generateAck(const std::vector<uint8_t> &pkt) {
88*84e33947SAndroid Build Coastguard Worker // An ACK consists of an empty packet with the ackSeq set to the received
89*84e33947SAndroid Build Coastguard Worker // packet's seq + 1 (since ackSeq indicates the next seq value we expect), and
90*84e33947SAndroid Build Coastguard Worker // seq set to the received packet's ackSeq - 1 (since we don't increment seq
91*84e33947SAndroid Build Coastguard Worker // on empty packets and ackSeq indicates the next expected seq)
92*84e33947SAndroid Build Coastguard Worker const ChppTransportHeader &hdr = getHeader(pkt);
93*84e33947SAndroid Build Coastguard Worker return generateEmptyPacket(/*acqSeq=*/hdr.seq + 1, /*seq=*/hdr.ackSeq - 1);
94*84e33947SAndroid Build Coastguard Worker }
95*84e33947SAndroid Build Coastguard Worker
96*84e33947SAndroid Build Coastguard Worker // Utilities for debugging -----------------------------------------------------
97*84e33947SAndroid Build Coastguard Worker
appErrorCodeToStr(uint8_t error)98*84e33947SAndroid Build Coastguard Worker const char *appErrorCodeToStr(uint8_t error) {
99*84e33947SAndroid Build Coastguard Worker switch (error) {
100*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_NONE:
101*84e33947SAndroid Build Coastguard Worker return "NONE";
102*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_INVALID_COMMAND:
103*84e33947SAndroid Build Coastguard Worker return "INVALID_COMMAND";
104*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_INVALID_ARG:
105*84e33947SAndroid Build Coastguard Worker return "INVALID_ARG";
106*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_BUSY:
107*84e33947SAndroid Build Coastguard Worker return "BUSY";
108*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_OOM:
109*84e33947SAndroid Build Coastguard Worker return "OOM";
110*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_UNSUPPORTED:
111*84e33947SAndroid Build Coastguard Worker return "UNSUPPORTED";
112*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_TIMEOUT:
113*84e33947SAndroid Build Coastguard Worker return "TIMEOUT";
114*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_DISABLED:
115*84e33947SAndroid Build Coastguard Worker return "DISABLED";
116*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_RATELIMITED:
117*84e33947SAndroid Build Coastguard Worker return "RATELIMITED";
118*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_BLOCKED:
119*84e33947SAndroid Build Coastguard Worker return "BLOCKED";
120*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_INVALID_LENGTH:
121*84e33947SAndroid Build Coastguard Worker return "INVALID_LENGTH";
122*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_NOT_READY:
123*84e33947SAndroid Build Coastguard Worker return "NOT_READY";
124*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_BEYOND_CHPP:
125*84e33947SAndroid Build Coastguard Worker return "BEYOND_CHPP";
126*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_UNEXPECTED_RESPONSE:
127*84e33947SAndroid Build Coastguard Worker return "UNEXPECTED_RESPONSE";
128*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_CONVERSION_FAILED:
129*84e33947SAndroid Build Coastguard Worker return "CONVERSION_FAILED";
130*84e33947SAndroid Build Coastguard Worker case CHPP_APP_ERROR_UNSPECIFIED:
131*84e33947SAndroid Build Coastguard Worker return "UNSPECIFIED";
132*84e33947SAndroid Build Coastguard Worker default:
133*84e33947SAndroid Build Coastguard Worker return "UNKNOWN";
134*84e33947SAndroid Build Coastguard Worker }
135*84e33947SAndroid Build Coastguard Worker }
136*84e33947SAndroid Build Coastguard Worker
appMessageTypeToStr(uint8_t type)137*84e33947SAndroid Build Coastguard Worker const char *appMessageTypeToStr(uint8_t type) {
138*84e33947SAndroid Build Coastguard Worker switch (type) {
139*84e33947SAndroid Build Coastguard Worker case CHPP_MESSAGE_TYPE_CLIENT_REQUEST:
140*84e33947SAndroid Build Coastguard Worker return "CLIENT_REQ";
141*84e33947SAndroid Build Coastguard Worker case CHPP_MESSAGE_TYPE_SERVICE_RESPONSE:
142*84e33947SAndroid Build Coastguard Worker return "SERVICE_RESP";
143*84e33947SAndroid Build Coastguard Worker case CHPP_MESSAGE_TYPE_CLIENT_NOTIFICATION:
144*84e33947SAndroid Build Coastguard Worker return "CLIENT_NOTIF";
145*84e33947SAndroid Build Coastguard Worker case CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION:
146*84e33947SAndroid Build Coastguard Worker return "SERVICE_NOTIF";
147*84e33947SAndroid Build Coastguard Worker case CHPP_MESSAGE_TYPE_SERVICE_REQUEST:
148*84e33947SAndroid Build Coastguard Worker return "SERVICE_REQ";
149*84e33947SAndroid Build Coastguard Worker case CHPP_MESSAGE_TYPE_CLIENT_RESPONSE:
150*84e33947SAndroid Build Coastguard Worker return "CLIENT_RESP";
151*84e33947SAndroid Build Coastguard Worker default:
152*84e33947SAndroid Build Coastguard Worker return "UNKNOWN";
153*84e33947SAndroid Build Coastguard Worker }
154*84e33947SAndroid Build Coastguard Worker }
155*84e33947SAndroid Build Coastguard Worker
handleToStr(uint8_t handle)156*84e33947SAndroid Build Coastguard Worker const char *handleToStr(uint8_t handle) {
157*84e33947SAndroid Build Coastguard Worker switch (handle) {
158*84e33947SAndroid Build Coastguard Worker case CHPP_HANDLE_NONE:
159*84e33947SAndroid Build Coastguard Worker return "(NONE)";
160*84e33947SAndroid Build Coastguard Worker case CHPP_HANDLE_LOOPBACK:
161*84e33947SAndroid Build Coastguard Worker return "(LOOPBACK)";
162*84e33947SAndroid Build Coastguard Worker case CHPP_HANDLE_TIMESYNC:
163*84e33947SAndroid Build Coastguard Worker return "(TIMESYNC)";
164*84e33947SAndroid Build Coastguard Worker case CHPP_HANDLE_DISCOVERY:
165*84e33947SAndroid Build Coastguard Worker return "(DISCOVERY)";
166*84e33947SAndroid Build Coastguard Worker default:
167*84e33947SAndroid Build Coastguard Worker return "";
168*84e33947SAndroid Build Coastguard Worker }
169*84e33947SAndroid Build Coastguard Worker }
170*84e33947SAndroid Build Coastguard Worker
packetAttrToStr(uint8_t attr)171*84e33947SAndroid Build Coastguard Worker const char *packetAttrToStr(uint8_t attr) {
172*84e33947SAndroid Build Coastguard Worker switch (attr) {
173*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ATTR_NONE:
174*84e33947SAndroid Build Coastguard Worker return "none";
175*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ATTR_RESET:
176*84e33947SAndroid Build Coastguard Worker return "reset";
177*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ATTR_RESET_ACK:
178*84e33947SAndroid Build Coastguard Worker return "reset-ack";
179*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ATTR_LOOPBACK_REQUEST:
180*84e33947SAndroid Build Coastguard Worker return "loopback-req";
181*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ATTR_LOOPBACK_RESPONSE:
182*84e33947SAndroid Build Coastguard Worker return "loopback-rsp";
183*84e33947SAndroid Build Coastguard Worker default:
184*84e33947SAndroid Build Coastguard Worker return "invalid";
185*84e33947SAndroid Build Coastguard Worker }
186*84e33947SAndroid Build Coastguard Worker }
187*84e33947SAndroid Build Coastguard Worker
transportErrorToStr(uint8_t error)188*84e33947SAndroid Build Coastguard Worker const char *transportErrorToStr(uint8_t error) {
189*84e33947SAndroid Build Coastguard Worker switch (error) {
190*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_NONE:
191*84e33947SAndroid Build Coastguard Worker return "none";
192*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_CHECKSUM:
193*84e33947SAndroid Build Coastguard Worker return "checksum";
194*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_OOM:
195*84e33947SAndroid Build Coastguard Worker return "oom";
196*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_BUSY:
197*84e33947SAndroid Build Coastguard Worker return "busy";
198*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_HEADER:
199*84e33947SAndroid Build Coastguard Worker return "header";
200*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_ORDER:
201*84e33947SAndroid Build Coastguard Worker return "order";
202*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_TIMEOUT:
203*84e33947SAndroid Build Coastguard Worker return "timeout";
204*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_MAX_RETRIES:
205*84e33947SAndroid Build Coastguard Worker return "max-retries";
206*84e33947SAndroid Build Coastguard Worker case CHPP_TRANSPORT_ERROR_APPLAYER:
207*84e33947SAndroid Build Coastguard Worker return "app-layer";
208*84e33947SAndroid Build Coastguard Worker default:
209*84e33947SAndroid Build Coastguard Worker return "invalid";
210*84e33947SAndroid Build Coastguard Worker }
211*84e33947SAndroid Build Coastguard Worker }
212*84e33947SAndroid Build Coastguard Worker
dumpRaw(std::ostream & os,const void * ptr,size_t len)213*84e33947SAndroid Build Coastguard Worker void dumpRaw(std::ostream &os, const void *ptr, size_t len) {
214*84e33947SAndroid Build Coastguard Worker const uint8_t *buffer = static_cast<const uint8_t *>(ptr);
215*84e33947SAndroid Build Coastguard Worker char line[32];
216*84e33947SAndroid Build Coastguard Worker char lineChars[32];
217*84e33947SAndroid Build Coastguard Worker size_t offset = 0;
218*84e33947SAndroid Build Coastguard Worker size_t offsetChars = 0;
219*84e33947SAndroid Build Coastguard Worker
220*84e33947SAndroid Build Coastguard Worker for (size_t i = 1; i <= len; i++) {
221*84e33947SAndroid Build Coastguard Worker // This ignores potential errors returned by snprintf. This is a relatively
222*84e33947SAndroid Build Coastguard Worker // simple case and the deliberate decision to ignore them has been made.
223*84e33947SAndroid Build Coastguard Worker offset += static_cast<size_t>(
224*84e33947SAndroid Build Coastguard Worker snprintf(&line[offset], sizeof(line) - offset, "%02x ", buffer[i - 1]));
225*84e33947SAndroid Build Coastguard Worker offsetChars += static_cast<size_t>(
226*84e33947SAndroid Build Coastguard Worker snprintf(&lineChars[offsetChars], sizeof(lineChars) - offsetChars, "%c",
227*84e33947SAndroid Build Coastguard Worker (isprint(buffer[i - 1])) ? buffer[i - 1] : '.'));
228*84e33947SAndroid Build Coastguard Worker if ((i % 8) == 0) {
229*84e33947SAndroid Build Coastguard Worker os << " " << line << "\t" << lineChars << std::endl;
230*84e33947SAndroid Build Coastguard Worker offset = 0;
231*84e33947SAndroid Build Coastguard Worker offsetChars = 0;
232*84e33947SAndroid Build Coastguard Worker } else if ((i % 4) == 0) {
233*84e33947SAndroid Build Coastguard Worker offset += static_cast<size_t>(
234*84e33947SAndroid Build Coastguard Worker snprintf(&line[offset], sizeof(line) - offset, " "));
235*84e33947SAndroid Build Coastguard Worker }
236*84e33947SAndroid Build Coastguard Worker }
237*84e33947SAndroid Build Coastguard Worker
238*84e33947SAndroid Build Coastguard Worker if (offset > 0) {
239*84e33947SAndroid Build Coastguard Worker char tabs[8];
240*84e33947SAndroid Build Coastguard Worker char *pos = tabs;
241*84e33947SAndroid Build Coastguard Worker while (offset < 28) {
242*84e33947SAndroid Build Coastguard Worker *pos++ = '\t';
243*84e33947SAndroid Build Coastguard Worker offset += 8;
244*84e33947SAndroid Build Coastguard Worker }
245*84e33947SAndroid Build Coastguard Worker *pos = '\0';
246*84e33947SAndroid Build Coastguard Worker os << " " << line << tabs << lineChars << std::endl;
247*84e33947SAndroid Build Coastguard Worker }
248*84e33947SAndroid Build Coastguard Worker }
249*84e33947SAndroid Build Coastguard Worker
dumpPreamble(std::ostream & os,uint16_t preamble)250*84e33947SAndroid Build Coastguard Worker void dumpPreamble(std::ostream &os, uint16_t preamble) {
251*84e33947SAndroid Build Coastguard Worker const char *p = reinterpret_cast<const char *>(&preamble);
252*84e33947SAndroid Build Coastguard Worker os << std::endl
253*84e33947SAndroid Build Coastguard Worker << "Preamble: 0x" << std::hex << preamble << " \"" << p[0] << p[1] << "\"";
254*84e33947SAndroid Build Coastguard Worker if (preamble == kPreamble) {
255*84e33947SAndroid Build Coastguard Worker os << " (ok)";
256*84e33947SAndroid Build Coastguard Worker } else {
257*84e33947SAndroid Build Coastguard Worker os << " (invalid -- expected 0x" << std::hex << kPreamble << ")";
258*84e33947SAndroid Build Coastguard Worker }
259*84e33947SAndroid Build Coastguard Worker os << std::endl;
260*84e33947SAndroid Build Coastguard Worker }
261*84e33947SAndroid Build Coastguard Worker
dumpHeader(std::ostream & os,const ChppTransportHeader & hdr)262*84e33947SAndroid Build Coastguard Worker void dumpHeader(std::ostream &os, const ChppTransportHeader &hdr) {
263*84e33947SAndroid Build Coastguard Worker os << "Header {" << std::endl
264*84e33947SAndroid Build Coastguard Worker << " flags: 0x" << std::hex << (unsigned)hdr.flags;
265*84e33947SAndroid Build Coastguard Worker if (hdr.flags & CHPP_TRANSPORT_FLAG_UNFINISHED_DATAGRAM) {
266*84e33947SAndroid Build Coastguard Worker os << " (unfinished)";
267*84e33947SAndroid Build Coastguard Worker } else {
268*84e33947SAndroid Build Coastguard Worker os << " (finished)";
269*84e33947SAndroid Build Coastguard Worker }
270*84e33947SAndroid Build Coastguard Worker uint8_t attr = CHPP_TRANSPORT_GET_ATTR(hdr.packetCode);
271*84e33947SAndroid Build Coastguard Worker uint8_t error = CHPP_TRANSPORT_GET_ERROR(hdr.packetCode);
272*84e33947SAndroid Build Coastguard Worker os << std::endl
273*84e33947SAndroid Build Coastguard Worker << " packetCode: 0x" << std::hex << (unsigned)hdr.packetCode
274*84e33947SAndroid Build Coastguard Worker << " (attr: " << packetAttrToStr(attr)
275*84e33947SAndroid Build Coastguard Worker << " | error: " << transportErrorToStr(error) << ")" << std::endl;
276*84e33947SAndroid Build Coastguard Worker
277*84e33947SAndroid Build Coastguard Worker os << " ackSeq: " << std::dec << (unsigned)hdr.ackSeq << std::endl
278*84e33947SAndroid Build Coastguard Worker << " seq: " << std::dec << (unsigned)hdr.seq << std::endl
279*84e33947SAndroid Build Coastguard Worker << " length: " << std::dec << hdr.length << std::endl
280*84e33947SAndroid Build Coastguard Worker << " reserved: " << std::dec << hdr.reserved << std::endl
281*84e33947SAndroid Build Coastguard Worker << "}" << std::endl;
282*84e33947SAndroid Build Coastguard Worker }
283*84e33947SAndroid Build Coastguard Worker
dumpConfig(std::ostream & os,const ChppTransportConfiguration & cfg)284*84e33947SAndroid Build Coastguard Worker void dumpConfig(std::ostream &os, const ChppTransportConfiguration &cfg) {
285*84e33947SAndroid Build Coastguard Worker os << "Config {" << std::endl
286*84e33947SAndroid Build Coastguard Worker << " version: " << std::dec << (unsigned)cfg.version.major << "."
287*84e33947SAndroid Build Coastguard Worker << std::dec << (unsigned)cfg.version.minor << "." << std::dec
288*84e33947SAndroid Build Coastguard Worker << cfg.version.patch << std::endl
289*84e33947SAndroid Build Coastguard Worker << "}" << std::endl;
290*84e33947SAndroid Build Coastguard Worker }
291*84e33947SAndroid Build Coastguard Worker
dumpEmptyPacket(std::ostream & os,const ChppEmptyPacket & pkt)292*84e33947SAndroid Build Coastguard Worker void dumpEmptyPacket(std::ostream &os, const ChppEmptyPacket &pkt) {
293*84e33947SAndroid Build Coastguard Worker dumpPreamble(os, pkt.preamble);
294*84e33947SAndroid Build Coastguard Worker dumpHeader(os, pkt.header);
295*84e33947SAndroid Build Coastguard Worker dumpFooter(os, pkt);
296*84e33947SAndroid Build Coastguard Worker }
297*84e33947SAndroid Build Coastguard Worker
dumpResetPacket(std::ostream & os,const ChppResetPacket & pkt)298*84e33947SAndroid Build Coastguard Worker void dumpResetPacket(std::ostream &os, const ChppResetPacket &pkt) {
299*84e33947SAndroid Build Coastguard Worker dumpPreamble(os, pkt.preamble);
300*84e33947SAndroid Build Coastguard Worker dumpHeader(os, pkt.header);
301*84e33947SAndroid Build Coastguard Worker dumpConfig(os, pkt.config);
302*84e33947SAndroid Build Coastguard Worker dumpFooter(os, pkt);
303*84e33947SAndroid Build Coastguard Worker }
304*84e33947SAndroid Build Coastguard Worker
dumpPacket(std::ostream & os,const ChppPacketPrefix & pkt)305*84e33947SAndroid Build Coastguard Worker void dumpPacket(std::ostream &os, const ChppPacketPrefix &pkt) {
306*84e33947SAndroid Build Coastguard Worker dumpPreamble(os, pkt.preamble);
307*84e33947SAndroid Build Coastguard Worker dumpHeader(os, pkt.header);
308*84e33947SAndroid Build Coastguard Worker size_t payloadOffset = 0;
309*84e33947SAndroid Build Coastguard Worker if (CHPP_TRANSPORT_GET_ATTR(pkt.header.packetCode) ==
310*84e33947SAndroid Build Coastguard Worker CHPP_TRANSPORT_ATTR_NONE &&
311*84e33947SAndroid Build Coastguard Worker pkt.header.length >= sizeof(ChppAppHeader)) {
312*84e33947SAndroid Build Coastguard Worker auto &appHdr = reinterpret_cast<const ChppAppHeader &>(*pkt.payload);
313*84e33947SAndroid Build Coastguard Worker os << "AppHeader {" << std::endl;
314*84e33947SAndroid Build Coastguard Worker os << " handle: 0x" << std::hex << (unsigned)appHdr.handle << " "
315*84e33947SAndroid Build Coastguard Worker << handleToStr(appHdr.handle) << std::endl;
316*84e33947SAndroid Build Coastguard Worker os << " type: " << std::dec << (unsigned)appHdr.type << " ("
317*84e33947SAndroid Build Coastguard Worker << appMessageTypeToStr(appHdr.type) << ")" << std::endl;
318*84e33947SAndroid Build Coastguard Worker os << " transaction: " << std::dec << (unsigned)appHdr.transaction
319*84e33947SAndroid Build Coastguard Worker << std::endl;
320*84e33947SAndroid Build Coastguard Worker os << " error: " << std::dec << (unsigned)appHdr.error << " ("
321*84e33947SAndroid Build Coastguard Worker << appErrorCodeToStr(appHdr.error) << ")" << std::endl;
322*84e33947SAndroid Build Coastguard Worker os << " command: " << std::dec << (unsigned)appHdr.command << std::endl;
323*84e33947SAndroid Build Coastguard Worker os << "}" << std::endl;
324*84e33947SAndroid Build Coastguard Worker payloadOffset = sizeof(ChppAppHeader);
325*84e33947SAndroid Build Coastguard Worker }
326*84e33947SAndroid Build Coastguard Worker size_t payloadSize = pkt.header.length - payloadOffset;
327*84e33947SAndroid Build Coastguard Worker if (payloadSize > 0) {
328*84e33947SAndroid Build Coastguard Worker os << "Payload (size " << payloadSize << ") {" << std::endl;
329*84e33947SAndroid Build Coastguard Worker dumpRaw(os, &pkt.payload[payloadOffset], pkt.header.length - payloadOffset);
330*84e33947SAndroid Build Coastguard Worker os << "}" << std::endl;
331*84e33947SAndroid Build Coastguard Worker }
332*84e33947SAndroid Build Coastguard Worker
333*84e33947SAndroid Build Coastguard Worker const auto &footer = *reinterpret_cast<const ChppTransportFooter *>(
334*84e33947SAndroid Build Coastguard Worker &pkt.payload[pkt.header.length]);
335*84e33947SAndroid Build Coastguard Worker uint32_t crc = chppCrc32(0, reinterpret_cast<const uint8_t *>(&pkt.header),
336*84e33947SAndroid Build Coastguard Worker sizeof(pkt.header) + pkt.header.length);
337*84e33947SAndroid Build Coastguard Worker os << "CRC: 0x" << std::hex << footer.checksum;
338*84e33947SAndroid Build Coastguard Worker if (footer.checksum != crc) {
339*84e33947SAndroid Build Coastguard Worker os << " (invalid, expected " << crc << ")";
340*84e33947SAndroid Build Coastguard Worker } else {
341*84e33947SAndroid Build Coastguard Worker os << " (ok)";
342*84e33947SAndroid Build Coastguard Worker }
343*84e33947SAndroid Build Coastguard Worker os << std::endl;
344*84e33947SAndroid Build Coastguard Worker }
345*84e33947SAndroid Build Coastguard Worker
operator <<(std::ostream & os,const ChppEmptyPacket & pkt)346*84e33947SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const ChppEmptyPacket &pkt) {
347*84e33947SAndroid Build Coastguard Worker dumpEmptyPacket(os, pkt);
348*84e33947SAndroid Build Coastguard Worker return os;
349*84e33947SAndroid Build Coastguard Worker }
350*84e33947SAndroid Build Coastguard Worker
operator <<(std::ostream & os,const ChppResetPacket & pkt)351*84e33947SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const ChppResetPacket &pkt) {
352*84e33947SAndroid Build Coastguard Worker dumpResetPacket(os, pkt);
353*84e33947SAndroid Build Coastguard Worker return os;
354*84e33947SAndroid Build Coastguard Worker }
355*84e33947SAndroid Build Coastguard Worker
operator <<(std::ostream & os,const ChppPacketPrefix & pkt)356*84e33947SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const ChppPacketPrefix &pkt) {
357*84e33947SAndroid Build Coastguard Worker dumpPacket(os, pkt);
358*84e33947SAndroid Build Coastguard Worker return os;
359*84e33947SAndroid Build Coastguard Worker }
360*84e33947SAndroid Build Coastguard Worker
361*84e33947SAndroid Build Coastguard Worker // Utilities for gtest packet checking -----------------------------------------
362*84e33947SAndroid Build Coastguard Worker
checkPacketValidity(std::vector<uint8_t> & received)363*84e33947SAndroid Build Coastguard Worker void checkPacketValidity(std::vector<uint8_t> &received) {
364*84e33947SAndroid Build Coastguard Worker const ChppPacketPrefix &pkt = asChpp(received);
365*84e33947SAndroid Build Coastguard Worker EXPECT_GE(received.size(), sizeof(ChppEmptyPacket));
366*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(pkt.preamble, kPreamble);
367*84e33947SAndroid Build Coastguard Worker
368*84e33947SAndroid Build Coastguard Worker constexpr size_t kFixedLenPortion =
369*84e33947SAndroid Build Coastguard Worker sizeof(pkt.preamble) + sizeof(pkt.header) + sizeof(ChppTransportFooter);
370*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(pkt.header.length, received.size() - kFixedLenPortion);
371*84e33947SAndroid Build Coastguard Worker
372*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(pkt.header.flags & CHPP_TRANSPORT_FLAG_RESERVED, 0);
373*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(pkt.header.reserved, 0);
374*84e33947SAndroid Build Coastguard Worker
375*84e33947SAndroid Build Coastguard Worker uint8_t error = CHPP_TRANSPORT_GET_ERROR(pkt.header.packetCode);
376*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(error <= CHPP_TRANSPORT_ERROR_MAX_RETRIES ||
377*84e33947SAndroid Build Coastguard Worker error == CHPP_TRANSPORT_ERROR_APPLAYER);
378*84e33947SAndroid Build Coastguard Worker uint8_t attrs = CHPP_TRANSPORT_GET_ATTR(pkt.header.packetCode);
379*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(attrs <= CHPP_TRANSPORT_ATTR_LOOPBACK_RESPONSE);
380*84e33947SAndroid Build Coastguard Worker
381*84e33947SAndroid Build Coastguard Worker uint32_t crc = chppCrc32(0, reinterpret_cast<const uint8_t *>(&pkt.header),
382*84e33947SAndroid Build Coastguard Worker sizeof(pkt.header) + pkt.header.length);
383*84e33947SAndroid Build Coastguard Worker const auto *footer = reinterpret_cast<const ChppTransportFooter *>(
384*84e33947SAndroid Build Coastguard Worker &received[sizeof(pkt.preamble) + sizeof(pkt.header) + pkt.header.length]);
385*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(footer->checksum, crc);
386*84e33947SAndroid Build Coastguard Worker }
387*84e33947SAndroid Build Coastguard Worker
comparePacketHeader(const ChppTransportHeader & rx,const ChppTransportHeader & expected)388*84e33947SAndroid Build Coastguard Worker bool comparePacketHeader(const ChppTransportHeader &rx,
389*84e33947SAndroid Build Coastguard Worker const ChppTransportHeader &expected) {
390*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx.flags, expected.flags);
391*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx.packetCode, expected.packetCode);
392*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx.ackSeq, expected.ackSeq);
393*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx.seq, expected.seq);
394*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx.length, expected.length);
395*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx.reserved, 0u);
396*84e33947SAndroid Build Coastguard Worker return (memcmp(&rx, &expected, sizeof(rx)) == 0);
397*84e33947SAndroid Build Coastguard Worker }
398*84e33947SAndroid Build Coastguard Worker
comparePacket(const std::vector<uint8_t> & received,const ChppEmptyPacket & expected)399*84e33947SAndroid Build Coastguard Worker bool comparePacket(const std::vector<uint8_t> &received,
400*84e33947SAndroid Build Coastguard Worker const ChppEmptyPacket &expected) {
401*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(received.size(), sizeof(expected));
402*84e33947SAndroid Build Coastguard Worker if (received.size() == sizeof(expected)) {
403*84e33947SAndroid Build Coastguard Worker const auto *rx = reinterpret_cast<const ChppEmptyPacket *>(received.data());
404*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx->preamble, expected.preamble);
405*84e33947SAndroid Build Coastguard Worker comparePacketHeader(rx->header, expected.header);
406*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx->footer.checksum, expected.footer.checksum);
407*84e33947SAndroid Build Coastguard Worker }
408*84e33947SAndroid Build Coastguard Worker return (received.size() == sizeof(expected) &&
409*84e33947SAndroid Build Coastguard Worker memcmp(received.data(), &expected, sizeof(expected)) == 0);
410*84e33947SAndroid Build Coastguard Worker }
411*84e33947SAndroid Build Coastguard Worker
comparePacket(const std::vector<uint8_t> & received,const ChppResetPacket & expected)412*84e33947SAndroid Build Coastguard Worker bool comparePacket(const std::vector<uint8_t> &received,
413*84e33947SAndroid Build Coastguard Worker const ChppResetPacket &expected) {
414*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(received.size(), sizeof(expected));
415*84e33947SAndroid Build Coastguard Worker if (received.size() == sizeof(expected)) {
416*84e33947SAndroid Build Coastguard Worker const auto *rx = reinterpret_cast<const ChppResetPacket *>(received.data());
417*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx->preamble, expected.preamble);
418*84e33947SAndroid Build Coastguard Worker comparePacketHeader(rx->header, expected.header);
419*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx->config.version.major, expected.config.version.major);
420*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx->config.version.minor, expected.config.version.minor);
421*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx->config.version.patch, expected.config.version.patch);
422*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(rx->footer.checksum, expected.footer.checksum);
423*84e33947SAndroid Build Coastguard Worker }
424*84e33947SAndroid Build Coastguard Worker return (received.size() == sizeof(expected) &&
425*84e33947SAndroid Build Coastguard Worker memcmp(received.data(), &expected, sizeof(expected)) == 0);
426*84e33947SAndroid Build Coastguard Worker }
427*84e33947SAndroid Build Coastguard Worker
428*84e33947SAndroid Build Coastguard Worker } // namespace chpp::test