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
TEST(PackPLDMMessage,BadPathTest)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
TEST(PackPLDMMessage,RequestMessageGoodPath)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
TEST(PackPLDMMessage,ResponseMessageGoodPath)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
TEST(UnpackPLDMMessage,BadPathTest)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
TEST(UnpackPLDMMessage,RequestMessageGoodPath)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
TEST(UnpackPLDMMessage,ResponseMessageGoodPath)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
TEST(GetPLDMCommands,testEncodeRequest)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 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
204 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
205
206 auto rc = encode_get_commands_req(0, pldmType, version, request);
207 EXPECT_EQ(rc, PLDM_SUCCESS);
208 EXPECT_EQ(0, memcmp(request->payload, &pldmType, sizeof(pldmType)));
209 EXPECT_EQ(0, memcmp(request->payload + sizeof(pldmType), &version,
210 sizeof(version)));
211 }
212
TEST(GetPLDMCommands,testDecodeRequest)213 TEST(GetPLDMCommands, testDecodeRequest)
214 {
215 uint8_t pldmType = 0x05;
216 ver32_t version{0xff, 0xff, 0xff, 0xff};
217 uint8_t pldmTypeOut{};
218 ver32_t versionOut{0xff, 0xff, 0xff, 0xff};
219 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_REQ_BYTES> requestMsg{};
220
221 memcpy(requestMsg.data() + hdrSize, &pldmType, sizeof(pldmType));
222 memcpy(requestMsg.data() + sizeof(pldmType) + hdrSize, &version,
223 sizeof(version));
224
225 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
226 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
227 auto rc = decode_get_commands_req(request, requestMsg.size() - hdrSize,
228 &pldmTypeOut, &versionOut);
229
230 EXPECT_EQ(rc, PLDM_SUCCESS);
231 EXPECT_EQ(pldmTypeOut, pldmType);
232 EXPECT_EQ(0, memcmp(&versionOut, &version, sizeof(version)));
233 }
234
TEST(GetPLDMCommands,testEncodeResponse)235 TEST(GetPLDMCommands, testEncodeResponse)
236 {
237 uint8_t completionCode = 0;
238 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES>
239 responseMsg{};
240 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
241 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
242 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> commands{};
243 commands[0].byte = 1;
244 commands[1].byte = 2;
245 commands[2].byte = 3;
246
247 auto rc =
248 encode_get_commands_resp(0, PLDM_SUCCESS, commands.data(), response);
249 EXPECT_EQ(rc, PLDM_SUCCESS);
250 uint8_t* payload_ptr = response->payload;
251 EXPECT_EQ(completionCode, payload_ptr[0]);
252 EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]);
253 EXPECT_EQ(2,
254 payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte)]);
255 EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(commands[0].byte) +
256 sizeof(commands[1].byte)]);
257 }
258
TEST(GetPLDMTypes,testEncodeResponse)259 TEST(GetPLDMTypes, testEncodeResponse)
260 {
261 uint8_t completionCode = 0;
262 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES>
263 responseMsg{};
264 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
265 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
266 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> types{};
267 types[0].byte = 1;
268 types[1].byte = 2;
269 types[2].byte = 3;
270
271 auto rc = encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response);
272 EXPECT_EQ(rc, PLDM_SUCCESS);
273 uint8_t* payload_ptr = response->payload;
274 EXPECT_EQ(completionCode, payload_ptr[0]);
275 EXPECT_EQ(1, payload_ptr[sizeof(completionCode)]);
276 EXPECT_EQ(2, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte)]);
277 EXPECT_EQ(3, payload_ptr[sizeof(completionCode) + sizeof(types[0].byte) +
278 sizeof(types[1].byte)]);
279 }
280
TEST(GetPLDMTypes,testGoodDecodeResponse)281 TEST(GetPLDMTypes, testGoodDecodeResponse)
282 {
283 std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
284 responseMsg[1 + hdrSize] = 1;
285 responseMsg[2 + hdrSize] = 2;
286 responseMsg[3 + hdrSize] = 3;
287 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
288
289 uint8_t completion_code;
290 responseMsg[hdrSize] = PLDM_SUCCESS;
291
292 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
293 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
294
295 auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize,
296 &completion_code, outTypes.data());
297
298 EXPECT_EQ(rc, PLDM_SUCCESS);
299 EXPECT_EQ(completion_code, PLDM_SUCCESS);
300 EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte);
301 EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte);
302 EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte);
303 }
304
TEST(GetPLDMTypes,testBadDecodeResponse)305 TEST(GetPLDMTypes, testBadDecodeResponse)
306 {
307 std::array<uint8_t, hdrSize + PLDM_GET_TYPES_RESP_BYTES> responseMsg{};
308 responseMsg[1 + hdrSize] = 1;
309 responseMsg[2 + hdrSize] = 2;
310 responseMsg[3 + hdrSize] = 3;
311 std::array<bitfield8_t, PLDM_MAX_TYPES / 8> outTypes{};
312
313 uint8_t retcompletion_code = 0;
314 responseMsg[hdrSize] = PLDM_SUCCESS;
315
316 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
317 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
318
319 auto rc = decode_get_types_resp(response, responseMsg.size() - hdrSize - 1,
320 &retcompletion_code, outTypes.data());
321
322 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
323 }
324
TEST(GetPLDMCommands,testGoodDecodeResponse)325 TEST(GetPLDMCommands, testGoodDecodeResponse)
326 {
327 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
328 responseMsg[1 + hdrSize] = 1;
329 responseMsg[2 + hdrSize] = 2;
330 responseMsg[3 + hdrSize] = 3;
331 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
332
333 uint8_t completion_code;
334 responseMsg[hdrSize] = PLDM_SUCCESS;
335
336 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
337 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
338
339 auto rc = decode_get_commands_resp(response, responseMsg.size() - hdrSize,
340 &completion_code, outTypes.data());
341
342 EXPECT_EQ(rc, PLDM_SUCCESS);
343 EXPECT_EQ(completion_code, PLDM_SUCCESS);
344 EXPECT_EQ(responseMsg[1 + hdrSize], outTypes[0].byte);
345 EXPECT_EQ(responseMsg[2 + hdrSize], outTypes[1].byte);
346 EXPECT_EQ(responseMsg[3 + hdrSize], outTypes[2].byte);
347 }
348
TEST(GetPLDMCommands,testBadDecodeResponse)349 TEST(GetPLDMCommands, testBadDecodeResponse)
350 {
351 std::array<uint8_t, hdrSize + PLDM_GET_COMMANDS_RESP_BYTES> responseMsg{};
352 responseMsg[1 + hdrSize] = 1;
353 responseMsg[2 + hdrSize] = 2;
354 responseMsg[3 + hdrSize] = 3;
355 std::array<bitfield8_t, PLDM_MAX_CMDS_PER_TYPE / 8> outTypes{};
356
357 uint8_t retcompletion_code = 0;
358 responseMsg[hdrSize] = PLDM_SUCCESS;
359
360 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
361 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
362
363 auto rc =
364 decode_get_commands_resp(response, responseMsg.size() - hdrSize - 1,
365 &retcompletion_code, outTypes.data());
366
367 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
368 }
369
TEST(GetPLDMVersion,testGoodEncodeRequest)370 TEST(GetPLDMVersion, testGoodEncodeRequest)
371 {
372 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
373 requestMsg{};
374 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
375 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
376 uint8_t pldmType = 0x03;
377 uint32_t transferHandle = 0x0;
378 uint8_t opFlag = 0x01;
379
380 auto rc =
381 encode_get_version_req(0, transferHandle, opFlag, pldmType, request);
382 EXPECT_EQ(rc, PLDM_SUCCESS);
383 EXPECT_EQ(
384 0, memcmp(request->payload, &transferHandle, sizeof(transferHandle)));
385 EXPECT_EQ(0, memcmp(request->payload + sizeof(transferHandle), &opFlag,
386 sizeof(opFlag)));
387 EXPECT_EQ(0,
388 memcmp(request->payload + sizeof(transferHandle) + sizeof(opFlag),
389 &pldmType, sizeof(pldmType)));
390 }
391
TEST(GetPLDMVersion,testBadEncodeRequest)392 TEST(GetPLDMVersion, testBadEncodeRequest)
393 {
394 uint8_t pldmType = 0x03;
395 uint32_t transferHandle = 0x0;
396 uint8_t opFlag = 0x01;
397
398 auto rc =
399 encode_get_version_req(0, transferHandle, opFlag, pldmType, nullptr);
400
401 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
402 }
403
TEST(GetPLDMVersion,testEncodeResponse)404 TEST(GetPLDMVersion, testEncodeResponse)
405 {
406 uint8_t completionCode = 0;
407 uint32_t transferHandle = 0;
408 uint8_t flag = PLDM_START_AND_END;
409 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES>
410 responseMsg{};
411 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
412 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
413 ver32_t version = {0xff, 0xff, 0xff, 0xff};
414
415 auto rc = encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END,
416 &version, sizeof(ver32_t), response);
417
418 EXPECT_EQ(rc, PLDM_SUCCESS);
419 EXPECT_EQ(completionCode, response->payload[0]);
420 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]),
421 &transferHandle, sizeof(transferHandle)));
422 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
423 sizeof(transferHandle),
424 &flag, sizeof(flag)));
425 EXPECT_EQ(0, memcmp(response->payload + sizeof(response->payload[0]) +
426 sizeof(transferHandle) + sizeof(flag),
427 &version, sizeof(version)));
428 }
429
TEST(GetPLDMVersion,testDecodeRequest)430 TEST(GetPLDMVersion, testDecodeRequest)
431 {
432 std::array<uint8_t, hdrSize + PLDM_GET_VERSION_REQ_BYTES> requestMsg{};
433 uint32_t transferHandle = 0x0;
434 uint32_t retTransferHandle = 0x0;
435 uint8_t flag = PLDM_GET_FIRSTPART;
436 uint8_t retFlag = PLDM_GET_FIRSTPART;
437 uint8_t pldmType = PLDM_BASE;
438 uint8_t retType = PLDM_BASE;
439
440 memcpy(requestMsg.data() + hdrSize, &transferHandle,
441 sizeof(transferHandle));
442 memcpy(requestMsg.data() + sizeof(transferHandle) + hdrSize, &flag,
443 sizeof(flag));
444 memcpy(requestMsg.data() + sizeof(transferHandle) + sizeof(flag) + hdrSize,
445 &pldmType, sizeof(pldmType));
446
447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
448 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
449
450 auto rc = decode_get_version_req(request, requestMsg.size() - hdrSize,
451 &retTransferHandle, &retFlag, &retType);
452
453 EXPECT_EQ(rc, PLDM_SUCCESS);
454 EXPECT_EQ(transferHandle, retTransferHandle);
455 EXPECT_EQ(flag, retFlag);
456 EXPECT_EQ(pldmType, retType);
457 }
458
TEST(GetPLDMVersion,testDecodeResponse)459 TEST(GetPLDMVersion, testDecodeResponse)
460 {
461 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES>
462 responseMsg{};
463 uint32_t transferHandle = 0x0;
464 uint32_t retTransferHandle = 0x0;
465 uint8_t flag = PLDM_START_AND_END;
466 uint8_t retFlag = PLDM_START_AND_END;
467 uint8_t completionCode = 0;
468 ver32_t version = {0xff, 0xff, 0xff, 0xff};
469 ver32_t versionOut;
470 uint8_t completion_code;
471
472 memcpy(responseMsg.data() + sizeof(completionCode) + hdrSize,
473 &transferHandle, sizeof(transferHandle));
474 memcpy(responseMsg.data() + sizeof(completionCode) +
475 sizeof(transferHandle) + hdrSize,
476 &flag, sizeof(flag));
477 memcpy(responseMsg.data() + sizeof(completionCode) +
478 sizeof(transferHandle) + sizeof(flag) + hdrSize,
479 &version, sizeof(version));
480
481 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
482 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
483
484 auto rc = decode_get_version_resp(response, responseMsg.size() - hdrSize,
485 &completion_code, &retTransferHandle,
486 &retFlag, &versionOut);
487 EXPECT_EQ(rc, PLDM_SUCCESS);
488 EXPECT_EQ(transferHandle, retTransferHandle);
489 EXPECT_EQ(flag, retFlag);
490
491 EXPECT_EQ(versionOut.major, version.major);
492 EXPECT_EQ(versionOut.minor, version.minor);
493 EXPECT_EQ(versionOut.update, version.update);
494 EXPECT_EQ(versionOut.alpha, version.alpha);
495 }
496
TEST(GetTID,testEncodeRequest)497 TEST(GetTID, testEncodeRequest)
498 {
499 pldm_msg request{};
500
501 auto rc = encode_get_tid_req(0, &request);
502 ASSERT_EQ(rc, PLDM_SUCCESS);
503 }
504
TEST(GetTID,testEncodeResponse)505 TEST(GetTID, testEncodeResponse)
506 {
507 uint8_t completionCode = 0;
508 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES>
509 responseMsg{};
510 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
511 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
512 uint8_t tid = 1;
513
514 auto rc = encode_get_tid_resp(0, PLDM_SUCCESS, tid, response);
515 EXPECT_EQ(rc, PLDM_SUCCESS);
516 uint8_t* payload = response->payload;
517 EXPECT_EQ(completionCode, payload[0]);
518 EXPECT_EQ(1, payload[sizeof(completionCode)]);
519 }
520
TEST(GetTID,testDecodeResponse)521 TEST(GetTID, testDecodeResponse)
522 {
523 std::array<uint8_t, hdrSize + PLDM_GET_TID_RESP_BYTES> responseMsg{};
524 responseMsg[1 + hdrSize] = 1;
525
526 uint8_t tid;
527 uint8_t completion_code;
528 responseMsg[hdrSize] = PLDM_SUCCESS;
529
530 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
531 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
532
533 auto rc = decode_get_tid_resp(response, responseMsg.size() - hdrSize,
534 &completion_code, &tid);
535
536 EXPECT_EQ(rc, PLDM_SUCCESS);
537 EXPECT_EQ(completion_code, PLDM_SUCCESS);
538 EXPECT_EQ(tid, 1);
539 }
540
TEST(MultipartReceive,testDecodeRequestPass)541 TEST(MultipartReceive, testDecodeRequestPass)
542 {
543 constexpr uint8_t kPldmType = PLDM_BASE;
544 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
545 constexpr uint32_t kTransferCtx = 0x01;
546 constexpr uint32_t kTransferHandle = 0x10;
547 constexpr uint32_t kSectionOffset = 0x0;
548 constexpr uint32_t kSectionLength = 0x10;
549 uint8_t pldm_type = 0x0;
550 uint8_t flag = PLDM_GET_FIRSTPART;
551 uint32_t transfer_ctx;
552 uint32_t transfer_handle;
553 uint32_t section_offset;
554 uint32_t section_length;
555
556 // Header values don't matter for this test.
557 pldm_msg_hdr hdr{};
558 // Assign values to the packet struct and memcpy to ensure correct byte
559 // ordering.
560 pldm_multipart_receive_req req_pkt = {
561 .pldm_type = kPldmType,
562 .transfer_opflag = kFlag,
563 .transfer_ctx = kTransferCtx,
564 .transfer_handle = kTransferHandle,
565 .section_offset = kSectionOffset,
566 .section_length = kSectionLength,
567 };
568 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
569 std::memcpy(req.data(), &hdr, sizeof(hdr));
570 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
571
572 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
573 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
574 int rc = decode_multipart_receive_req(
575 pldm_request, req.size() - hdrSize, &pldm_type, &flag, &transfer_ctx,
576 &transfer_handle, §ion_offset, §ion_length);
577
578 EXPECT_EQ(rc, PLDM_SUCCESS);
579 EXPECT_EQ(pldm_type, kPldmType);
580 EXPECT_EQ(flag, kFlag);
581 EXPECT_EQ(transfer_ctx, kTransferCtx);
582 EXPECT_EQ(transfer_handle, kTransferHandle);
583 EXPECT_EQ(section_offset, kSectionOffset);
584 EXPECT_EQ(section_length, kSectionLength);
585 }
586
TEST(MultipartReceive,testDecodeRequestFailNullData)587 TEST(MultipartReceive, testDecodeRequestFailNullData)
588 {
589 EXPECT_EQ(decode_multipart_receive_req(NULL, 0, NULL, NULL, NULL, NULL,
590 NULL, NULL),
591 PLDM_ERROR_INVALID_DATA);
592 }
593
TEST(MultipartReceive,testDecodeRequestFailBadLength)594 TEST(MultipartReceive, testDecodeRequestFailBadLength)
595 {
596 constexpr uint8_t kPldmType = PLDM_BASE;
597 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
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 // Header values don't matter for this test.
606 pldm_msg_hdr hdr{};
607 // Assign values to the packet struct and memcpy to ensure correct byte
608 // ordering.
609 pldm_multipart_receive_req req_pkt{};
610 req_pkt.pldm_type = kPldmType;
611 req_pkt.transfer_opflag = kFlag;
612
613 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
614 std::memcpy(req.data(), &hdr, sizeof(hdr));
615 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
616
617 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
618 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
619 EXPECT_EQ(decode_multipart_receive_req(
620 pldm_request, (req.size() - hdrSize) + 1, &pldm_type, &flag,
621 &transfer_ctx, &transfer_handle, §ion_offset,
622 §ion_length),
623 PLDM_ERROR_INVALID_LENGTH);
624 }
625
TEST(MultipartReceive,testDecodeRequestFailBadPldmType)626 TEST(MultipartReceive, testDecodeRequestFailBadPldmType)
627 {
628 constexpr uint8_t kPldmType = 0xff;
629 constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
630 uint8_t pldm_type;
631 uint8_t flag;
632 uint32_t transfer_ctx;
633 uint32_t transfer_handle;
634 uint32_t section_offset;
635 uint32_t section_length;
636
637 // Header values don't matter for this test.
638 pldm_msg_hdr hdr{};
639 // Assign values to the packet struct and memcpy to ensure correct byte
640 // ordering.
641 pldm_multipart_receive_req req_pkt{};
642 req_pkt.pldm_type = kPldmType;
643 req_pkt.transfer_opflag = kFlag;
644
645 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
646 std::memcpy(req.data(), &hdr, sizeof(hdr));
647 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
648
649 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
650 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
651 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
652 &pldm_type, &flag, &transfer_ctx,
653 &transfer_handle, §ion_offset,
654 §ion_length),
655 PLDM_ERROR_INVALID_PLDM_TYPE);
656 }
657
TEST(MultipartReceive,testDecodeRequestFailBadTransferFlag)658 TEST(MultipartReceive, testDecodeRequestFailBadTransferFlag)
659 {
660 constexpr uint8_t kPldmType = PLDM_BASE;
661 constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10;
662 uint8_t pldm_type;
663 uint8_t flag;
664 uint32_t transfer_ctx;
665 uint32_t transfer_handle;
666 uint32_t section_offset;
667 uint32_t section_length;
668
669 // Header values don't matter for this test.
670 pldm_msg_hdr hdr{};
671 // Assign values to the packet struct and memcpy to ensure correct byte
672 // ordering.
673 pldm_multipart_receive_req req_pkt{};
674 req_pkt.pldm_type = kPldmType;
675 req_pkt.transfer_opflag = kFlag;
676
677 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
678 std::memcpy(req.data(), &hdr, sizeof(hdr));
679 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
680
681 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
682 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
683 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
684 &pldm_type, &flag, &transfer_ctx,
685 &transfer_handle, §ion_offset,
686 §ion_length),
687 PLDM_INVALID_TRANSFER_OPERATION_FLAG);
688 }
689
TEST(MultipartReceive,testDecodeRequestFailBadOffset)690 TEST(MultipartReceive, testDecodeRequestFailBadOffset)
691 {
692 constexpr uint8_t kPldmType = PLDM_BASE;
693 constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
694 constexpr uint32_t kTransferHandle = 0x01;
695 constexpr uint32_t kSectionOffset = 0x0;
696 uint8_t pldm_type;
697 uint8_t flag;
698 uint32_t transfer_ctx;
699 uint32_t transfer_handle;
700 uint32_t section_offset;
701 uint32_t section_length;
702
703 // Header values don't matter for this test.
704 pldm_msg_hdr hdr{};
705 // Assign values to the packet struct and memcpy to ensure correct byte
706 // ordering.
707 pldm_multipart_receive_req req_pkt{};
708 req_pkt.pldm_type = kPldmType;
709 req_pkt.transfer_opflag = kFlag;
710 req_pkt.transfer_handle = kTransferHandle;
711 req_pkt.section_offset = kSectionOffset;
712
713 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
714 std::memcpy(req.data(), &hdr, sizeof(hdr));
715 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
716
717 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
718 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
719 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
720 &pldm_type, &flag, &transfer_ctx,
721 &transfer_handle, §ion_offset,
722 §ion_length),
723 PLDM_ERROR_INVALID_DATA);
724 }
725
TEST(MultipartReceive,testDecodeRequestFailBadHandle)726 TEST(MultipartReceive, testDecodeRequestFailBadHandle)
727 {
728 constexpr uint8_t kPldmType = PLDM_BASE;
729 constexpr uint8_t kFlag = PLDM_XFER_NEXT_PART;
730 constexpr uint32_t kSectionOffset = 0x100;
731 constexpr uint32_t kTransferHandle = 0x0;
732 uint8_t pldm_type;
733 uint8_t flag;
734 uint32_t transfer_ctx;
735 uint32_t transfer_handle;
736 uint32_t section_offset;
737 uint32_t section_length;
738
739 // Header values don't matter for this test.
740 pldm_msg_hdr hdr{};
741 // Assign values to the packet struct and memcpy to ensure correct byte
742 // ordering.
743 pldm_multipart_receive_req req_pkt{};
744 req_pkt.pldm_type = kPldmType;
745 req_pkt.transfer_opflag = kFlag;
746 req_pkt.transfer_handle = kTransferHandle;
747 req_pkt.section_offset = kSectionOffset;
748
749 std::vector<uint8_t> req(sizeof(hdr) + PLDM_MULTIPART_RECEIVE_REQ_BYTES);
750 std::memcpy(req.data(), &hdr, sizeof(hdr));
751 std::memcpy(req.data() + sizeof(hdr), &req_pkt, sizeof(req_pkt));
752
753 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
754 pldm_msg* pldm_request = reinterpret_cast<pldm_msg*>(req.data());
755 EXPECT_EQ(decode_multipart_receive_req(pldm_request, req.size() - hdrSize,
756 &pldm_type, &flag, &transfer_ctx,
757 &transfer_handle, §ion_offset,
758 §ion_length),
759 PLDM_ERROR_INVALID_DATA);
760 }
761
TEST(CcOnlyResponse,testEncode)762 TEST(CcOnlyResponse, testEncode)
763 {
764 struct pldm_msg responseMsg;
765
766 auto rc =
767 encode_cc_only_resp(0 /*instance id*/, 1 /*pldm type*/, 2 /*command*/,
768 3 /*completion code*/, &responseMsg);
769 EXPECT_EQ(rc, PLDM_SUCCESS);
770
771 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
772 auto p = reinterpret_cast<uint8_t*>(&responseMsg);
773 EXPECT_THAT(std::vector<uint8_t>(p, p + sizeof(responseMsg)),
774 ElementsAreArray({0, 1, 2, 3}));
775
776 rc = encode_cc_only_resp(PLDM_INSTANCE_MAX + 1, 1, 2, 3, &responseMsg);
777 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
778
779 rc = encode_cc_only_resp(0, 1, 2, 3, nullptr);
780 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
781 }
782
TEST(SetTID,testGoodEncodeRequest)783 TEST(SetTID, testGoodEncodeRequest)
784 {
785 uint8_t instanceId = 0;
786 uint8_t tid = 0x01;
787 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
788 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
789 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
790
791 auto rc = encode_set_tid_req(instanceId, tid, request);
792 ASSERT_EQ(rc, PLDM_SUCCESS);
793
794 EXPECT_EQ(request->hdr.command, PLDM_SET_TID);
795 EXPECT_EQ(request->hdr.type, PLDM_BASE);
796 EXPECT_EQ(request->hdr.request, 1);
797 EXPECT_EQ(request->hdr.datagram, 0);
798 EXPECT_EQ(request->hdr.instance_id, instanceId);
799 EXPECT_EQ(0, memcmp(request->payload, &tid, sizeof(tid)));
800 }
801
TEST(SetTID,testBadEncodeRequest)802 TEST(SetTID, testBadEncodeRequest)
803 {
804 uint8_t tid = 0x01;
805 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(tid)> requestMsg{};
806 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
807 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
808
809 auto rc = encode_set_tid_req(0, tid, nullptr);
810 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
811
812 rc = encode_set_tid_req(0, 0, request);
813 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
814
815 rc = encode_set_tid_req(0, 0xff, request);
816 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
817 }
818
819 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateSuccess)820 TEST(PldmMsgHdr, correlateSuccess)
821 {
822 static const struct pldm_msg_hdr req = {
823 .instance_id = 0,
824 .reserved = 0,
825 .datagram = 0,
826 .request = 1,
827 .type = 0,
828 .header_ver = 1,
829 .command = 0x01,
830 };
831 static const struct pldm_msg_hdr resp = {
832 .instance_id = 0,
833 .reserved = 0,
834 .datagram = 0,
835 .request = 0,
836 .type = 0,
837 .header_ver = 1,
838 .command = 0x01,
839 };
840
841 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), true);
842 }
843 #endif
844
845 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailInstanceID)846 TEST(PldmMsgHdr, correlateFailInstanceID)
847 {
848 static const struct pldm_msg_hdr req = {
849 .instance_id = 0,
850 .reserved = 0,
851 .datagram = 0,
852 .request = 1,
853 .type = 0,
854 .header_ver = 1,
855 .command = 0x01,
856 };
857 static const struct pldm_msg_hdr resp = {
858 .instance_id = 1,
859 .reserved = 0,
860 .datagram = 0,
861 .request = 0,
862 .type = 0,
863 .header_ver = 1,
864 .command = 0x01,
865 };
866
867 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
868 }
869 #endif
870
871 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailRequest)872 TEST(PldmMsgHdr, correlateFailRequest)
873 {
874 static const struct pldm_msg_hdr req = {
875 .instance_id = 0,
876 .reserved = 0,
877 .datagram = 0,
878 .request = 1,
879 .type = 0,
880 .header_ver = 1,
881 .command = 0x01,
882 };
883 static const struct pldm_msg_hdr resp = {
884 .instance_id = 0,
885 .reserved = 0,
886 .datagram = 0,
887 .request = 1,
888 .type = 0,
889 .header_ver = 1,
890 .command = 0x01,
891 };
892
893 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
894 }
895 #endif
896
897 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailType)898 TEST(PldmMsgHdr, correlateFailType)
899 {
900 static const struct pldm_msg_hdr req = {
901 .instance_id = 0,
902 .reserved = 0,
903 .datagram = 0,
904 .request = 1,
905 .type = 0,
906 .header_ver = 1,
907 .command = 0x01,
908 };
909 static const struct pldm_msg_hdr resp = {
910 .instance_id = 0,
911 .reserved = 0,
912 .datagram = 0,
913 .request = 0,
914 .type = 1,
915 .header_ver = 1,
916 .command = 0x01,
917 };
918
919 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
920 }
921 #endif
922
923 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailCommand)924 TEST(PldmMsgHdr, correlateFailCommand)
925 {
926 static const struct pldm_msg_hdr req = {
927 .instance_id = 0,
928 .reserved = 0,
929 .datagram = 0,
930 .request = 1,
931 .type = 0,
932 .header_ver = 1,
933 .command = 0x01,
934 };
935 static const struct pldm_msg_hdr resp = {
936 .instance_id = 0,
937 .reserved = 0,
938 .datagram = 0,
939 .request = 0,
940 .type = 0,
941 .header_ver = 1,
942 .command = 0x02,
943 };
944
945 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
946 }
947 #endif
948
949 #ifdef LIBPLDM_API_TESTING
TEST(PldmMsgHdr,correlateFailRequestIsResponse)950 TEST(PldmMsgHdr, correlateFailRequestIsResponse)
951 {
952 static const struct pldm_msg_hdr req = {
953 .instance_id = 0,
954 .reserved = 0,
955 .datagram = 0,
956 .request = 0,
957 .type = 0,
958 .header_ver = 1,
959 .command = 0x01,
960 };
961 static const struct pldm_msg_hdr resp = {
962 .instance_id = 0,
963 .reserved = 0,
964 .datagram = 0,
965 .request = 0,
966 .type = 0,
967 .header_ver = 1,
968 .command = 0x02,
969 };
970
971 ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
972 }
973 #endif
974