xref: /openbmc/libpldm/tests/dsp/base.cpp (revision 615344fc)
1 #include <libpldm/base.h>
2 #include <libpldm/pldm_types.h>
3 
4 #include <array>
5 #include <cstdint>
6 #include <cstring>
7 #include <vector>
8 
9 #include <gmock/gmock.h>
10 #include <gtest/gtest.h>
11 
12 using testing::ElementsAreArray;
13 
14 constexpr auto hdrSize = sizeof(pldm_msg_hdr);
15 
16 TEST(PackPLDMMessage, BadPathTest)
17 {
18     struct pldm_header_info hdr;
19     struct pldm_header_info* hdr_ptr = NULL;
20     pldm_msg_hdr msg{};
21 
22     // PLDM header information pointer is NULL
23     auto rc = pack_pldm_header(hdr_ptr, &msg);
24     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
25 
26     // PLDM message pointer is NULL
27     rc = pack_pldm_header(&hdr, nullptr);
28     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
29 
30     // PLDM header information pointer and PLDM message pointer is NULL
31     rc = pack_pldm_header(hdr_ptr, nullptr);
32     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
33 
34     // RESERVED message type
35     hdr.msg_type = PLDM_RESERVED;
36     rc = pack_pldm_header(&hdr, &msg);
37     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
38 
39     // Instance ID out of range
40     hdr.msg_type = PLDM_REQUEST;
41     hdr.instance = 32;
42     rc = pack_pldm_header(&hdr, &msg);
43     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
44 
45     // PLDM type out of range
46     hdr.msg_type = PLDM_REQUEST;
47     hdr.instance = 31;
48     hdr.pldm_type = 64;
49     rc = pack_pldm_header(&hdr, &msg);
50     EXPECT_EQ(rc, PLDM_ERROR_INVALID_PLDM_TYPE);
51 }
52 
53 TEST(PackPLDMMessage, RequestMessageGoodPath)
54 {
55     struct pldm_header_info hdr;
56     pldm_msg_hdr msg{};
57 
58     // Message type is REQUEST and lower range of the field values
59     hdr.msg_type = PLDM_REQUEST;
60     hdr.instance = 0;
61     hdr.pldm_type = 0;
62     hdr.command = 0;
63 
64     auto rc = pack_pldm_header(&hdr, &msg);
65     EXPECT_EQ(rc, PLDM_SUCCESS);
66     EXPECT_EQ(msg.request, 1);
67     EXPECT_EQ(msg.datagram, 0);
68     EXPECT_EQ(msg.instance_id, 0);
69     EXPECT_EQ(msg.type, 0);
70     EXPECT_EQ(msg.command, 0);
71 
72     // Message type is REQUEST and upper range of the field values
73     hdr.instance = 31;
74     hdr.pldm_type = 63;
75     hdr.command = 255;
76 
77     rc = pack_pldm_header(&hdr, &msg);
78     EXPECT_EQ(rc, PLDM_SUCCESS);
79     EXPECT_EQ(msg.request, 1);
80     EXPECT_EQ(msg.datagram, 0);
81     EXPECT_EQ(msg.instance_id, 31);
82     EXPECT_EQ(msg.type, 63);
83     EXPECT_EQ(msg.command, 255);
84 
85     // Message type is PLDM_ASYNC_REQUEST_NOTIFY
86     hdr.msg_type = PLDM_ASYNC_REQUEST_NOTIFY;
87 
88     rc = pack_pldm_header(&hdr, &msg);
89     EXPECT_EQ(rc, PLDM_SUCCESS);
90     EXPECT_EQ(msg.request, 1);
91     EXPECT_EQ(msg.datagram, 1);
92     EXPECT_EQ(msg.instance_id, 31);
93     EXPECT_EQ(msg.type, 63);
94     EXPECT_EQ(msg.command, 255);
95 }
96 
97 TEST(PackPLDMMessage, ResponseMessageGoodPath)
98 {
99     struct pldm_header_info hdr;
100     pldm_msg_hdr msg{};
101 
102     // Message type is PLDM_RESPONSE and lower range of the field values
103     hdr.msg_type = PLDM_RESPONSE;
104     hdr.instance = 0;
105     hdr.pldm_type = 0;
106     hdr.command = 0;
107 
108     auto rc = pack_pldm_header(&hdr, &msg);
109     EXPECT_EQ(rc, PLDM_SUCCESS);
110     EXPECT_EQ(msg.request, 0);
111     EXPECT_EQ(msg.datagram, 0);
112     EXPECT_EQ(msg.instance_id, 0);
113     EXPECT_EQ(msg.type, 0);
114     EXPECT_EQ(msg.command, 0);
115 
116     // Message type is PLDM_RESPONSE and upper range of the field values
117     hdr.instance = 31;
118     hdr.pldm_type = 63;
119     hdr.command = 255;
120 
121     rc = pack_pldm_header(&hdr, &msg);
122     EXPECT_EQ(rc, PLDM_SUCCESS);
123     EXPECT_EQ(msg.request, 0);
124     EXPECT_EQ(msg.datagram, 0);
125     EXPECT_EQ(msg.instance_id, 31);
126     EXPECT_EQ(msg.type, 63);
127     EXPECT_EQ(msg.command, 255);
128 }
129 
130 TEST(UnpackPLDMMessage, BadPathTest)
131 {
132     struct pldm_header_info hdr;
133 
134     // PLDM message pointer is NULL
135     auto rc = unpack_pldm_header(nullptr, &hdr);
136     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
137 }
138 
139 TEST(UnpackPLDMMessage, RequestMessageGoodPath)
140 {
141     struct pldm_header_info hdr;
142     pldm_msg_hdr msg{};
143 
144     // Unpack PLDM request message and lower range of field values
145     msg.request = 1;
146     auto rc = unpack_pldm_header(&msg, &hdr);
147     EXPECT_EQ(rc, PLDM_SUCCESS);
148     EXPECT_EQ(hdr.msg_type, PLDM_REQUEST);
149     EXPECT_EQ(hdr.instance, 0);
150     EXPECT_EQ(hdr.pldm_type, 0);
151     EXPECT_EQ(hdr.command, 0);
152 
153     // Unpack PLDM async request message and lower range of field values
154     msg.datagram = 1;
155     rc = unpack_pldm_header(&msg, &hdr);
156     EXPECT_EQ(rc, PLDM_SUCCESS);
157     EXPECT_EQ(hdr.msg_type, PLDM_ASYNC_REQUEST_NOTIFY);
158 
159     // Unpack PLDM request message and upper range of field values
160     msg.datagram = 0;
161     msg.instance_id = 31;
162     msg.type = 63;
163     msg.command = 255;
164     rc = unpack_pldm_header(&msg, &hdr);
165     EXPECT_EQ(rc, PLDM_SUCCESS);
166     EXPECT_EQ(hdr.msg_type, PLDM_REQUEST);
167     EXPECT_EQ(hdr.instance, 31);
168     EXPECT_EQ(hdr.pldm_type, 63);
169     EXPECT_EQ(hdr.command, 255);
170 }
171 
172 TEST(UnpackPLDMMessage, ResponseMessageGoodPath)
173 {
174     struct pldm_header_info hdr;
175     pldm_msg_hdr msg{};
176 
177     // Unpack PLDM response message and lower range of field values
178     auto rc = unpack_pldm_header(&msg, &hdr);
179     EXPECT_EQ(rc, PLDM_SUCCESS);
180     EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE);
181     EXPECT_EQ(hdr.instance, 0);
182     EXPECT_EQ(hdr.pldm_type, 0);
183     EXPECT_EQ(hdr.command, 0);
184 
185     // Unpack PLDM response message and upper range of field values
186     msg.instance_id = 31;
187     msg.type = 63;
188     msg.command = 255;
189     rc = unpack_pldm_header(&msg, &hdr);
190     EXPECT_EQ(rc, PLDM_SUCCESS);
191     EXPECT_EQ(hdr.msg_type, PLDM_RESPONSE);
192     EXPECT_EQ(hdr.instance, 31);
193     EXPECT_EQ(hdr.pldm_type, 63);
194     EXPECT_EQ(hdr.command, 255);
195 }
196 
197 TEST(GetPLDMCommands, testEncodeRequest)
198 {
199     uint8_t pldmType = 0x05;
200     ver32_t version{0xff, 0xff, 0xff, 0xff};
201     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
202         requestMsg{};
203     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
204 
205     auto rc = encode_get_commands_req(0, pldmType, version, request);
206     EXPECT_EQ(rc, PLDM_SUCCESS);
207     EXPECT_EQ(0, memcmp(request->payload, &pldmType, sizeof(pldmType)));
208     EXPECT_EQ(0, memcmp(request->payload + sizeof(pldmType), &version,
209                         sizeof(version)));
210 }
211 
212 TEST(GetPLDMCommands, testDecodeRequest)
213 {
214     uint8_t pldmType = 0x05;
215     ver32_t version{0xff, 0xff, 0xff, 0xff};
216     uint8_t pldmTypeOut{};
217     ver32_t versionOut{0xff, 0xff, 0xff, 0xff};
218     std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_REQ_BYTES> requestMsg{};
219 
220     memcpy(requestMsg.data() + hdrSize, &pldmType, sizeof(pldmType));
221     memcpy(requestMsg.data() + sizeof(pldmType) + hdrSize, &version,
222            sizeof(version));
223 
224     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
225     auto rc = decode_get_commands_req(request, requestMsg.size() - hdrSize,
226                                       &pldmTypeOut, &versionOut);
227 
228     EXPECT_EQ(rc, PLDM_SUCCESS);
229     EXPECT_EQ(pldmTypeOut, pldmType);
230     EXPECT_EQ(0, memcmp(&versionOut, &version, sizeof(version)));
231 }
232 
233 TEST(GetPLDMCommands, testEncodeResponse)
234 {
235     uint8_t completionCode = 0;
236     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES>
237         responseMsg{};
238     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
239     std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> commands{};
240     commands[0].byte = 1;
241     commands[1].byte = 2;
242     commands[2].byte = 3;
243 
244     auto rc =
245         encode_get_commands_resp(0, PLDM_SUCCESS, commands.data(), response);
246     EXPECT_EQ(rc, PLDM_SUCCESS);
247     uint8_t* payload_ptr = response->payload;
248     EXPECT_EQ(completionCode, payload_ptr[0]);
249     EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]);
250     EXPECT_EQ(2,
251               payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte)]);
252     EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte) +
253                              sizeof(commands[1].byte)]);
254 }
255 
256 TEST(GetPLDMTypes, testEncodeResponse)
257 {
258     uint8_t completionCode = 0;
259     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES>
260         responseMsg{};
261     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
262     std::array<bitfield8_t, PLDM_MAX_TYPES / 8> types{};
263     types[0].byte = 1;
264     types[1].byte = 2;
265     types[2].byte = 3;
266 
267     auto rc = encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response);
268     EXPECT_EQ(rc, PLDM_SUCCESS);
269     uint8_t* payload_ptr = response->payload;
270     EXPECT_EQ(completionCode, payload_ptr[0]);
271     EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]);
272     EXPECT_EQ(2, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte)]);
273     EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte) +
274                              sizeof(types[1].byte)]);
275 }
276 
277 TEST(GetPLDMTypes, testGoodDecodeResponse)
278 {
279     std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
280     responseMsg[1 + hdrSize] = 1;
281     responseMsg[2 + hdrSize] = 2;
282     responseMsg[3 + hdrSize] = 3;
283     std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
284 
285     uint8_t completion_code;
286     responseMsg[hdrSize] = PLDM_SUCCESS;
287 
288     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
289 
290     auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize,
291                                     &completion_code, outTypes.data());
292 
293     EXPECT_EQ(rc, PLDM_SUCCESS);
294     EXPECT_EQ(completion_code, PLDM_SUCCESS);
295     EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte);
296     EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte);
297     EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte);
298 }
299 
300 TEST(GetPLDMTypes, testBadDecodeResponse)
301 {
302     std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
303     responseMsg[1 + hdrSize] = 1;
304     responseMsg[2 + hdrSize] = 2;
305     responseMsg[3 + hdrSize] = 3;
306     std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
307 
308     uint8_t retcompletion_code = 0;
309     responseMsg[hdrSize] = PLDM_SUCCESS;
310 
311     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
312 
313     auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize - 1,
314                                     &retcompletion_code, outTypes.data());
315 
316     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
317 }
318 
319 TEST(GetPLDMCommands, testGoodDecodeResponse)
320 {
321     std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
322     responseMsg[1 + hdrSize] = 1;
323     responseMsg[2 + hdrSize] = 2;
324     responseMsg[3 + hdrSize] = 3;
325     std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
326 
327     uint8_t completion_code;
328     responseMsg[hdrSize] = PLDM_SUCCESS;
329 
330     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
331 
332     auto rc = decode_get_commands_resp(response, responseMsg.size() - hdrSize,
333                                        &completion_code, outTypes.data());
334 
335     EXPECT_EQ(rc, PLDM_SUCCESS);
336     EXPECT_EQ(completion_code, PLDM_SUCCESS);
337     EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte);
338     EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte);
339     EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte);
340 }
341 
342 TEST(GetPLDMCommands, testBadDecodeResponse)
343 {
344     std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
345     responseMsg[1 + hdrSize] = 1;
346     responseMsg[2 + hdrSize] = 2;
347     responseMsg[3 + hdrSize] = 3;
348     std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
349 
350     uint8_t retcompletion_code = 0;
351     responseMsg[hdrSize] = PLDM_SUCCESS;
352 
353     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
354 
355     auto rc =
356         decode_get_commands_resp(response, responseMsg.size() - hdrSize - 1,
357                                  &retcompletion_code, outTypes.data());
358 
359     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
360 }
361 
362 TEST(GetPLDMVersion, testGoodEncodeRequest)
363 {
364     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
365         requestMsg{};
366     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
367     uint8_t pldmType = 0x03;
368     uint32_t transferHandle = 0x0;
369     uint8_t opFlag = 0x01;
370 
371     auto rc =
372         encode_get_version_req(0, transferHandle, opFlag, pldmType, request);
373     EXPECT_EQ(rc, PLDM_SUCCESS);
374     EXPECT_EQ(
375         0, memcmp(request->payload, &transferHandle, sizeof(transferHandle)));
376     EXPECT_EQ(0, memcmp(request->payload + sizeof(transferHandle), &opFlag,
377                         sizeof(opFlag)));
378     EXPECT_EQ(0,
379               memcmp(request->payload + sizeof(transferHandle) + sizeof(opFlag),
380                      &pldmType, sizeof(pldmType)));
381 }
382 
383 TEST(GetPLDMVersion, testBadEncodeRequest)
384 {
385     uint8_t pldmType = 0x03;
386     uint32_t transferHandle = 0x0;
387     uint8_t opFlag = 0x01;
388 
389     auto rc =
390         encode_get_version_req(0, transferHandle, opFlag, pldmType, nullptr);
391 
392     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
393 }
394 
395 TEST(GetPLDMVersion, testEncodeResponse)
396 {
397     uint8_t completionCode = 0;
398     uint32_t transferHandle = 0;
399     uint8_t flag = PLDM_START_AND_END;
400     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES>
401         responseMsg{};
402     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
403     ver32_t version = {0xff, 0xff, 0xff, 0xff};
404 
405     auto rc = encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END,
406                                       &version, sizeof(ver32_t), response);
407 
408     EXPECT_EQ(rc, PLDM_SUCCESS);
409     EXPECT_EQ(completionCode, response->payload[0]);
410     EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]),
411                         &transferHandle, sizeof(transferHandle)));
412     EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
413                             sizeof(transferHandle),
414                         &flag, sizeof(flag)));
415     EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
416                             sizeof(transferHandle) + sizeof(flag),
417                         &version, sizeof(version)));
418 }
419 
420 TEST(GetPLDMVersion, testDecodeRequest)
421 {
422     std::array<uint8_t, hdrSize + PLDM_GET_VERSION_REQ_BYTES> requestMsg{};
423     uint32_t transferHandle = 0x0;
424     uint32_t retTransferHandle = 0x0;
425     uint8_t flag = PLDM_GET_FIRSTPART;
426     uint8_t retFlag = PLDM_GET_FIRSTPART;
427     uint8_t pldmType = PLDM_BASE;
428     uint8_t retType = PLDM_BASE;
429 
430     memcpy(requestMsg.data() + hdrSize, &transferHandle,
431            sizeof(transferHandle));
432     memcpy(requestMsg.data() + sizeof(transferHandle) + hdrSize, &flag,
433            sizeof(flag));
434     memcpy(requestMsg.data() + sizeof(transferHandle) + sizeof(flag) + hdrSize,
435            &pldmType, sizeof(pldmType));
436 
437     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
438 
439     auto rc = decode_get_version_req(request, requestMsg.size() - hdrSize,
440                                      &retTransferHandle, &retFlag, &retType);
441 
442     EXPECT_EQ(rc, PLDM_SUCCESS);
443     EXPECT_EQ(transferHandle, retTransferHandle);
444     EXPECT_EQ(flag, retFlag);
445     EXPECT_EQ(pldmType, retType);
446 }
447 
448 TEST(GetPLDMVersion, testDecodeResponse)
449 {
450     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES>
451         responseMsg{};
452     uint32_t transferHandle = 0x0;
453     uint32_t retTransferHandle = 0x0;
454     uint8_t flag = PLDM_START_AND_END;
455     uint8_t retFlag = PLDM_START_AND_END;
456     uint8_t completionCode = 0;
457     ver32_t version = {0xff, 0xff, 0xff, 0xff};
458     ver32_t versionOut;
459     uint8_t completion_code;
460 
461     memcpy(responseMsg.data() + sizeof(completionCode) + hdrSize,
462            &transferHandle, sizeof(transferHandle));
463     memcpy(responseMsg.data() + sizeof(completionCode) +
464                sizeof(transferHandle) + hdrSize,
465            &flag, sizeof(flag));
466     memcpy(responseMsg.data() + sizeof(completionCode) +
467                sizeof(transferHandle) + sizeof(flag) + hdrSize,
468            &version, sizeof(version));
469 
470     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
471 
472     auto rc = decode_get_version_resp(response, responseMsg.size() - hdrSize,
473                                       &completion_code, &retTransferHandle,
474                                       &retFlag, &versionOut);
475     EXPECT_EQ(rc, PLDM_SUCCESS);
476     EXPECT_EQ(transferHandle, retTransferHandle);
477     EXPECT_EQ(flag, retFlag);
478 
479     EXPECT_EQ(versionOut.major, version.major);
480     EXPECT_EQ(versionOut.minor, version.minor);
481     EXPECT_EQ(versionOut.update, version.update);
482     EXPECT_EQ(versionOut.alpha, version.alpha);
483 }
484 
485 TEST(GetTID, testEncodeRequest)
486 {
487     pldm_msg request{};
488 
489     auto rc = encode_get_tid_req(0, &request);
490     ASSERT_EQ(rc, PLDM_SUCCESS);
491 }
492 
493 TEST(GetTID, testEncodeResponse)
494 {
495     uint8_t completionCode = 0;
496     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES>
497         responseMsg{};
498     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
499     uint8_t tid = 1;
500 
501     auto rc = encode_get_tid_resp(0, PLDM_SUCCESS, tid, response);
502     EXPECT_EQ(rc, PLDM_SUCCESS);
503     uint8_t* payload = response->payload;
504     EXPECT_EQ(completionCode, payload[0]);
505     EXPECT_EQ(1, payload[sizeof(completionCode)]);
506 }
507 
508 TEST(GetTID, testDecodeResponse)
509 {
510     std::array<uint8_t, hdrSize + PLDM_GET_TID_RESP_BYTES> responseMsg{};
511     responseMsg[1 + hdrSize] = 1;
512 
513     uint8_t tid;
514     uint8_t completion_code;
515     responseMsg[hdrSize] = PLDM_SUCCESS;
516 
517     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
518 
519     auto rc = decode_get_tid_resp(response, responseMsg.size() - hdrSize,
520                                   &completion_code, &tid);
521 
522     EXPECT_EQ(rc, PLDM_SUCCESS);
523     EXPECT_EQ(completion_code, PLDM_SUCCESS);
524     EXPECT_EQ(tid, 1);
525 }
526 
527 TEST(MultipartReceive, testDecodeRequestPass)
528 {
529     constexpr uint8_t kPldmType = PLDM_BASE;
530     constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
531     constexpr uint32_t kTransferCtx = 0x01;
532     constexpr uint32_t kTransferHandle = 0x10;
533     constexpr uint32_t kSectionOffset = 0x0;
534     constexpr uint32_t kSectionLength = 0x10;
535     uint8_t pldm_type = 0x0;
536     uint8_t flag = PLDM_GET_FIRSTPART;
537     uint32_t transfer_ctx;
538     uint32_t transfer_handle;
539     uint32_t section_offset;
540     uint32_t section_length;
541 
542     // Header values don't matter for this test.
543     pldm_msg_hdr hdr{};
544     // Assign values to the packet struct and memcpy to ensure correct byte
545     // ordering.
546     pldm_multipart_receive_req req_pkt = {
547         .pldm_type = kPldmType,
548         .transfer_opflag = kFlag,
549         .transfer_ctx = kTransferCtx,
550         .transfer_handle = kTransferHandle,
551         .section_offset = kSectionOffset,
552         .section_length = kSectionLength,
553     };
554     std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
555     std::memcpy(req.data(), &hdr, sizeof(hdr));
556     std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
557 
558     pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
559     int rc = decode_multipart_receive_req(
560         pldm_request, req.size() - hdrSize, &pldm_type, &flag, &transfer_ctx,
561         &transfer_handle, &section_offset, &section_length);
562 
563     EXPECT_EQ(rc, PLDM_SUCCESS);
564     EXPECT_EQ(pldm_type, kPldmType);
565     EXPECT_EQ(flag, kFlag);
566     EXPECT_EQ(transfer_ctx, kTransferCtx);
567     EXPECT_EQ(transfer_handle, kTransferHandle);
568     EXPECT_EQ(section_offset, kSectionOffset);
569     EXPECT_EQ(section_length, kSectionLength);
570 }
571 
572 TEST(MultipartReceive, testDecodeRequestFailNullData)
573 {
574     EXPECT_EQ(decode_multipart_receive_req(NULL, 0, NULL, NULL, NULL, NULL,
575                                            NULL, NULL),
576               PLDM_ERROR_INVALID_DATA);
577 }
578 
579 TEST(MultipartReceive, testDecodeRequestFailBadLength)
580 {
581     constexpr uint8_t kPldmType = PLDM_BASE;
582     constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
583     uint8_t pldm_type;
584     uint8_t flag;
585     uint32_t transfer_ctx;
586     uint32_t transfer_handle;
587     uint32_t section_offset;
588     uint32_t section_length;
589 
590     // Header values don't matter for this test.
591     pldm_msg_hdr hdr{};
592     // Assign values to the packet struct and memcpy to ensure correct byte
593     // ordering.
594     pldm_multipart_receive_req req_pkt{};
595     req_pkt.pldm_type = kPldmType;
596     req_pkt.transfer_opflag = kFlag;
597 
598     std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
599     std::memcpy(req.data(), &hdr, sizeof(hdr));
600     std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
601 
602     pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
603     EXPECT_EQ(decode_multipart_receive_req(
604                   pldm_request, (req.size() - hdrSize) + 1, &pldm_type, &flag,
605                   &transfer_ctx, &transfer_handle, &section_offset,
606                   &section_length),
607               PLDM_ERROR_INVALID_LENGTH);
608 }
609 
610 TEST(MultipartReceive, testDecodeRequestFailBadPldmType)
611 {
612     constexpr uint8_t kPldmType = 0xff;
613     constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
614     uint8_t pldm_type;
615     uint8_t flag;
616     uint32_t transfer_ctx;
617     uint32_t transfer_handle;
618     uint32_t section_offset;
619     uint32_t section_length;
620 
621     // Header values don't matter for this test.
622     pldm_msg_hdr hdr{};
623     // Assign values to the packet struct and memcpy to ensure correct byte
624     // ordering.
625     pldm_multipart_receive_req req_pkt{};
626     req_pkt.pldm_type = kPldmType;
627     req_pkt.transfer_opflag = kFlag;
628 
629     std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
630     std::memcpy(req.data(), &hdr, sizeof(hdr));
631     std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
632 
633     pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
634     EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
635                                            &pldm_type, &flag, &transfer_ctx,
636                                            &transfer_handle, &section_offset,
637                                            &section_length),
638               PLDM_ERROR_INVALID_PLDM_TYPE);
639 }
640 
641 TEST(MultipartReceive, testDecodeRequestFailBadTransferFlag)
642 {
643     constexpr uint8_t kPldmType = PLDM_BASE;
644     constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10;
645     uint8_t pldm_type;
646     uint8_t flag;
647     uint32_t transfer_ctx;
648     uint32_t transfer_handle;
649     uint32_t section_offset;
650     uint32_t section_length;
651 
652     // Header values don't matter for this test.
653     pldm_msg_hdr hdr{};
654     // Assign values to the packet struct and memcpy to ensure correct byte
655     // ordering.
656     pldm_multipart_receive_req req_pkt{};
657     req_pkt.pldm_type = kPldmType;
658     req_pkt.transfer_opflag = kFlag;
659 
660     std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
661     std::memcpy(req.data(), &hdr, sizeof(hdr));
662     std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
663 
664     pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
665     EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
666                                            &pldm_type, &flag, &transfer_ctx,
667                                            &transfer_handle, &section_offset,
668                                            &section_length),
669               PLDM_INVALID_TRANSFER_OPERATION_FLAG);
670 }
671 
672 TEST(MultipartReceive, testDecodeRequestFailBadOffset)
673 {
674     constexpr uint8_t kPldmType = PLDM_BASE;
675     constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
676     constexpr uint32_t kTransferHandle = 0x01;
677     constexpr uint32_t kSectionOffset = 0x0;
678     uint8_t pldm_type;
679     uint8_t flag;
680     uint32_t transfer_ctx;
681     uint32_t transfer_handle;
682     uint32_t section_offset;
683     uint32_t section_length;
684 
685     // Header values don't matter for this test.
686     pldm_msg_hdr hdr{};
687     // Assign values to the packet struct and memcpy to ensure correct byte
688     // ordering.
689     pldm_multipart_receive_req req_pkt{};
690     req_pkt.pldm_type = kPldmType;
691     req_pkt.transfer_opflag = kFlag;
692     req_pkt.transfer_handle = kTransferHandle;
693     req_pkt.section_offset = kSectionOffset;
694 
695     std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
696     std::memcpy(req.data(), &hdr, sizeof(hdr));
697     std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
698 
699     pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
700     EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
701                                            &pldm_type, &flag, &transfer_ctx,
702                                            &transfer_handle, &section_offset,
703                                            &section_length),
704               PLDM_ERROR_INVALID_DATA);
705 }
706 
707 TEST(MultipartReceive, testDecodeRequestFailBadHandle)
708 {
709     constexpr uint8_t kPldmType = PLDM_BASE;
710     constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
711     constexpr uint32_t kSectionOffset = 0x100;
712     constexpr uint32_t kTransferHandle = 0x0;
713     uint8_t pldm_type;
714     uint8_t flag;
715     uint32_t transfer_ctx;
716     uint32_t transfer_handle;
717     uint32_t section_offset;
718     uint32_t section_length;
719 
720     // Header values don't matter for this test.
721     pldm_msg_hdr hdr{};
722     // Assign values to the packet struct and memcpy to ensure correct byte
723     // ordering.
724     pldm_multipart_receive_req req_pkt{};
725     req_pkt.pldm_type = kPldmType;
726     req_pkt.transfer_opflag = kFlag;
727     req_pkt.transfer_handle = kTransferHandle;
728     req_pkt.section_offset = kSectionOffset;
729 
730     std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
731     std::memcpy(req.data(), &hdr, sizeof(hdr));
732     std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
733 
734     pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
735     EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
736                                            &pldm_type, &flag, &transfer_ctx,
737                                            &transfer_handle, &section_offset,
738                                            &section_length),
739               PLDM_ERROR_INVALID_DATA);
740 }
741 
742 TEST(CcOnlyResponse, testEncode)
743 {
744     struct pldm_msg responseMsg;
745 
746     auto rc =
747         encode_cc_only_resp(0 /*instance id*/, 1 /*pldm type*/, 2 /*command*/,
748                             3 /*completion code*/, &responseMsg);
749     EXPECT_EQ(rc, PLDM_SUCCESS);
750 
751     auto p = reinterpret_cast<uint8_t*>(&responseMsg);
752     EXPECT_THAT(std::vector<uint8_t>(p, p + sizeof(responseMsg)),
753                 ElementsAreArray({0, 1, 2, 3}));
754 
755     rc = encode_cc_only_resp(PLDM_INSTANCE_MAX + 1, 1, 2, 3, &responseMsg);
756     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
757 
758     rc = encode_cc_only_resp(0, 1, 2, 3, nullptr);
759     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
760 }
761 
762 TEST(SetTID, testGoodEncodeRequest)
763 {
764     uint8_t instanceId = 0;
765     uint8_t tid = 0x01;
766     std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
767     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
768 
769     auto rc = encode_set_tid_req(instanceId, tid, request);
770     ASSERT_EQ(rc, PLDM_SUCCESS);
771 
772     EXPECT_EQ(request->hdr.command, PLDM_SET_TID);
773     EXPECT_EQ(request->hdr.type, PLDM_BASE);
774     EXPECT_EQ(request->hdr.request, 1);
775     EXPECT_EQ(request->hdr.datagram, 0);
776     EXPECT_EQ(request->hdr.instance_id, instanceId);
777     EXPECT_EQ(0, memcmp(request->payload, &tid, sizeof(tid)));
778 }
779 
780 TEST(SetTID, testBadEncodeRequest)
781 {
782     uint8_t tid = 0x01;
783     std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
784     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
785 
786     auto rc = encode_set_tid_req(0, tid, nullptr);
787     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
788 
789     rc = encode_set_tid_req(0, 0, request);
790     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
791 
792     rc = encode_set_tid_req(0, 0xff, request);
793     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
794 }
795 
796 #ifdef LIBPLDM_API_TESTING
797 TEST(PldmMsgHdr, correlateSuccess)
798 {
799     static const struct pldm_msg_hdr req = {
800         .instance_id = 0,
801         .reserved = 0,
802         .datagram = 0,
803         .request = 1,
804         .type = 0,
805         .header_ver = 1,
806         .command = 0x01,
807     };
808     static const struct pldm_msg_hdr resp = {
809         .instance_id = 0,
810         .reserved = 0,
811         .datagram = 0,
812         .request = 0,
813         .type = 0,
814         .header_ver = 1,
815         .command = 0x01,
816     };
817 
818     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), true);
819 }
820 #endif
821 
822 #ifdef LIBPLDM_API_TESTING
823 TEST(PldmMsgHdr, correlateFailInstanceID)
824 {
825     static const struct pldm_msg_hdr req = {
826         .instance_id = 0,
827         .reserved = 0,
828         .datagram = 0,
829         .request = 1,
830         .type = 0,
831         .header_ver = 1,
832         .command = 0x01,
833     };
834     static const struct pldm_msg_hdr resp = {
835         .instance_id = 1,
836         .reserved = 0,
837         .datagram = 0,
838         .request = 0,
839         .type = 0,
840         .header_ver = 1,
841         .command = 0x01,
842     };
843 
844     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
845 }
846 #endif
847 
848 #ifdef LIBPLDM_API_TESTING
849 TEST(PldmMsgHdr, correlateFailRequest)
850 {
851     static const struct pldm_msg_hdr req = {
852         .instance_id = 0,
853         .reserved = 0,
854         .datagram = 0,
855         .request = 1,
856         .type = 0,
857         .header_ver = 1,
858         .command = 0x01,
859     };
860     static const struct pldm_msg_hdr resp = {
861         .instance_id = 0,
862         .reserved = 0,
863         .datagram = 0,
864         .request = 1,
865         .type = 0,
866         .header_ver = 1,
867         .command = 0x01,
868     };
869 
870     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
871 }
872 #endif
873 
874 #ifdef LIBPLDM_API_TESTING
875 TEST(PldmMsgHdr, correlateFailType)
876 {
877     static const struct pldm_msg_hdr req = {
878         .instance_id = 0,
879         .reserved = 0,
880         .datagram = 0,
881         .request = 1,
882         .type = 0,
883         .header_ver = 1,
884         .command = 0x01,
885     };
886     static const struct pldm_msg_hdr resp = {
887         .instance_id = 0,
888         .reserved = 0,
889         .datagram = 0,
890         .request = 0,
891         .type = 1,
892         .header_ver = 1,
893         .command = 0x01,
894     };
895 
896     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
897 }
898 #endif
899 
900 #ifdef LIBPLDM_API_TESTING
901 TEST(PldmMsgHdr, correlateFailCommand)
902 {
903     static const struct pldm_msg_hdr req = {
904         .instance_id = 0,
905         .reserved = 0,
906         .datagram = 0,
907         .request = 1,
908         .type = 0,
909         .header_ver = 1,
910         .command = 0x01,
911     };
912     static const struct pldm_msg_hdr resp = {
913         .instance_id = 0,
914         .reserved = 0,
915         .datagram = 0,
916         .request = 0,
917         .type = 0,
918         .header_ver = 1,
919         .command = 0x02,
920     };
921 
922     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
923 }
924 #endif
925 
926 #ifdef LIBPLDM_API_TESTING
927 TEST(PldmMsgHdr, correlateFailRequestIsResponse)
928 {
929     static const struct pldm_msg_hdr req = {
930         .instance_id = 0,
931         .reserved = 0,
932         .datagram = 0,
933         .request = 0,
934         .type = 0,
935         .header_ver = 1,
936         .command = 0x01,
937     };
938     static const struct pldm_msg_hdr resp = {
939         .instance_id = 0,
940         .reserved = 0,
941         .datagram = 0,
942         .request = 0,
943         .type = 0,
944         .header_ver = 1,
945         .command = 0x02,
946     };
947 
948     ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
949 }
950 #endif
951