blob: b3b1383bbc9ad5c5ea9b4b59fa67459ad0046d11 [file] [log] [blame]
Andrew Jeffery9c766792022-08-10 23:12:49 +09301#include <string.h>
2
3#include <array>
4#include <cstring>
5#include <vector>
6
7#include "libpldm/base.h"
8
9#include <gmock/gmock.h>
10#include <gtest/gtest.h>
11
12using testing::ElementsAreArray;
13
14constexpr auto hdrSize = sizeof(pldm_msg_hdr);
15
16TEST(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
53TEST(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
97TEST(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
130TEST(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
139TEST(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
172TEST(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
197TEST(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
212TEST(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
233TEST(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
256TEST(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
277TEST(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
300TEST(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
319TEST(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
342TEST(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
362TEST(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
383TEST(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
395TEST(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
420TEST(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
448TEST(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
485TEST(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
493TEST(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
508TEST(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
527TEST(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
572TEST(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
579TEST(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
610TEST(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
641TEST(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
672TEST(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
707TEST(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
742TEST(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 /*complection 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}