xref: /openbmc/libpldm/tests/dsp/base.cpp (revision 4e3d5725eb19cef457558dc6da647509d52cfef1)
1 #include "msgbuf.hpp"
2 
3 #include <libpldm/base.h>
4 #include <libpldm/pldm_types.h>
5 
6 #include <array>
7 #include <cstdint>
8 #include <cstring>
9 #include <vector>
10 
11 #include <gmock/gmock.h>
12 #include <gtest/gtest.h>
13 
14 using testing::ElementsAreArray;
15 
16 constexpr auto hdrSize = sizeof(pldm_msg_hdr);
17 
TEST(Ver2string,Ver2string)18 TEST(Ver2string, Ver2string)
19 {
20     ver32_t version{0x61, 0x10, 0xf7, 0xf3};
21     const char* vstr = "3.7.10a";
22     char buffer[1024];
23     auto rc = pldm_base_ver2str(&version, buffer, sizeof(buffer));
24     EXPECT_EQ(rc, (signed)std::strlen(vstr));
25     EXPECT_STREQ(vstr, buffer);
26 
27     version = {0x00, 0xf0, 0xf0, 0xf1};
28     vstr = "1.0.0";
29     rc = pldm_base_ver2str(&version, buffer, sizeof(buffer));
30     EXPECT_EQ(rc, (signed)std::strlen(vstr));
31     EXPECT_STREQ(vstr, buffer);
32 
33     version = {0x00, 0xf7, 0x01, 0x10};
34     vstr = "10.01.7";
35     rc = pldm_base_ver2str(&version, buffer, sizeof(buffer));
36     EXPECT_EQ(rc, (signed)std::strlen(vstr));
37     EXPECT_STREQ(vstr, buffer);
38 
39     version = {0x00, 0xff, 0xf1, 0xf3};
40     vstr = "3.1";
41     rc = pldm_base_ver2str(&version, buffer, sizeof(buffer));
42     EXPECT_EQ(rc, (signed)std::strlen(vstr));
43     EXPECT_STREQ(vstr, buffer);
44 
45     version = {0x61, 0xff, 0xf0, 0xf1};
46     vstr = "1.0a";
47     rc = pldm_base_ver2str(&version, buffer, sizeof(buffer));
48     EXPECT_EQ(rc, (signed)std::strlen(vstr));
49     EXPECT_STREQ(vstr, buffer);
50 
51     rc = pldm_base_ver2str(&version, buffer, 3);
52     EXPECT_EQ(rc, 2);
53     EXPECT_STREQ("1.", buffer);
54 
55     rc = pldm_base_ver2str(&version, buffer, 1);
56     EXPECT_EQ(rc, 0);
57 
58     rc = pldm_base_ver2str(&version, buffer, 0);
59     EXPECT_EQ(rc, -1);
60 }
61 
TEST(PackPLDMMessage,BadPathTest)62 TEST(PackPLDMMessage, BadPathTest)
63 {
64     struct pldm_header_info hdr;
65     struct pldm_header_info* hdr_ptr = NULL;
66     pldm_msg_hdr msg{};
67 
68     // PLDM header information pointer is NULL
69     auto rc = pack_pldm_header(hdr_ptr, &msg);
70     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
71 
72     // PLDM message pointer is NULL
73     rc = pack_pldm_header(&hdr, nullptr);
74     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
75 
76     // PLDM header information pointer and PLDM message pointer is NULL
77     rc = pack_pldm_header(hdr_ptr, nullptr);
78     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
79 
80     // RESERVED message type
81     hdr.msg_type = PLDM_RESERVED;
82     rc = pack_pldm_header(&hdr, &msg);
83     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
84 
85     // Instance ID out of range
86     hdr.msg_type = PLDM_REQUEST;
87     hdr.instance = 32;
88     rc = pack_pldm_header(&hdr, &msg);
89     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
90 
91     // PLDM type out of range
92     hdr.msg_type = PLDM_REQUEST;
93     hdr.instance = 31;
94     hdr.pldm_type = 64;
95     rc = pack_pldm_header(&hdr, &msg);
96     EXPECT_EQ(rc, PLDM_ERROR_INVALID_PLDM_TYPE);
97 }
98 
TEST(PackPLDMMessage,RequestMessageGoodPath)99 TEST(PackPLDMMessage, RequestMessageGoodPath)
100 {
101     struct pldm_header_info hdr;
102     pldm_msg_hdr msg{};
103 
104     // Message type is REQUEST and lower range of the field values
105     hdr.msg_type = PLDM_REQUEST;
106     hdr.instance = 0;
107     hdr.pldm_type = 0;
108     hdr.command = 0;
109 
110     auto rc = pack_pldm_header(&hdr, &msg);
111     EXPECT_EQ(rc, PLDM_SUCCESS);
112     EXPECT_EQ(msg.request, 1);
113     EXPECT_EQ(msg.datagram, 0);
114     EXPECT_EQ(msg.instance_id, 0);
115     EXPECT_EQ(msg.type, 0);
116     EXPECT_EQ(msg.command, 0);
117 
118     // Message type is REQUEST and upper range of the field values
119     hdr.instance = 31;
120     hdr.pldm_type = 63;
121     hdr.command = 255;
122 
123     rc = pack_pldm_header(&hdr, &msg);
124     EXPECT_EQ(rc, PLDM_SUCCESS);
125     EXPECT_EQ(msg.request, 1);
126     EXPECT_EQ(msg.datagram, 0);
127     EXPECT_EQ(msg.instance_id, 31);
128     EXPECT_EQ(msg.type, 63);
129     EXPECT_EQ(msg.command, 255);
130 
131     // Message type is PLDM_ASYNC_REQUEST_NOTIFY
132     hdr.msg_type = PLDM_ASYNC_REQUEST_NOTIFY;
133 
134     rc = pack_pldm_header(&hdr, &msg);
135     EXPECT_EQ(rc, PLDM_SUCCESS);
136     EXPECT_EQ(msg.request, 1);
137     EXPECT_EQ(msg.datagram, 1);
138     EXPECT_EQ(msg.instance_id, 31);
139     EXPECT_EQ(msg.type, 63);
140     EXPECT_EQ(msg.command, 255);
141 }
142 
TEST(PackPLDMMessage,ResponseMessageGoodPath)143 TEST(PackPLDMMessage, ResponseMessageGoodPath)
144 {
145     struct pldm_header_info hdr;
146     pldm_msg_hdr msg{};
147 
148     // Message type is PLDM_RESPONSE and lower range of the field values
149     hdr.msg_type = PLDM_RESPONSE;
150     hdr.instance = 0;
151     hdr.pldm_type = 0;
152     hdr.command = 0;
153 
154     auto rc = pack_pldm_header(&hdr, &msg);
155     EXPECT_EQ(rc, PLDM_SUCCESS);
156     EXPECT_EQ(msg.request, 0);
157     EXPECT_EQ(msg.datagram, 0);
158     EXPECT_EQ(msg.instance_id, 0);
159     EXPECT_EQ(msg.type, 0);
160     EXPECT_EQ(msg.command, 0);
161 
162     // Message type is PLDM_RESPONSE and upper range of the field values
163     hdr.instance = 31;
164     hdr.pldm_type = 63;
165     hdr.command = 255;
166 
167     rc = pack_pldm_header(&hdr, &msg);
168     EXPECT_EQ(rc, PLDM_SUCCESS);
169     EXPECT_EQ(msg.request, 0);
170     EXPECT_EQ(msg.datagram, 0);
171     EXPECT_EQ(msg.instance_id, 31);
172     EXPECT_EQ(msg.type, 63);
173     EXPECT_EQ(msg.command, 255);
174 }
175 
TEST(UnpackPLDMMessage,BadPathTest)176 TEST(UnpackPLDMMessage, BadPathTest)
177 {
178     struct pldm_header_info hdr;
179 
180     // PLDM message pointer is NULL
181     auto rc = unpack_pldm_header(nullptr, &hdr);
182     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
183 }
184 
TEST(UnpackPLDMMessage,RequestMessageGoodPath)185 TEST(UnpackPLDMMessage, RequestMessageGoodPath)
186 {
187     struct pldm_header_info hdr;
188     pldm_msg_hdr msg{};
189 
190     // Unpack PLDM request message and lower range of field values
191     msg.request = 1;
192     auto rc = unpack_pldm_header(&msg, &hdr);
193     EXPECT_EQ(rc, PLDM_SUCCESS);
194     EXPECT_EQ(hdr.msg_type, PLDM_REQUEST);
195     EXPECT_EQ(hdr.instance, 0);
196     EXPECT_EQ(hdr.pldm_type, 0);
197     EXPECT_EQ(hdr.command, 0);
198 
199     // Unpack PLDM async request message and lower range of field values
200     msg.datagram = 1;
201     rc = unpack_pldm_header(&msg, &hdr);
202     EXPECT_EQ(rc, PLDM_SUCCESS);
203     EXPECT_EQ(hdr.msg_type, PLDM_ASYNC_REQUEST_NOTIFY);
204 
205     // Unpack PLDM request message and upper range of field values
206     msg.datagram = 0;
207     msg.instance_id = 31;
208     msg.type = 63;
209     msg.command = 255;
210     rc = unpack_pldm_header(&msg, &hdr);
211     EXPECT_EQ(rc, PLDM_SUCCESS);
212     EXPECT_EQ(hdr.msg_type, PLDM_REQUEST);
213     EXPECT_EQ(hdr.instance, 31);
214     EXPECT_EQ(hdr.pldm_type, 63);
215     EXPECT_EQ(hdr.command, 255);
216 }
217 
TEST(UnpackPLDMMessage,ResponseMessageGoodPath)218 TEST(UnpackPLDMMessage, ResponseMessageGoodPath)
219 {
220     struct pldm_header_info hdr;
221     pldm_msg_hdr msg{};
222 
223     // Unpack PLDM response message and lower range of field values
224     auto rc = unpack_pldm_header(&msg, &hdr);
225     EXPECT_EQ(rc, PLDM_SUCCESS);
226     EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE);
227     EXPECT_EQ(hdr.instance, 0);
228     EXPECT_EQ(hdr.pldm_type, 0);
229     EXPECT_EQ(hdr.command, 0);
230 
231     // Unpack PLDM response message and upper range of field values
232     msg.instance_id = 31;
233     msg.type = 63;
234     msg.command = 255;
235     rc = unpack_pldm_header(&msg, &hdr);
236     EXPECT_EQ(rc, PLDM_SUCCESS);
237     EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE);
238     EXPECT_EQ(hdr.instance, 31);
239     EXPECT_EQ(hdr.pldm_type, 63);
240     EXPECT_EQ(hdr.command, 255);
241 }
242 
TEST(GetPLDMCommands,testEncodeRequest)243 TEST(GetPLDMCommands, testEncodeRequest)
244 {
245     uint8_t pldmType = 0x05;
246     ver32_t version{0xff, 0xff, 0xff, 0xff};
247     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
248         requestMsg{};
249     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
250     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
251 
252     auto rc = encode_get_commands_req(0, pldmType, version, request);
253     EXPECT_EQ(rc, PLDM_SUCCESS);
254     EXPECT_EQ(0, memcmp(request->payload, &pldmType, sizeof(pldmType)));
255     EXPECT_EQ(0, memcmp(request->payload + sizeof(pldmType), &version,
256                         sizeof(version)));
257 }
258 
TEST(GetPLDMCommands,testDecodeRequest)259 TEST(GetPLDMCommands, testDecodeRequest)
260 {
261     uint8_t pldmType = 0x05;
262     ver32_t version{0xff, 0xff, 0xff, 0xff};
263     uint8_t pldmTypeOut{};
264     ver32_t versionOut{0xff, 0xff, 0xff, 0xff};
265     std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_REQ_BYTES> requestMsg{};
266 
267     memcpy(requestMsg.data() + hdrSize, &pldmType, sizeof(pldmType));
268     memcpy(requestMsg.data() + sizeof(pldmType) + hdrSize, &version,
269            sizeof(version));
270 
271     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
272     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
273     auto rc = decode_get_commands_req(request, requestMsg.size() - hdrSize,
274                                       &pldmTypeOut, &versionOut);
275 
276     EXPECT_EQ(rc, PLDM_SUCCESS);
277     EXPECT_EQ(pldmTypeOut, pldmType);
278     EXPECT_EQ(0, memcmp(&versionOut, &version, sizeof(version)));
279 }
280 
TEST(GetPLDMCommands,testEncodeResponse)281 TEST(GetPLDMCommands, testEncodeResponse)
282 {
283     uint8_t completionCode = 0;
284     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES>
285         responseMsg{};
286     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
287     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
288     std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> commands{};
289     commands[0].byte = 1;
290     commands[1].byte = 2;
291     commands[2].byte = 3;
292 
293     auto rc =
294         encode_get_commands_resp(0, PLDM_SUCCESS, commands.data(), response);
295     EXPECT_EQ(rc, PLDM_SUCCESS);
296     uint8_t* payload_ptr = response->payload;
297     EXPECT_EQ(completionCode, payload_ptr[0]);
298     EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]);
299     EXPECT_EQ(2,
300               payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte)]);
301     EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte) +
302                              sizeof(commands[1].byte)]);
303 }
304 
TEST(GetPLDMTypes,testEncodeResponse)305 TEST(GetPLDMTypes, testEncodeResponse)
306 {
307     uint8_t completionCode = 0;
308     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES>
309         responseMsg{};
310     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
311     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
312     std::array<bitfield8_t, PLDM_MAX_TYPES / 8> types{};
313     types[0].byte = 1;
314     types[1].byte = 2;
315     types[2].byte = 3;
316 
317     auto rc = encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response);
318     EXPECT_EQ(rc, PLDM_SUCCESS);
319     uint8_t* payload_ptr = response->payload;
320     EXPECT_EQ(completionCode, payload_ptr[0]);
321     EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]);
322     EXPECT_EQ(2, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte)]);
323     EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte) +
324                              sizeof(types[1].byte)]);
325 }
326 
TEST(GetPLDMTypes,testGoodDecodeResponse)327 TEST(GetPLDMTypes, testGoodDecodeResponse)
328 {
329     std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
330     responseMsg[1 + hdrSize] = 1;
331     responseMsg[2 + hdrSize] = 2;
332     responseMsg[3 + hdrSize] = 3;
333     std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
334 
335     uint8_t completion_code;
336     responseMsg[hdrSize] = PLDM_SUCCESS;
337 
338     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
339     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
340 
341     auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize,
342                                     &completion_code, outTypes.data());
343 
344     EXPECT_EQ(rc, PLDM_SUCCESS);
345     EXPECT_EQ(completion_code, PLDM_SUCCESS);
346     EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte);
347     EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte);
348     EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte);
349 }
350 
TEST(GetPLDMTypes,testBadDecodeResponse)351 TEST(GetPLDMTypes, testBadDecodeResponse)
352 {
353     std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
354     responseMsg[1 + hdrSize] = 1;
355     responseMsg[2 + hdrSize] = 2;
356     responseMsg[3 + hdrSize] = 3;
357     std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
358 
359     uint8_t retcompletion_code = 0;
360     responseMsg[hdrSize] = PLDM_SUCCESS;
361 
362     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
363     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
364 
365     auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize - 1,
366                                     &retcompletion_code, outTypes.data());
367 
368     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
369 }
370 
TEST(GetPLDMCommands,testGoodDecodeResponse)371 TEST(GetPLDMCommands, testGoodDecodeResponse)
372 {
373     std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
374     responseMsg[1 + hdrSize] = 1;
375     responseMsg[2 + hdrSize] = 2;
376     responseMsg[3 + hdrSize] = 3;
377     std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
378 
379     uint8_t completion_code;
380     responseMsg[hdrSize] = PLDM_SUCCESS;
381 
382     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
383     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
384 
385     auto rc = decode_get_commands_resp(response, responseMsg.size() - hdrSize,
386                                        &completion_code, outTypes.data());
387 
388     EXPECT_EQ(rc, PLDM_SUCCESS);
389     EXPECT_EQ(completion_code, PLDM_SUCCESS);
390     EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte);
391     EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte);
392     EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte);
393 }
394 
TEST(GetPLDMCommands,testBadDecodeResponse)395 TEST(GetPLDMCommands, testBadDecodeResponse)
396 {
397     std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
398     responseMsg[1 + hdrSize] = 1;
399     responseMsg[2 + hdrSize] = 2;
400     responseMsg[3 + hdrSize] = 3;
401     std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
402 
403     uint8_t retcompletion_code = 0;
404     responseMsg[hdrSize] = PLDM_SUCCESS;
405 
406     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
407     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
408 
409     auto rc =
410         decode_get_commands_resp(response, responseMsg.size() - hdrSize - 1,
411                                  &retcompletion_code, outTypes.data());
412 
413     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
414 }
415 
TEST(GetPLDMVersion,testGoodEncodeRequest)416 TEST(GetPLDMVersion, testGoodEncodeRequest)
417 {
418     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
419         requestMsg{};
420     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
421     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
422     uint8_t pldmType = 0x03;
423     uint32_t transferHandle = 0x0;
424     uint8_t opFlag = 0x01;
425 
426     auto rc =
427         encode_get_version_req(0, transferHandle, opFlag, pldmType, request);
428     EXPECT_EQ(rc, PLDM_SUCCESS);
429     EXPECT_EQ(
430         0, memcmp(request->payload, &transferHandle, sizeof(transferHandle)));
431     EXPECT_EQ(0, memcmp(request->payload + sizeof(transferHandle), &opFlag,
432                         sizeof(opFlag)));
433     EXPECT_EQ(0,
434               memcmp(request->payload + sizeof(transferHandle) + sizeof(opFlag),
435                      &pldmType, sizeof(pldmType)));
436 }
437 
TEST(GetPLDMVersion,testBadEncodeRequest)438 TEST(GetPLDMVersion, testBadEncodeRequest)
439 {
440     uint8_t pldmType = 0x03;
441     uint32_t transferHandle = 0x0;
442     uint8_t opFlag = 0x01;
443 
444     auto rc =
445         encode_get_version_req(0, transferHandle, opFlag, pldmType, nullptr);
446 
447     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
448 }
449 
TEST(GetPLDMVersion,testEncodeResponse)450 TEST(GetPLDMVersion, testEncodeResponse)
451 {
452     uint8_t completionCode = 0;
453     uint32_t transferHandle = 0;
454     uint8_t flag = PLDM_START_AND_END;
455     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES>
456         responseMsg{};
457     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
458     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
459     ver32_t version = {0xff, 0xff, 0xff, 0xff};
460 
461     auto rc = encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END,
462                                       &version, sizeof(ver32_t), response);
463 
464     EXPECT_EQ(rc, PLDM_SUCCESS);
465     EXPECT_EQ(completionCode, response->payload[0]);
466     EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]),
467                         &transferHandle, sizeof(transferHandle)));
468     EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
469                             sizeof(transferHandle),
470                         &flag, sizeof(flag)));
471     EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
472                             sizeof(transferHandle) + sizeof(flag),
473                         &version, sizeof(version)));
474 }
475 
TEST(GetPLDMVersion,testDecodeRequest)476 TEST(GetPLDMVersion, testDecodeRequest)
477 {
478     std::array<uint8_t, hdrSize + PLDM_GET_VERSION_REQ_BYTES> requestMsg{};
479     uint32_t transferHandle = 0x0;
480     uint32_t retTransferHandle = 0x0;
481     uint8_t flag = PLDM_GET_FIRSTPART;
482     uint8_t retFlag = PLDM_GET_FIRSTPART;
483     uint8_t pldmType = PLDM_BASE;
484     uint8_t retType = PLDM_BASE;
485 
486     memcpy(requestMsg.data() + hdrSize, &transferHandle,
487            sizeof(transferHandle));
488     memcpy(requestMsg.data() + sizeof(transferHandle) + hdrSize, &flag,
489            sizeof(flag));
490     memcpy(requestMsg.data() + sizeof(transferHandle) + sizeof(flag) + hdrSize,
491            &pldmType, sizeof(pldmType));
492 
493     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
494     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
495 
496     auto rc = decode_get_version_req(request, requestMsg.size() - hdrSize,
497                                      &retTransferHandle, &retFlag, &retType);
498 
499     EXPECT_EQ(rc, PLDM_SUCCESS);
500     EXPECT_EQ(transferHandle, retTransferHandle);
501     EXPECT_EQ(flag, retFlag);
502     EXPECT_EQ(pldmType, retType);
503 }
504 
TEST(GetPLDMVersion,testDecodeResponse)505 TEST(GetPLDMVersion, testDecodeResponse)
506 {
507     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES>
508         responseMsg{};
509     uint32_t transferHandle = 0x0;
510     uint32_t retTransferHandle = 0x0;
511     uint8_t flag = PLDM_START_AND_END;
512     uint8_t retFlag = PLDM_START_AND_END;
513     uint8_t completionCode = 0;
514     ver32_t version = {0xff, 0xff, 0xff, 0xff};
515     ver32_t versionOut;
516     uint8_t completion_code;
517 
518     memcpy(responseMsg.data() + sizeof(completionCode) + hdrSize,
519            &transferHandle, sizeof(transferHandle));
520     memcpy(responseMsg.data() + sizeof(completionCode) +
521                sizeof(transferHandle) + hdrSize,
522            &flag, sizeof(flag));
523     memcpy(responseMsg.data() + sizeof(completionCode) +
524                sizeof(transferHandle) + sizeof(flag) + hdrSize,
525            &version, sizeof(version));
526 
527     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
528     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
529 
530     auto rc = decode_get_version_resp(response, responseMsg.size() - hdrSize,
531                                       &completion_code, &retTransferHandle,
532                                       &retFlag, &versionOut);
533     EXPECT_EQ(rc, PLDM_SUCCESS);
534     EXPECT_EQ(transferHandle, retTransferHandle);
535     EXPECT_EQ(flag, retFlag);
536 
537     EXPECT_EQ(versionOut.major, version.major);
538     EXPECT_EQ(versionOut.minor, version.minor);
539     EXPECT_EQ(versionOut.update, version.update);
540     EXPECT_EQ(versionOut.alpha, version.alpha);
541 }
542 
TEST(GetTID,testEncodeRequest)543 TEST(GetTID, testEncodeRequest)
544 {
545     pldm_msg request{};
546 
547     auto rc = encode_get_tid_req(0, &request);
548     ASSERT_EQ(rc, PLDM_SUCCESS);
549 }
550 
TEST(GetTID,testEncodeResponse)551 TEST(GetTID, testEncodeResponse)
552 {
553     uint8_t completionCode = 0;
554     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES>
555         responseMsg{};
556     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
557     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
558     uint8_t tid = 1;
559 
560     auto rc = encode_get_tid_resp(0, PLDM_SUCCESS, tid, response);
561     EXPECT_EQ(rc, PLDM_SUCCESS);
562     uint8_t* payload = response->payload;
563     EXPECT_EQ(completionCode, payload[0]);
564     EXPECT_EQ(1, payload[sizeof(completionCode)]);
565 }
566 
TEST(GetTID,testDecodeResponse)567 TEST(GetTID, testDecodeResponse)
568 {
569     std::array<uint8_t, hdrSize + PLDM_GET_TID_RESP_BYTES> responseMsg{};
570     responseMsg[1 + hdrSize] = 1;
571 
572     uint8_t tid;
573     uint8_t completion_code;
574     responseMsg[hdrSize] = PLDM_SUCCESS;
575 
576     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
577     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
578 
579     auto rc = decode_get_tid_resp(response, responseMsg.size() - hdrSize,
580                                   &completion_code, &tid);
581 
582     EXPECT_EQ(rc, PLDM_SUCCESS);
583     EXPECT_EQ(completion_code, PLDM_SUCCESS);
584     EXPECT_EQ(tid, 1);
585 }
586 
TEST(DecodeMultipartReceiveRequest,testDecodeRequestPass)587 TEST(DecodeMultipartReceiveRequest, testDecodeRequestPass)
588 {
589     constexpr uint8_t kPldmType = PLDM_BASE;
590     constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
591     constexpr uint32_t kTransferCtx = 0x01;
592     constexpr uint32_t kTransferHandle = 0x10;
593     constexpr uint32_t kSectionOffset = 0x0;
594     constexpr uint32_t kSectionLength = 0x10;
595 
596     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
597     PLDM_MSGBUF_RW_DEFINE_P(buf);
598     int rc;
599 
600     // Header values don't matter for this test.
601     rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
602                                 msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
603     ASSERT_EQ(rc, 0);
604     pldm_msgbuf_insert_uint8(buf, kPldmType);
605     pldm_msgbuf_insert_uint8(buf, kFlag);
606     pldm_msgbuf_insert_uint32(buf, kTransferCtx);
607     pldm_msgbuf_insert_uint32(buf, kTransferHandle);
608     pldm_msgbuf_insert_uint32(buf, kSectionOffset);
609     pldm_msgbuf_insert_uint32(buf, kSectionLength);
610     rc = pldm_msgbuf_complete(buf);
611     ASSERT_EQ(rc, 0);
612 
613     uint8_t pldm_type;
614     uint8_t flag;
615     uint32_t transfer_ctx;
616     uint32_t transfer_handle;
617     uint32_t section_offset;
618     uint32_t section_length;
619     rc = decode_multipart_receive_req(
620         msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag, &transfer_ctx,
621         &transfer_handle, &section_offset, &section_length);
622 
623     ASSERT_EQ(rc, PLDM_SUCCESS);
624     EXPECT_EQ(pldm_type, kPldmType);
625     EXPECT_EQ(flag, kFlag);
626     EXPECT_EQ(transfer_ctx, kTransferCtx);
627     EXPECT_EQ(transfer_handle, kTransferHandle);
628     EXPECT_EQ(section_offset, kSectionOffset);
629     EXPECT_EQ(section_length, kSectionLength);
630 }
631 
TEST(DecodeMultipartReceiveRequest,testDecodeRequestFailNullData)632 TEST(DecodeMultipartReceiveRequest, testDecodeRequestFailNullData)
633 {
634     EXPECT_EQ(decode_multipart_receive_req(NULL, 0, NULL, NULL, NULL, NULL,
635                                            NULL, NULL),
636               PLDM_ERROR_INVALID_DATA);
637 }
638 
TEST(DecodeMultipartReceiveRequest,testDecodeRequestFailBadLength)639 TEST(DecodeMultipartReceiveRequest, testDecodeRequestFailBadLength)
640 {
641     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1);
642     uint8_t pldm_type;
643     uint8_t flag;
644     uint32_t transfer_ctx;
645     uint32_t transfer_handle;
646     uint32_t section_offset;
647     uint32_t section_length;
648 
649     memset(msg, 0, PLDM_MSG_SIZE(PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1));
650     EXPECT_EQ(decode_multipart_receive_req(
651                   msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES + 1, &pldm_type, &flag,
652                   &transfer_ctx, &transfer_handle, &section_offset,
653                   &section_length),
654               PLDM_ERROR_INVALID_DATA);
655 }
656 
TEST(DecodeMultipartReceiveRequest,testDecodeRequestFailBadPldmType)657 TEST(DecodeMultipartReceiveRequest, testDecodeRequestFailBadPldmType)
658 {
659     constexpr uint8_t kPldmType = 0xff;
660     constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
661 
662     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
663     PLDM_MSGBUF_RW_DEFINE_P(buf);
664     int rc;
665 
666     // Header values don't matter for this test.
667     rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
668                                 msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
669     ASSERT_EQ(rc, 0);
670     pldm_msgbuf_insert_uint8(buf, kPldmType);
671     pldm_msgbuf_insert_uint8(buf, kFlag);
672     rc = pldm_msgbuf_complete(buf);
673     ASSERT_EQ(rc, 0);
674 
675     uint8_t pldm_type;
676     uint8_t flag;
677     uint32_t transfer_ctx;
678     uint32_t transfer_handle;
679     uint32_t section_offset;
680     uint32_t section_length;
681 
682     EXPECT_EQ(decode_multipart_receive_req(
683                   msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag,
684                   &transfer_ctx, &transfer_handle, &section_offset,
685                   &section_length),
686               PLDM_ERROR_INVALID_PLDM_TYPE);
687 }
688 
TEST(DecodeMultipartReceiveRequest,testDecodeRequestFailBadTransferFlag)689 TEST(DecodeMultipartReceiveRequest, testDecodeRequestFailBadTransferFlag)
690 {
691     constexpr uint8_t kPldmType = PLDM_BASE;
692     constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10;
693 
694     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
695     PLDM_MSGBUF_RW_DEFINE_P(buf);
696     int rc;
697 
698     // Header values don't matter for this test.
699     rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
700                                 msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
701     ASSERT_EQ(rc, 0);
702     pldm_msgbuf_insert_uint8(buf, kPldmType);
703     pldm_msgbuf_insert_uint8(buf, kFlag);
704     rc = pldm_msgbuf_complete(buf);
705     ASSERT_EQ(rc, 0);
706 
707     uint8_t pldm_type;
708     uint8_t flag;
709     uint32_t transfer_ctx;
710     uint32_t transfer_handle;
711     uint32_t section_offset;
712     uint32_t section_length;
713 
714     EXPECT_EQ(decode_multipart_receive_req(
715                   msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag,
716                   &transfer_ctx, &transfer_handle, &section_offset,
717                   &section_length),
718               PLDM_ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION);
719 }
720 
TEST(DecodeMultipartReceiveRequest,testDecodeRequestFailBadHandle)721 TEST(DecodeMultipartReceiveRequest, testDecodeRequestFailBadHandle)
722 {
723     constexpr uint8_t kPldmType = PLDM_BASE;
724     constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
725     constexpr uint32_t kTransferCtx = 0x01;
726     constexpr uint32_t kTransferHandle = 0x0;
727     constexpr uint32_t kSectionOffset = 0x100;
728 
729     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
730     PLDM_MSGBUF_RW_DEFINE_P(buf);
731     int rc;
732 
733     // Header values don't matter for this test.
734     rc = pldm_msgbuf_init_errno(buf, PLDM_MULTIPART_RECEIVE_REQ_BYTES,
735                                 msg->payload, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
736     ASSERT_EQ(rc, 0);
737     pldm_msgbuf_insert_uint8(buf, kPldmType);
738     pldm_msgbuf_insert_uint8(buf, kFlag);
739     pldm_msgbuf_insert_uint32(buf, kTransferCtx);
740     pldm_msgbuf_insert_uint32(buf, kTransferHandle);
741     pldm_msgbuf_insert_uint32(buf, kSectionOffset);
742     rc = pldm_msgbuf_complete(buf);
743     ASSERT_EQ(rc, 0);
744 
745     uint8_t pldm_type;
746     uint8_t flag;
747     uint32_t transfer_ctx;
748     uint32_t transfer_handle;
749     uint32_t section_offset;
750     uint32_t section_length;
751     EXPECT_EQ(decode_multipart_receive_req(
752                   msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES, &pldm_type, &flag,
753                   &transfer_ctx, &transfer_handle, &section_offset,
754                   &section_length),
755               PLDM_ERROR_INVALID_DATA);
756 }
757 
758 #ifdef LIBPLDM_API_TESTING
TEST(EncodeMultipartReceiveRequest,GoodTest)759 TEST(EncodeMultipartReceiveRequest, GoodTest)
760 {
761     uint8_t instance_id = 0;
762 
763     const struct pldm_base_multipart_receive_req req_data = {
764         PLDM_BASE, PLDM_XFER_FIRST_PART, 0x01, 0x10, 0x00, 0x10};
765 
766     static constexpr const size_t requestMsgLength =
767         PLDM_MULTIPART_RECEIVE_REQ_BYTES;
768 
769     std::array<uint8_t, requestMsgLength> requestMsg = {
770         PLDM_BASE, PLDM_XFER_FIRST_PART,
771         0x01,      0x00,
772         0x00,      0x00,
773         0x10,      0x00,
774         0x00,      0x00,
775         0x00,      0x00,
776         0x00,      0x00,
777         0x10,      0x00,
778         0x00,      0x00};
779 
780     PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength);
781     size_t payload_length = requestMsgLength;
782     auto rc = encode_pldm_base_multipart_receive_req(
783         instance_id, &req_data, requestPtr, &payload_length);
784 
785     ASSERT_EQ(rc, 0);
786     EXPECT_EQ(
787         0, memcmp(requestPtr->payload, requestMsg.data(), sizeof(requestMsg)));
788     EXPECT_EQ(payload_length, requestMsgLength);
789 }
790 #endif
791 
792 #ifdef LIBPLDM_API_TESTING
TEST(EncodeMultipartReceiveRequest,BadTestUnAllocatedPtrParams)793 TEST(EncodeMultipartReceiveRequest, BadTestUnAllocatedPtrParams)
794 {
795     uint8_t instance_id = 0;
796     int rc;
797 
798     const struct pldm_base_multipart_receive_req req_data = {
799         PLDM_BASE, PLDM_XFER_FIRST_PART, 0x01, 0x10, 0x00, 0x10};
800 
801     static constexpr const size_t requestMsgLength =
802         PLDM_MULTIPART_RECEIVE_REQ_BYTES;
803 
804     PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength);
805     size_t payload_length = requestMsgLength;
806     rc = encode_pldm_base_multipart_receive_req(instance_id, nullptr,
807                                                 requestPtr, &payload_length);
808     EXPECT_EQ(rc, -EINVAL);
809 
810     rc = encode_pldm_base_multipart_receive_req(instance_id, &req_data, nullptr,
811                                                 &payload_length);
812     EXPECT_EQ(rc, -EINVAL);
813 }
814 #endif
815 
816 #ifdef LIBPLDM_API_TESTING
TEST(EncodeMultipartReceiveRequest,BadTestInvalidExpectedOutputMsgLength)817 TEST(EncodeMultipartReceiveRequest, BadTestInvalidExpectedOutputMsgLength)
818 {
819     uint8_t instance_id = 0;
820     int rc;
821 
822     const struct pldm_base_multipart_receive_req req_data = {
823         PLDM_BASE, PLDM_XFER_FIRST_PART, 0x01, 0x10, 0x00, 0x10};
824 
825     static constexpr const size_t requestMsgLength =
826         PLDM_MULTIPART_RECEIVE_REQ_BYTES;
827 
828     PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength);
829     size_t payload_length = 1;
830     rc = encode_pldm_base_multipart_receive_req(instance_id, &req_data,
831                                                 requestPtr, &payload_length);
832     EXPECT_EQ(rc, -EOVERFLOW);
833 }
834 #endif
835 
836 #ifdef LIBPLDM_API_TESTING
TEST(DecodeMultipartReceiveResponse,GoodTest)837 TEST(DecodeMultipartReceiveResponse, GoodTest)
838 {
839     uint8_t completionCode = PLDM_SUCCESS;
840     uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END;
841     uint32_t nextDataTransferHandle = 0x15;
842     static constexpr const uint32_t dataLength = 9;
843     std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
844     uint32_t dataIntegrityChecksum = 0x3C;
845 
846     struct pldm_base_multipart_receive_resp resp_data = {};
847 
848     PLDM_MSGBUF_RW_DEFINE_P(buf);
849     int rc;
850 
851     static constexpr const size_t payload_length =
852         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength +
853         sizeof(dataIntegrityChecksum);
854     PLDM_MSG_DEFINE_P(responseMsg, payload_length);
855 
856     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length);
857     ASSERT_EQ(rc, 0);
858 
859     pldm_msgbuf_insert_uint8(buf, completionCode);
860     pldm_msgbuf_insert_uint8(buf, transferFlag);
861     pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle);
862     pldm_msgbuf_insert_uint32(buf, dataLength);
863     rc = pldm_msgbuf_insert_array_uint8(buf, dataLength, data.data(),
864                                         dataLength);
865     EXPECT_EQ(rc, 0);
866     pldm_msgbuf_insert_uint32(buf, dataIntegrityChecksum);
867 
868     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
869 
870     uint32_t respDataIntegrityChecksum = 0;
871 
872     rc = decode_pldm_base_multipart_receive_resp(
873         responseMsg, payload_length, &resp_data, &respDataIntegrityChecksum);
874 
875     ASSERT_EQ(rc, 0);
876     EXPECT_EQ(resp_data.completion_code, completionCode);
877     EXPECT_EQ(resp_data.transfer_flag, transferFlag);
878     EXPECT_EQ(resp_data.next_transfer_handle, nextDataTransferHandle);
879     EXPECT_EQ(resp_data.data.length, dataLength);
880     EXPECT_EQ(0,
881               memcmp(data.data(), resp_data.data.ptr, resp_data.data.length));
882     EXPECT_EQ(respDataIntegrityChecksum, dataIntegrityChecksum);
883 }
884 #endif
885 
886 #ifdef LIBPLDM_API_TESTING
TEST(DecodeMultipartReceiveResponse,BadTestUnAllocatedPtrParams)887 TEST(DecodeMultipartReceiveResponse, BadTestUnAllocatedPtrParams)
888 {
889     uint8_t completionCode = PLDM_SUCCESS;
890     uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END;
891     uint32_t nextDataTransferHandle = 0x15;
892     static constexpr const uint32_t dataLength = 9;
893     std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
894     uint32_t dataIntegrityChecksum = 0x3C;
895 
896     struct pldm_base_multipart_receive_resp resp_data = {};
897 
898     PLDM_MSGBUF_RW_DEFINE_P(buf);
899     int rc;
900 
901     static constexpr const size_t payload_length =
902         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength +
903         sizeof(dataIntegrityChecksum);
904     PLDM_MSG_DEFINE_P(responseMsg, payload_length);
905 
906     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length);
907     ASSERT_EQ(rc, 0);
908 
909     pldm_msgbuf_insert_uint8(buf, completionCode);
910     pldm_msgbuf_insert_uint8(buf, transferFlag);
911     pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle);
912     pldm_msgbuf_insert_uint32(buf, dataLength);
913     rc = pldm_msgbuf_insert_array_uint8(buf, dataLength, data.data(),
914                                         dataLength);
915     EXPECT_EQ(rc, 0);
916     pldm_msgbuf_insert_uint32(buf, dataIntegrityChecksum);
917 
918     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
919 
920     uint32_t respDataIntegrityChecksum = 0;
921 
922     rc = decode_pldm_base_multipart_receive_resp(
923         nullptr, payload_length, &resp_data, &respDataIntegrityChecksum);
924 
925     EXPECT_EQ(rc, -EINVAL);
926 
927     rc = decode_pldm_base_multipart_receive_resp(
928         responseMsg, payload_length, nullptr, &respDataIntegrityChecksum);
929 
930     EXPECT_EQ(rc, -EINVAL);
931 }
932 #endif
933 
934 #ifdef LIBPLDM_API_TESTING
TEST(DecodeMultipartReceiveResponse,BadTestInvalidExpectedInputMsgLength)935 TEST(DecodeMultipartReceiveResponse, BadTestInvalidExpectedInputMsgLength)
936 {
937     uint8_t completionCode = PLDM_SUCCESS;
938     uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END;
939     uint32_t nextDataTransferHandle = 0x15;
940     static constexpr const uint32_t dataLength = 9;
941     std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
942     uint32_t dataIntegrityChecksum = 0x3C;
943 
944     struct pldm_base_multipart_receive_resp resp_data = {};
945 
946     PLDM_MSGBUF_RW_DEFINE_P(buf);
947     int rc;
948 
949     static constexpr const size_t payload_length =
950         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength +
951         sizeof(dataIntegrityChecksum);
952     PLDM_MSG_DEFINE_P(responseMsg, payload_length);
953 
954     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length);
955     ASSERT_EQ(rc, 0);
956 
957     pldm_msgbuf_insert_uint8(buf, completionCode);
958     pldm_msgbuf_insert_uint8(buf, transferFlag);
959     pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle);
960     pldm_msgbuf_insert_uint32(buf, dataLength);
961     rc = pldm_msgbuf_insert_array_uint8(buf, dataLength, data.data(),
962                                         dataLength);
963     EXPECT_EQ(rc, 0);
964     pldm_msgbuf_insert_uint32(buf, dataIntegrityChecksum);
965 
966     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
967 
968     uint32_t respDataIntegrityChecksum = 0;
969 
970     rc = decode_pldm_base_multipart_receive_resp(responseMsg, 0, &resp_data,
971                                                  &respDataIntegrityChecksum);
972 
973     EXPECT_EQ(rc, -EOVERFLOW);
974 }
975 #endif
976 
977 #ifdef LIBPLDM_API_TESTING
TEST(DecodeMultipartReceiveResponse,BadTestRedundantCheckSum)978 TEST(DecodeMultipartReceiveResponse, BadTestRedundantCheckSum)
979 {
980     uint8_t completionCode = PLDM_SUCCESS;
981     uint8_t transferFlag =
982         PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_ACK_COMPLETION;
983     uint32_t nextDataTransferHandle = 0x00;
984     static constexpr const uint32_t dataLength = 0;
985     uint32_t dataIntegrityChecksum = 0x2c;
986 
987     struct pldm_base_multipart_receive_resp resp_data = {};
988 
989     PLDM_MSGBUF_RW_DEFINE_P(buf);
990     int rc;
991 
992     /*
993      * Data field is omitted in a response with ACKNOWLEDGE_COMPLETION
994      * TransferFlag. Intentionally insert a DataIntegrityChecksum field to the
995      * response message
996      */
997 
998     static constexpr const size_t payload_length =
999         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength +
1000         sizeof(dataIntegrityChecksum);
1001     PLDM_MSG_DEFINE_P(responseMsg, payload_length);
1002 
1003     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length);
1004     ASSERT_EQ(rc, 0);
1005 
1006     pldm_msgbuf_insert_uint8(buf, completionCode);
1007     pldm_msgbuf_insert_uint8(buf, transferFlag);
1008     pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle);
1009     pldm_msgbuf_insert_uint32(buf, dataLength);
1010     pldm_msgbuf_insert_uint32(buf, dataIntegrityChecksum);
1011 
1012     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1013 
1014     uint32_t respDataIntegrityChecksum = 0;
1015 
1016     rc = decode_pldm_base_multipart_receive_resp(
1017         responseMsg, payload_length, &resp_data, &respDataIntegrityChecksum);
1018 
1019     /*
1020      * pldm_msgbuf_complete_consumed() returns -EBADMSG as
1021      * decode_pldm_base_multipart_receive_resp() didn't consume all the input
1022      * message buffer.
1023      */
1024     EXPECT_EQ(rc, -EBADMSG);
1025 }
1026 #endif
1027 
1028 #ifdef LIBPLDM_API_TESTING
TEST(DecodeMultipartReceiveResponse,BadTestMissingCheckSum)1029 TEST(DecodeMultipartReceiveResponse, BadTestMissingCheckSum)
1030 {
1031     uint8_t completionCode = PLDM_SUCCESS;
1032     uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_END;
1033     uint32_t nextDataTransferHandle = 0x00;
1034     static constexpr const uint32_t dataLength = 9;
1035     std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
1036 
1037     struct pldm_base_multipart_receive_resp resp_data = {};
1038 
1039     PLDM_MSGBUF_RW_DEFINE_P(buf);
1040     int rc;
1041 
1042     /*
1043      * Intentionally do not insert DataIntegrityChecksum field to the response
1044      * message
1045      */
1046     static constexpr const size_t payload_length =
1047         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength;
1048     PLDM_MSG_DEFINE_P(responseMsg, payload_length);
1049 
1050     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length);
1051     ASSERT_EQ(rc, 0);
1052 
1053     pldm_msgbuf_insert_uint8(buf, completionCode);
1054     pldm_msgbuf_insert_uint8(buf, transferFlag);
1055     pldm_msgbuf_insert_uint32(buf, nextDataTransferHandle);
1056     pldm_msgbuf_insert_uint32(buf, dataLength);
1057     rc = pldm_msgbuf_insert_array_uint8(buf, dataLength, data.data(),
1058                                         dataLength);
1059     EXPECT_EQ(rc, 0);
1060 
1061     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1062 
1063     uint32_t respDataIntegrityChecksum = 0;
1064 
1065     rc = decode_pldm_base_multipart_receive_resp(
1066         responseMsg, payload_length, &resp_data, &respDataIntegrityChecksum);
1067 
1068     /*
1069      * pldm_msgbuf_extract_p() returns -EOVERFLOW as
1070      * decode_pldm_base_multipart_receive_resp() tried to consume more than
1071      * the expected input message buffer.
1072      */
1073     EXPECT_EQ(rc, -EOVERFLOW);
1074 }
1075 #endif
1076 
1077 #ifdef LIBPLDM_API_TESTING
TEST(EncodeMultipartReceiveResponse,GoodTestWithChecksum)1078 TEST(EncodeMultipartReceiveResponse, GoodTestWithChecksum)
1079 {
1080     uint8_t instance_id = 0;
1081     uint8_t completionCode = PLDM_SUCCESS;
1082     uint8_t transferFlag =
1083         PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START_AND_END;
1084     uint32_t nextDataTransferHandle = 0x15;
1085     static constexpr const uint32_t dataLength = 9;
1086     std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
1087     uint32_t dataIntegrityChecksum = 0x3C;
1088     static constexpr const size_t responseMsgLength =
1089         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength +
1090         sizeof(dataIntegrityChecksum);
1091     size_t payload_length = responseMsgLength;
1092 
1093     struct variable_field payload = {data.data(), dataLength};
1094     struct pldm_base_multipart_receive_resp resp_data = {
1095         completionCode, transferFlag, nextDataTransferHandle, payload};
1096     std::array<uint8_t, responseMsgLength> responseMsg = {
1097         completionCode,
1098         transferFlag,
1099         0x15, // nextDataTransferHandle
1100         0x00,
1101         0x00,
1102         0x00,
1103         0x09, // dataLength
1104         0x00,
1105         0x00,
1106         0x00,
1107         0x1, // data
1108         0x2,
1109         0x3,
1110         0x4,
1111         0x5,
1112         0x6,
1113         0x7,
1114         0x8,
1115         0x9,
1116         0x3c, // dataIntegrityChecksum
1117         0x00,
1118         0x00,
1119         0x00};
1120 
1121     PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength);
1122     int rc;
1123 
1124     rc = encode_base_multipart_receive_resp(instance_id, &resp_data,
1125                                             dataIntegrityChecksum, responsePtr,
1126                                             &payload_length);
1127 
1128     ASSERT_EQ(0, rc);
1129     EXPECT_EQ(0, memcmp(responsePtr->payload, responseMsg.data(),
1130                         sizeof(responseMsg)));
1131     EXPECT_EQ(payload_length, responseMsgLength);
1132 }
1133 #endif
1134 
1135 #ifdef LIBPLDM_API_TESTING
TEST(EncodeMultipartReceiveResponse,GoodTestWithoutChecksum)1136 TEST(EncodeMultipartReceiveResponse, GoodTestWithoutChecksum)
1137 {
1138     uint8_t instance_id = 0;
1139     uint8_t completionCode = PLDM_SUCCESS;
1140     uint8_t transferFlag =
1141         PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_ACK_COMPLETION;
1142     uint32_t nextDataTransferHandle = 0;
1143     static constexpr const uint32_t dataLength = 0;
1144     static constexpr const size_t responseMsgLength =
1145         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength;
1146     size_t payload_length = responseMsgLength;
1147 
1148     struct variable_field payload = {nullptr, dataLength};
1149     struct pldm_base_multipart_receive_resp resp_data = {
1150         completionCode, transferFlag, nextDataTransferHandle, payload};
1151     std::array<uint8_t, responseMsgLength> responseMsg = {
1152         completionCode, transferFlag,
1153         0x00, // nextDataTransferHandle
1154         0x00,           0x00,         0x00,
1155         0x00, // dataLength
1156         0x00,           0x00,         0x00};
1157 
1158     PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength);
1159     int rc;
1160 
1161     rc = encode_base_multipart_receive_resp(instance_id, &resp_data, 0,
1162                                             responsePtr, &payload_length);
1163 
1164     ASSERT_EQ(0, rc);
1165     EXPECT_EQ(0, memcmp(responsePtr->payload, responseMsg.data(),
1166                         sizeof(responseMsg)));
1167     EXPECT_EQ(payload_length, responseMsgLength);
1168 }
1169 #endif
1170 
1171 #ifdef LIBPLDM_API_TESTING
TEST(EncodeMultipartReceiveResponse,GoodTestCompletionCode)1172 TEST(EncodeMultipartReceiveResponse, GoodTestCompletionCode)
1173 {
1174     uint8_t instance_id = 0;
1175     uint8_t completionCode = PLDM_MULTIPART_RECEIVE_NEGOTIATION_INCOMPLETE;
1176     uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START;
1177     uint32_t nextDataTransferHandle = 0x16;
1178     static constexpr const uint32_t dataLength = 9;
1179     std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
1180     static constexpr const size_t responseMsgLength =
1181         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength;
1182     size_t payload_length = responseMsgLength;
1183 
1184     struct variable_field payload = {data.data(), dataLength};
1185     struct pldm_base_multipart_receive_resp resp_data = {
1186         completionCode, transferFlag, nextDataTransferHandle, payload};
1187     std::array<uint8_t, 1> responseMsg = {completionCode};
1188 
1189     PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength);
1190     int rc;
1191 
1192     rc = encode_base_multipart_receive_resp(instance_id, &resp_data, 0,
1193                                             responsePtr, &payload_length);
1194 
1195     ASSERT_EQ(0, rc);
1196     EXPECT_EQ(0, memcmp(responsePtr->payload, responseMsg.data(),
1197                         sizeof(responseMsg)));
1198     EXPECT_EQ(payload_length, 1ul);
1199 }
1200 #endif
1201 
1202 #ifdef LIBPLDM_API_TESTING
TEST(EncodeMultipartReceiveResponse,BadTestUnAllocatedParams)1203 TEST(EncodeMultipartReceiveResponse, BadTestUnAllocatedParams)
1204 {
1205     uint8_t instance_id = 0;
1206     uint8_t completionCode = PLDM_SUCCESS;
1207     uint8_t transferFlag =
1208         PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START_AND_END;
1209     uint32_t nextDataTransferHandle = 0x15;
1210     static constexpr const uint32_t dataLength = 9;
1211     std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
1212     uint32_t dataIntegrityChecksum = 0x3C;
1213     static constexpr const size_t responseMsgLength =
1214         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES + dataLength +
1215         sizeof(dataIntegrityChecksum);
1216     size_t payload_length = responseMsgLength;
1217 
1218     struct variable_field payload = {data.data(), dataLength};
1219     struct pldm_base_multipart_receive_resp resp_data = {
1220         completionCode, transferFlag, nextDataTransferHandle, payload};
1221 
1222     PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength);
1223     int rc;
1224 
1225     rc = encode_base_multipart_receive_resp(instance_id, nullptr,
1226                                             dataIntegrityChecksum, responsePtr,
1227                                             &payload_length);
1228     EXPECT_EQ(rc, -EINVAL);
1229 
1230     rc = encode_base_multipart_receive_resp(instance_id, &resp_data,
1231                                             dataIntegrityChecksum, nullptr,
1232                                             &payload_length);
1233     EXPECT_EQ(rc, -EINVAL);
1234 
1235     rc = encode_base_multipart_receive_resp(
1236         instance_id, &resp_data, dataIntegrityChecksum, responsePtr, nullptr);
1237     EXPECT_EQ(rc, -EINVAL);
1238 
1239     resp_data.data.ptr = nullptr;
1240     rc = encode_base_multipart_receive_resp(instance_id, &resp_data,
1241                                             dataIntegrityChecksum, responsePtr,
1242                                             &payload_length);
1243     EXPECT_EQ(rc, -EINVAL);
1244 }
1245 #endif
1246 
1247 #ifdef LIBPLDM_API_TESTING
TEST(EncodeMultipartReceiveResponse,BadTestInvalidExpectedOutputMsgLength)1248 TEST(EncodeMultipartReceiveResponse, BadTestInvalidExpectedOutputMsgLength)
1249 {
1250     uint8_t instance_id = 0;
1251     uint8_t completionCode = PLDM_SUCCESS;
1252     uint8_t transferFlag = PLDM_BASE_MULTIPART_RECEIVE_TRANSFER_FLAG_START;
1253     uint32_t nextDataTransferHandle = 0x16;
1254     static constexpr const uint32_t dataLength = 9;
1255     std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
1256     static constexpr const size_t responseMsgLength =
1257         PLDM_BASE_MULTIPART_RECEIVE_RESP_MIN_BYTES;
1258     size_t payload_length = responseMsgLength;
1259 
1260     struct variable_field payload = {data.data(), dataLength};
1261     struct pldm_base_multipart_receive_resp resp_data = {
1262         completionCode, transferFlag, nextDataTransferHandle, payload};
1263 
1264     PLDM_MSG_DEFINE_P(responsePtr, responseMsgLength);
1265     int rc;
1266 
1267     rc = encode_base_multipart_receive_resp(instance_id, &resp_data, 0,
1268                                             responsePtr, &payload_length);
1269     EXPECT_EQ(rc, -EOVERFLOW);
1270 }
1271 #endif
1272 
TEST(CcOnlyResponse,testEncode)1273 TEST(CcOnlyResponse, testEncode)
1274 {
1275     struct pldm_msg responseMsg;
1276 
1277     auto rc =
1278         encode_cc_only_resp(0 /*instance id*/, 1 /*pldm type*/, 2 /*command*/,
1279                             3 /*completion code*/, &responseMsg);
1280     EXPECT_EQ(rc, PLDM_SUCCESS);
1281 
1282     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1283     auto p = reinterpret_cast<uint8_t*>(&responseMsg);
1284     EXPECT_THAT(std::vector<uint8_t>(p, p + sizeof(responseMsg)),
1285                 ElementsAreArray({0, 1, 2, 3}));
1286 
1287     rc = encode_cc_only_resp(PLDM_INSTANCE_MAX + 1, 1, 2, 3, &responseMsg);
1288     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1289 
1290     rc = encode_cc_only_resp(0, 1, 2, 3, nullptr);
1291     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1292 }
1293 
TEST(SetTID,testGoodEncodeRequest)1294 TEST(SetTID, testGoodEncodeRequest)
1295 {
1296     uint8_t instanceId = 0;
1297     uint8_t tid = 0x01;
1298     std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
1299     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1300     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
1301 
1302     auto rc = encode_set_tid_req(instanceId, tid, request);
1303     ASSERT_EQ(rc, PLDM_SUCCESS);
1304 
1305     EXPECT_EQ(request->hdr.command, PLDM_SET_TID);
1306     EXPECT_EQ(request->hdr.type, PLDM_BASE);
1307     EXPECT_EQ(request->hdr.request, 1);
1308     EXPECT_EQ(request->hdr.datagram, 0);
1309     EXPECT_EQ(request->hdr.instance_id, instanceId);
1310     EXPECT_EQ(0, memcmp(request->payload, &tid, sizeof(tid)));
1311 }
1312 
TEST(SetTID,testBadEncodeRequest)1313 TEST(SetTID, testBadEncodeRequest)
1314 {
1315     uint8_t tid = 0x01;
1316     std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
1317     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1318     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
1319 
1320     auto rc = encode_set_tid_req(0, tid, nullptr);
1321     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1322 
1323     rc = encode_set_tid_req(0, 0, request);
1324     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1325 
1326     rc = encode_set_tid_req(0, 0xff, request);
1327     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1328 }
1329 
1330 #ifdef LIBPLDM_API_TESTING
TEST(SetTID,testGoodDecodeRequest)1331 TEST(SetTID, testGoodDecodeRequest)
1332 {
1333     uint8_t tid = 0x01;
1334     uint8_t tidOut = 0x00;
1335     std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
1336 
1337     requestMsg[sizeof(pldm_msg_hdr)] = tid;
1338 
1339     pldm_msg* request = new (requestMsg.data()) pldm_msg;
1340     auto rc = decode_set_tid_req(
1341         request, requestMsg.size() - sizeof(pldm_msg_hdr), &tidOut);
1342 
1343     EXPECT_EQ(rc, PLDM_SUCCESS);
1344     EXPECT_EQ(tid, tidOut);
1345 }
1346 #endif
1347 
1348 #ifdef LIBPLDM_API_TESTING
TEST(SetTID,testBadDecodeRequestMsg)1349 TEST(SetTID, testBadDecodeRequestMsg)
1350 {
1351     uint8_t tid = 0x01;
1352     std::array<uint8_t, hdrSize + PLDM_SET_TID_REQ_BYTES> requestMsg{};
1353 
1354     auto rc = decode_set_tid_req(
1355         nullptr, requestMsg.size() - sizeof(pldm_msg_hdr), &tid);
1356 
1357     EXPECT_EQ(rc, -EINVAL);
1358 }
1359 #endif
1360 
1361 #ifdef LIBPLDM_API_TESTING
TEST(SetTID,testBadDecodeRequestTid)1362 TEST(SetTID, testBadDecodeRequestTid)
1363 {
1364     std::array<uint8_t, hdrSize + PLDM_SET_TID_REQ_BYTES> requestMsg{};
1365     pldm_msg* request = new (requestMsg.data()) pldm_msg;
1366 
1367     auto rc = decode_set_tid_req(
1368         request, requestMsg.size() - sizeof(pldm_msg_hdr), nullptr);
1369 
1370     EXPECT_EQ(rc, -EINVAL);
1371 }
1372 #endif
1373 
1374 #ifdef LIBPLDM_API_TESTING
TEST(SetTID,testBadDecodeRequestMsgSize)1375 TEST(SetTID, testBadDecodeRequestMsgSize)
1376 {
1377     std::array<uint8_t, hdrSize + PLDM_SET_TID_REQ_BYTES> requestMsg{};
1378     pldm_msg* request = new (requestMsg.data()) pldm_msg;
1379 
1380     auto rc = decode_set_tid_req(request, -1, nullptr);
1381 
1382     EXPECT_EQ(rc, -EINVAL);
1383 }
1384 #endif
1385 
1386 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateSuccess)1387 TEST(PldmMsgHdr, correlateSuccess)
1388 {
1389     static const struct pldm_msg_hdr req = {
1390         .instance_id = 0,
1391         .reserved = 0,
1392         .datagram = 0,
1393         .request = 1,
1394         .type = 0,
1395         .header_ver = 1,
1396         .command = 0x01,
1397     };
1398     static const struct pldm_msg_hdr resp = {
1399         .instance_id = 0,
1400         .reserved = 0,
1401         .datagram = 0,
1402         .request = 0,
1403         .type = 0,
1404         .header_ver = 1,
1405         .command = 0x01,
1406     };
1407 
1408     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), true);
1409 }
1410 #endif
1411 
1412 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailInstanceID)1413 TEST(PldmMsgHdr, correlateFailInstanceID)
1414 {
1415     static const struct pldm_msg_hdr req = {
1416         .instance_id = 0,
1417         .reserved = 0,
1418         .datagram = 0,
1419         .request = 1,
1420         .type = 0,
1421         .header_ver = 1,
1422         .command = 0x01,
1423     };
1424     static const struct pldm_msg_hdr resp = {
1425         .instance_id = 1,
1426         .reserved = 0,
1427         .datagram = 0,
1428         .request = 0,
1429         .type = 0,
1430         .header_ver = 1,
1431         .command = 0x01,
1432     };
1433 
1434     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
1435 }
1436 #endif
1437 
1438 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailRequest)1439 TEST(PldmMsgHdr, correlateFailRequest)
1440 {
1441     static const struct pldm_msg_hdr req = {
1442         .instance_id = 0,
1443         .reserved = 0,
1444         .datagram = 0,
1445         .request = 1,
1446         .type = 0,
1447         .header_ver = 1,
1448         .command = 0x01,
1449     };
1450     static const struct pldm_msg_hdr resp = {
1451         .instance_id = 0,
1452         .reserved = 0,
1453         .datagram = 0,
1454         .request = 1,
1455         .type = 0,
1456         .header_ver = 1,
1457         .command = 0x01,
1458     };
1459 
1460     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
1461 }
1462 #endif
1463 
1464 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailType)1465 TEST(PldmMsgHdr, correlateFailType)
1466 {
1467     static const struct pldm_msg_hdr req = {
1468         .instance_id = 0,
1469         .reserved = 0,
1470         .datagram = 0,
1471         .request = 1,
1472         .type = 0,
1473         .header_ver = 1,
1474         .command = 0x01,
1475     };
1476     static const struct pldm_msg_hdr resp = {
1477         .instance_id = 0,
1478         .reserved = 0,
1479         .datagram = 0,
1480         .request = 0,
1481         .type = 1,
1482         .header_ver = 1,
1483         .command = 0x01,
1484     };
1485 
1486     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
1487 }
1488 #endif
1489 
1490 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailCommand)1491 TEST(PldmMsgHdr, correlateFailCommand)
1492 {
1493     static const struct pldm_msg_hdr req = {
1494         .instance_id = 0,
1495         .reserved = 0,
1496         .datagram = 0,
1497         .request = 1,
1498         .type = 0,
1499         .header_ver = 1,
1500         .command = 0x01,
1501     };
1502     static const struct pldm_msg_hdr resp = {
1503         .instance_id = 0,
1504         .reserved = 0,
1505         .datagram = 0,
1506         .request = 0,
1507         .type = 0,
1508         .header_ver = 1,
1509         .command = 0x02,
1510     };
1511 
1512     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
1513 }
1514 #endif
1515 
1516 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailRequestIsResponse)1517 TEST(PldmMsgHdr, correlateFailRequestIsResponse)
1518 {
1519     static const struct pldm_msg_hdr req = {
1520         .instance_id = 0,
1521         .reserved = 0,
1522         .datagram = 0,
1523         .request = 0,
1524         .type = 0,
1525         .header_ver = 1,
1526         .command = 0x01,
1527     };
1528     static const struct pldm_msg_hdr resp = {
1529         .instance_id = 0,
1530         .reserved = 0,
1531         .datagram = 0,
1532         .request = 0,
1533         .type = 0,
1534         .header_ver = 1,
1535         .command = 0x02,
1536     };
1537 
1538     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
1539 }
1540 #endif
1541 
1542 #ifdef LIBPLDM_API_TESTING
TEST(EncodeNegotiateTransferParamsRequest,GoodTest)1543 TEST(EncodeNegotiateTransferParamsRequest, GoodTest)
1544 {
1545     uint8_t instance_id = 0;
1546 
1547     const struct pldm_base_negotiate_transfer_params_req req_data = {
1548         0x0001, // BE 256
1549         {{0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x81}}};
1550 
1551     static constexpr const size_t requestMsgLength =
1552         PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES;
1553 
1554     std::array<uint8_t, requestMsgLength> requestMsg = {
1555         0x01, 0x00, // requester_part_size = 256
1556         0x00, 0x00, 0x00, 0x00,
1557         0x00, 0x00, 0x00, 0x81}; // requester_protocol_support =
1558                                  // PLDM_BASE & PLDM_FILE
1559 
1560     PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength);
1561     size_t payload_length = requestMsgLength;
1562     auto rc = encode_pldm_base_negotiate_transfer_params_req(
1563         instance_id, &req_data, requestPtr, &payload_length);
1564 
1565     ASSERT_EQ(rc, 0);
1566     EXPECT_EQ(
1567         0, memcmp(requestPtr->payload, requestMsg.data(), sizeof(requestMsg)));
1568     EXPECT_EQ(payload_length, requestMsgLength);
1569 }
1570 #endif
1571 
1572 #ifdef LIBPLDM_API_TESTING
TEST(EncodeNegotiateTransferParamsRequest,BadTestUnAllocatedPtrParams)1573 TEST(EncodeNegotiateTransferParamsRequest, BadTestUnAllocatedPtrParams)
1574 {
1575     int rc;
1576     uint8_t instance_id = 0;
1577     const struct pldm_base_negotiate_transfer_params_req req_data = {
1578         0x0001, // BE 256
1579         {{0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x81}}};
1580 
1581     static constexpr const size_t requestMsgLength =
1582         PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES;
1583 
1584     PLDM_MSG_DEFINE_P(requestPtr, requestMsgLength);
1585     size_t payload_length = requestMsgLength;
1586     rc = encode_pldm_base_negotiate_transfer_params_req(
1587         instance_id, nullptr, requestPtr, &payload_length);
1588     EXPECT_EQ(rc, -EINVAL);
1589 
1590     rc = encode_pldm_base_negotiate_transfer_params_req(
1591         instance_id, &req_data, nullptr, &payload_length);
1592     EXPECT_EQ(rc, -EINVAL);
1593 }
1594 #endif
1595 
1596 #ifdef LIBPLDM_API_TESTING
TEST(EncodeNegotiateTransferParamsRequest,BadTestInvalidExpectedOutputMsgLength)1597 TEST(EncodeNegotiateTransferParamsRequest,
1598      BadTestInvalidExpectedOutputMsgLength)
1599 {
1600     int rc;
1601     uint8_t instance_id = 0;
1602     const struct pldm_base_negotiate_transfer_params_req req_data = {
1603         0x0001, // BE 256
1604         {{0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, {0x81}}};
1605 
1606     PLDM_MSG_DEFINE_P(requestPtr,
1607                       PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES);
1608 
1609     size_t payload_length = 1;
1610     rc = encode_pldm_base_negotiate_transfer_params_req(
1611         instance_id, &req_data, requestPtr, &payload_length);
1612     EXPECT_EQ(rc, -EOVERFLOW);
1613 }
1614 #endif
1615 
1616 #ifdef LIBPLDM_API_TESTING
TEST(DecodeNegotiateTransferParamsResponse,GoodTest)1617 TEST(DecodeNegotiateTransferParamsResponse, GoodTest)
1618 {
1619     uint8_t completionCode = PLDM_SUCCESS;
1620     uint16_t responderPartSize = 128;
1621     std::array<uint8_t, 8> responderProtocolSupport = {0x00, 0x00, 0x00, 0x00,
1622                                                        0x00, 0x00, 0x00, 0x81};
1623 
1624     struct pldm_base_negotiate_transfer_params_resp resp_data = {};
1625 
1626     PLDM_MSGBUF_RW_DEFINE_P(buf);
1627     int rc;
1628 
1629     static constexpr const size_t payload_length =
1630         PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES;
1631     PLDM_MSG_DEFINE_P(responseMsg, payload_length);
1632 
1633     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length);
1634     ASSERT_EQ(rc, 0);
1635 
1636     pldm_msgbuf_insert_uint8(buf, completionCode);
1637     pldm_msgbuf_insert_uint16(buf, responderPartSize);
1638     rc = pldm_msgbuf_insert_array_uint8(
1639         buf, sizeof(resp_data.responder_protocol_support),
1640         responderProtocolSupport.data(),
1641         sizeof(resp_data.responder_protocol_support));
1642     EXPECT_EQ(rc, 0);
1643 
1644     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1645 
1646     rc = decode_pldm_base_negotiate_transfer_params_resp(
1647         responseMsg, payload_length, &resp_data);
1648 
1649     ASSERT_EQ(rc, 0);
1650     EXPECT_EQ(resp_data.completion_code, completionCode);
1651     EXPECT_EQ(resp_data.responder_part_size, responderPartSize);
1652     EXPECT_EQ(0, memcmp(responderProtocolSupport.data(),
1653                         resp_data.responder_protocol_support,
1654                         sizeof(resp_data.responder_protocol_support)));
1655 }
1656 #endif
1657 
1658 #ifdef LIBPLDM_API_TESTING
TEST(DecodeNegotiateTransferParamsResponse,BadTestUnAllocatedPtrParams)1659 TEST(DecodeNegotiateTransferParamsResponse, BadTestUnAllocatedPtrParams)
1660 {
1661     uint8_t completionCode = PLDM_SUCCESS;
1662     uint16_t responderPartSize = 128;
1663     std::array<uint8_t, 8> responderProtocolSupport = {0x00, 0x00, 0x00, 0x00,
1664                                                        0x00, 0x00, 0x00, 0x81};
1665 
1666     struct pldm_base_negotiate_transfer_params_resp resp_data = {};
1667 
1668     PLDM_MSGBUF_RW_DEFINE_P(buf);
1669     int rc;
1670 
1671     static constexpr const size_t payload_length =
1672         PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES;
1673     PLDM_MSG_DEFINE_P(responseMsg, payload_length);
1674 
1675     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length);
1676     ASSERT_EQ(rc, 0);
1677 
1678     pldm_msgbuf_insert_uint8(buf, completionCode);
1679     pldm_msgbuf_insert_uint16(buf, responderPartSize);
1680     rc = pldm_msgbuf_insert_array_uint8(
1681         buf, sizeof(resp_data.responder_protocol_support),
1682         responderProtocolSupport.data(),
1683         sizeof(resp_data.responder_protocol_support));
1684     EXPECT_EQ(rc, 0);
1685 
1686     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1687 
1688     rc = decode_pldm_base_negotiate_transfer_params_resp(
1689         nullptr, payload_length, &resp_data);
1690 
1691     EXPECT_EQ(rc, -EINVAL);
1692 
1693     rc = decode_pldm_base_negotiate_transfer_params_resp(
1694         responseMsg, payload_length, nullptr);
1695 
1696     EXPECT_EQ(rc, -EINVAL);
1697 }
1698 #endif
1699 
1700 #ifdef LIBPLDM_API_TESTING
TEST(DecodeNegotiateTransferParamsResponse,BadTestInvalidExpectedInputMsgLength)1701 TEST(DecodeNegotiateTransferParamsResponse,
1702      BadTestInvalidExpectedInputMsgLength)
1703 {
1704     uint8_t completionCode = PLDM_SUCCESS;
1705     uint16_t responderPartSize = 128;
1706     std::array<uint8_t, 8> responderProtocolSupport = {0x00, 0x00, 0x00, 0x00,
1707                                                        0x00, 0x00, 0x00, 0x81};
1708 
1709     struct pldm_base_negotiate_transfer_params_resp resp_data = {};
1710 
1711     PLDM_MSGBUF_RW_DEFINE_P(buf);
1712     int rc;
1713 
1714     static constexpr const size_t payload_length =
1715         PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES;
1716     PLDM_MSG_DEFINE_P(responseMsg, payload_length);
1717 
1718     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg->payload, payload_length);
1719     ASSERT_EQ(rc, 0);
1720 
1721     pldm_msgbuf_insert_uint8(buf, completionCode);
1722     pldm_msgbuf_insert_uint16(buf, responderPartSize);
1723     rc = pldm_msgbuf_insert_array_uint8(
1724         buf, sizeof(resp_data.responder_protocol_support),
1725         responderProtocolSupport.data(),
1726         sizeof(resp_data.responder_protocol_support));
1727     EXPECT_EQ(rc, 0);
1728 
1729     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1730 
1731     rc = decode_pldm_base_negotiate_transfer_params_resp(responseMsg, 0,
1732                                                          &resp_data);
1733 
1734     EXPECT_EQ(rc, -EOVERFLOW);
1735 }
1736 #endif
1737 
1738 #ifdef LIBPLDM_API_TESTING
TEST(NegotiateTransferParams,TestDecodeNegotiateTransferParamsReqPass)1739 TEST(NegotiateTransferParams, TestDecodeNegotiateTransferParamsReqPass)
1740 {
1741     // Prepare a sample request message
1742     uint8_t instance_id = 0x0A;
1743     uint16_t requester_part_size = 1024; // 0x0400
1744     bitfield8_t requester_protocol_support[8];
1745     for (int i = 0; i < 8; ++i)
1746     {
1747         requester_protocol_support[i].byte = static_cast<uint8_t>(i + 1);
1748     }
1749 
1750     PLDM_MSG_DEFINE_P(request,
1751                       PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES);
1752 
1753     // Build the request using the an appropriate API
1754     struct pldm_base_negotiate_transfer_params_req req;
1755     req.requester_part_size = requester_part_size;
1756     memcpy(req.requester_protocol_support, requester_protocol_support,
1757            sizeof(requester_protocol_support));
1758 
1759     size_t req_payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES;
1760     ASSERT_EQ(encode_pldm_base_negotiate_transfer_params_req(
1761                   instance_id, &req, request, &req_payload_len),
1762               0);
1763 
1764     struct pldm_base_negotiate_transfer_params_req decoded_req;
1765     size_t payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES;
1766 
1767     // Successful decode
1768     int rc = decode_pldm_base_negotiate_transfer_params_req(
1769         request, payload_len, &decoded_req);
1770     ASSERT_EQ(rc, 0);
1771     EXPECT_EQ(decoded_req.requester_part_size, requester_part_size);
1772     for (int i = 0; i < 8; ++i)
1773     {
1774         EXPECT_EQ(decoded_req.requester_protocol_support[i].byte,
1775                   requester_protocol_support[i].byte);
1776     }
1777 }
1778 #endif
1779 
1780 #ifdef LIBPLDM_API_TESTING
TEST(NegotiateTransferParams,TestDecodeNegotiateTransferParamsReqFail)1781 TEST(NegotiateTransferParams, TestDecodeNegotiateTransferParamsReqFail)
1782 {
1783     // Prepare a sample request message
1784     uint8_t instance_id = 0x0A;
1785     uint16_t requester_part_size = 1024; // 0x0400
1786     bitfield8_t requester_protocol_support[8];
1787     for (int i = 0; i < 8; ++i)
1788     {
1789         requester_protocol_support[i].byte = static_cast<uint8_t>(i + 1);
1790     }
1791 
1792     PLDM_MSG_DEFINE_P(request,
1793                       PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES);
1794 
1795     // Build the request using the an appropriate API
1796     struct pldm_base_negotiate_transfer_params_req req;
1797     req.requester_part_size = requester_part_size;
1798     memcpy(req.requester_protocol_support, requester_protocol_support,
1799            sizeof(requester_protocol_support));
1800 
1801     size_t req_payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES;
1802     ASSERT_EQ(encode_pldm_base_negotiate_transfer_params_req(
1803                   instance_id, &req, request, &req_payload_len),
1804               0);
1805 
1806     struct pldm_base_negotiate_transfer_params_req decoded_req;
1807     size_t payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_REQ_BYTES;
1808     int rc = 0;
1809 
1810     // Null arguments
1811     rc = decode_pldm_base_negotiate_transfer_params_req(nullptr, payload_len,
1812                                                         &decoded_req);
1813     EXPECT_EQ(rc, -EINVAL);
1814     rc = decode_pldm_base_negotiate_transfer_params_req(request, payload_len,
1815                                                         nullptr);
1816     EXPECT_EQ(rc, -EINVAL);
1817 
1818     // Incorrect payload length - too short
1819     rc = decode_pldm_base_negotiate_transfer_params_req(
1820         request, payload_len - 1, &decoded_req);
1821     EXPECT_EQ(rc, -EOVERFLOW);
1822 
1823     // Incorrect payload length - too long
1824     rc = decode_pldm_base_negotiate_transfer_params_req(
1825         request, payload_len + 1, &decoded_req);
1826     EXPECT_EQ(rc, -EBADMSG);
1827 }
1828 #endif
1829 
1830 #ifdef LIBPLDM_API_TESTING
TEST(NegotiateTransferParams,TestEncodeNegotiateTransferParamsRespPass)1831 TEST(NegotiateTransferParams, TestEncodeNegotiateTransferParamsRespPass)
1832 {
1833     // Prepare encode parameters for a successful response
1834     uint8_t instance_id = 0x0B;
1835     uint8_t completion_code_success = PLDM_SUCCESS;
1836     uint16_t responder_part_size = 2048; // 0x0800
1837     bitfield8_t responder_protocol_support[8];
1838     for (int i = 0; i < 8; ++i)
1839     {
1840         responder_protocol_support[i].byte = static_cast<uint8_t>(0xA0 + i);
1841     }
1842 
1843     struct pldm_base_negotiate_transfer_params_resp resp_params_success;
1844     resp_params_success.completion_code = completion_code_success;
1845     resp_params_success.responder_part_size = responder_part_size;
1846     memcpy(resp_params_success.responder_protocol_support,
1847            responder_protocol_support, sizeof(responder_protocol_support));
1848 
1849     PLDM_MSG_DEFINE_P(response,
1850                       PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES);
1851     size_t payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES;
1852 
1853     // Encode success case
1854     int rc = encode_pldm_base_negotiate_transfer_params_resp(
1855         instance_id, &resp_params_success, response, &payload_len);
1856     ASSERT_EQ(rc, 0);
1857     EXPECT_EQ(response->hdr.request, PLDM_RESPONSE);
1858     EXPECT_EQ(response->hdr.instance_id, instance_id);
1859     EXPECT_EQ(response->hdr.type, PLDM_BASE);
1860     EXPECT_EQ(response->hdr.command, PLDM_NEGOTIATE_TRANSFER_PARAMETERS);
1861 
1862     // Verify the encoded response using the decode function
1863     struct pldm_base_negotiate_transfer_params_resp decoded_resp;
1864     payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES;
1865     rc = decode_pldm_base_negotiate_transfer_params_resp(response, payload_len,
1866                                                          &decoded_resp);
1867     ASSERT_EQ(rc, 0);
1868     EXPECT_EQ(decoded_resp.completion_code, completion_code_success);
1869     EXPECT_EQ(decoded_resp.responder_part_size, responder_part_size);
1870     for (int i = 0; i < 8; ++i)
1871     {
1872         EXPECT_EQ(decoded_resp.responder_protocol_support[i].byte,
1873                   responder_protocol_support[i].byte);
1874     }
1875 }
1876 
TEST(NegotiateTransferParams,TestEncodeNegotiateTransferParamsRespFail)1877 TEST(NegotiateTransferParams, TestEncodeNegotiateTransferParamsRespFail)
1878 {
1879     // Prepare encode parameters
1880     uint8_t instance_id = 0x0B;
1881     uint8_t completion_code_success = PLDM_SUCCESS;
1882     uint16_t responder_part_size = 2048; // 0x0800
1883     bitfield8_t responder_protocol_support[8];
1884     for (int i = 0; i < 8; ++i)
1885     {
1886         responder_protocol_support[i].byte = static_cast<uint8_t>(0xA0 + i);
1887     }
1888 
1889     struct pldm_base_negotiate_transfer_params_resp resp_params_success;
1890     resp_params_success.completion_code = completion_code_success;
1891     resp_params_success.responder_part_size = responder_part_size;
1892     memcpy(resp_params_success.responder_protocol_support,
1893            responder_protocol_support, sizeof(responder_protocol_support));
1894 
1895     PLDM_MSG_DEFINE_P(response,
1896                       PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES);
1897     size_t payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES;
1898     int rc = 0;
1899 
1900     // Null arguments
1901     rc = encode_pldm_base_negotiate_transfer_params_resp(
1902         instance_id, nullptr, response, &payload_len);
1903     EXPECT_EQ(rc, -EINVAL);
1904 
1905     payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES;
1906     rc = encode_pldm_base_negotiate_transfer_params_resp(
1907         instance_id, &resp_params_success, nullptr, &payload_len);
1908     EXPECT_EQ(rc, -EINVAL);
1909 
1910     // Incorrect payload length
1911     payload_len = PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES - 1;
1912     rc = encode_pldm_base_negotiate_transfer_params_resp(
1913         instance_id, &resp_params_success, response, &payload_len);
1914     EXPECT_EQ(rc, -EOVERFLOW);
1915 }
1916 #endif
1917