1 #include "common/instance_id.hpp"
2 #include "common/utils.hpp"
3 #include "libpldmresponder/base.hpp"
4 #include "test/test_instance_id.hpp"
5 
6 #include <libpldm/base.h>
7 
8 #include <sdeventplus/event.hpp>
9 
10 #include <array>
11 #include <cstring>
12 
13 #include <gtest/gtest.h>
14 
15 using namespace pldm::responder;
16 
17 class TestBaseCommands : public testing::Test
18 {
19   protected:
20     TestBaseCommands() : event(sdeventplus::Event::get_default()) {}
21 
22     sdeventplus::Event event;
23 };
24 
25 TEST_F(TestBaseCommands, testPLDMTypesGoodRequest)
26 {
27     std::array<uint8_t, sizeof(pldm_msg_hdr)> requestPayload{};
28     auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
29     // payload length will be 0 in this case
30     size_t requestPayloadLength = 0;
31     base::Handler handler(event);
32     auto response = handler.getPLDMTypes(request, requestPayloadLength);
33     // Need to support OEM type.
34     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
35     uint8_t* payload_ptr = responsePtr->payload;
36     ASSERT_EQ(payload_ptr[0], 0);
37     ASSERT_EQ(payload_ptr[1], 29); // 0b11101 see DSP0240 table11
38     ASSERT_EQ(payload_ptr[2], 0);
39 }
40 
41 TEST_F(TestBaseCommands, testGetPLDMCommandsGoodRequest)
42 {
43     // Need to support OEM type commands.
44     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
45         requestPayload{};
46     auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
47     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
48     base::Handler handler(event);
49     auto response = handler.getPLDMCommands(request, requestPayloadLength);
50     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
51     uint8_t* payload_ptr = responsePtr->payload;
52     ASSERT_EQ(payload_ptr[0], 0);
53     ASSERT_EQ(payload_ptr[1], 60); // 60 = 0b111100
54     ASSERT_EQ(payload_ptr[2], 0);
55 }
56 
57 TEST_F(TestBaseCommands, testGetPLDMCommandsBadRequest)
58 {
59     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES>
60         requestPayload{};
61     auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
62 
63     request->payload[0] = 0xFF;
64     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
65     base::Handler handler(event);
66     auto response = handler.getPLDMCommands(request, requestPayloadLength);
67     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
68     uint8_t* payload_ptr = responsePtr->payload;
69     ASSERT_EQ(payload_ptr[0], PLDM_ERROR_INVALID_PLDM_TYPE);
70 }
71 
72 TEST_F(TestBaseCommands, testGetPLDMVersionGoodRequest)
73 {
74     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
75         requestPayload{};
76     auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
77     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
78 
79     uint8_t pldmType = PLDM_BASE;
80     uint32_t transferHandle = 0x0;
81     uint8_t flag = PLDM_GET_FIRSTPART;
82     uint8_t retFlag = PLDM_START_AND_END;
83     ver32_t version = {0x00, 0xF0, 0xF0, 0xF1};
84 
85     auto rc =
86         encode_get_version_req(0, transferHandle, flag, pldmType, request);
87 
88     ASSERT_EQ(0, rc);
89 
90     base::Handler handler(event);
91     auto response = handler.getPLDMVersion(request, requestPayloadLength);
92     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
93 
94     ASSERT_EQ(responsePtr->payload[0], 0);
95     ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]),
96                         &transferHandle, sizeof(transferHandle)));
97     ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]) +
98                             sizeof(transferHandle),
99                         &retFlag, sizeof(flag)));
100     ASSERT_EQ(0, memcmp(responsePtr->payload + sizeof(responsePtr->payload[0]) +
101                             sizeof(transferHandle) + sizeof(flag),
102                         &version, sizeof(version)));
103 }
104 
105 TEST_F(TestBaseCommands, testGetPLDMVersionBadRequest)
106 {
107     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES>
108         requestPayload{};
109     auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
110     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
111 
112     uint8_t pldmType = 7;
113     uint32_t transferHandle = 0x0;
114     uint8_t flag = PLDM_GET_FIRSTPART;
115 
116     auto rc =
117         encode_get_version_req(0, transferHandle, flag, pldmType, request);
118 
119     ASSERT_EQ(0, rc);
120 
121     base::Handler handler(event);
122     auto response = handler.getPLDMVersion(request, requestPayloadLength - 1);
123     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
124 
125     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
126 
127     request = reinterpret_cast<pldm_msg*>(requestPayload.data());
128     requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
129 
130     rc = encode_get_version_req(0, transferHandle, flag, pldmType, request);
131 
132     ASSERT_EQ(0, rc);
133 
134     response = handler.getPLDMVersion(request, requestPayloadLength);
135     responsePtr = reinterpret_cast<pldm_msg*>(response.data());
136 
137     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_PLDM_TYPE);
138 }
139 
140 TEST_F(TestBaseCommands, testGetTIDGoodRequest)
141 {
142     std::array<uint8_t, sizeof(pldm_msg_hdr)> requestPayload{};
143     auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
144     size_t requestPayloadLength = 0;
145 
146     base::Handler handler(event);
147     handler.setOemPlatformHandler(nullptr);
148     auto response = handler.getTID(request, requestPayloadLength);
149 
150     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
151     uint8_t* payload = responsePtr->payload;
152 
153     ASSERT_EQ(payload[0], 0);
154     ASSERT_EQ(payload[1], 1);
155 }
156