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