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