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