xref: /openbmc/pldm/platform-mc/test/terminus_manager_test.cpp (revision c40d4a68684a114b6a26adeca40b49146aa2c319)
1 #include "common/instance_id.hpp"
2 #include "common/types.hpp"
3 #include "mock_terminus_manager.hpp"
4 #include "platform-mc/platform_manager.hpp"
5 #include "platform-mc/terminus_manager.hpp"
6 #include "requester/handler.hpp"
7 #include "requester/mctp_endpoint_discovery.hpp"
8 #include "requester/request.hpp"
9 #include "test/test_instance_id.hpp"
10 
11 #include <libpldm/base.h>
12 #include <libpldm/bios.h>
13 #include <libpldm/fru.h>
14 #include <libpldm/platform.h>
15 
16 #include <sdbusplus/timer.hpp>
17 #include <sdeventplus/event.hpp>
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 using ::testing::AtLeast;
23 using ::testing::Between;
24 using ::testing::Exactly;
25 using ::testing::NiceMock;
26 using ::testing::Return;
27 
28 class TerminusManagerTest : public testing::Test
29 {
30   protected:
TerminusManagerTest()31     TerminusManagerTest() :
32         bus(pldm::utils::DBusHandler::getBus()),
33         event(sdeventplus::Event::get_default()), instanceIdDb(),
34         reqHandler(pldmTransport, event, instanceIdDb, false,
35                    std::chrono::seconds(1), 2, std::chrono::milliseconds(100)),
36         terminusManager(event, reqHandler, instanceIdDb, termini, nullptr,
37                         pldm::BmcMctpEid),
38         mockTerminusManager(event, reqHandler, instanceIdDb, termini, nullptr),
39         platformManager(mockTerminusManager, termini, nullptr)
40     {}
41 
42     PldmTransport* pldmTransport = nullptr;
43     sdbusplus::bus_t& bus;
44     sdeventplus::Event event;
45     TestInstanceIdDb instanceIdDb;
46     pldm::requester::Handler<pldm::requester::Request> reqHandler;
47     pldm::platform_mc::TerminusManager terminusManager;
48     pldm::platform_mc::MockTerminusManager mockTerminusManager;
49     pldm::platform_mc::PlatformManager platformManager;
50     std::map<pldm_tid_t, std::shared_ptr<pldm::platform_mc::Terminus>> termini;
51 };
52 
TEST_F(TerminusManagerTest,mapTidTest)53 TEST_F(TerminusManagerTest, mapTidTest)
54 {
55     pldm::MctpInfo mctpInfo1(8, "", "", 0, std::nullopt);
56 
57     auto mappedTid1 = terminusManager.mapTid(mctpInfo1);
58     EXPECT_NE(mappedTid1, std::nullopt);
59 
60     auto tid1 = terminusManager.toTid(mctpInfo1);
61     EXPECT_NE(tid1, std::nullopt);
62 
63     auto mctpInfo2 = terminusManager.toMctpInfo(tid1.value());
64     EXPECT_EQ(mctpInfo1, mctpInfo2.value());
65 
66     auto ret = terminusManager.unmapTid(tid1.value());
67     EXPECT_EQ(ret, true);
68 
69     tid1 = terminusManager.toTid(mctpInfo1);
70     EXPECT_EQ(tid1, std::nullopt);
71 }
72 
TEST_F(TerminusManagerTest,negativeMapTidTest)73 TEST_F(TerminusManagerTest, negativeMapTidTest)
74 {
75     // map null EID(0) to TID
76     pldm::MctpInfo m0(0, "", "", 0, std::nullopt);
77     auto mappedTid = terminusManager.mapTid(m0);
78     EXPECT_EQ(mappedTid, std::nullopt);
79 
80     // map broadcast EID(0xff) to TID
81     pldm::MctpInfo m1(0xff, "", "", 0, std::nullopt);
82     mappedTid = terminusManager.mapTid(m1);
83     EXPECT_EQ(mappedTid, std::nullopt);
84 
85     // map EID to tid which has been assigned
86     pldm::MctpInfo m2(9, "", "", 1, std::nullopt);
87     pldm::MctpInfo m3(10, "", "", 1, std::nullopt);
88     auto mappedTid2 = terminusManager.mapTid(m2);
89     auto mappedTid3 = terminusManager.storeTerminusInfo(m3, mappedTid2.value());
90     EXPECT_NE(mappedTid2, std::nullopt);
91     EXPECT_EQ(mappedTid3, std::nullopt);
92 
93     // map two mctpInfo with same EID but different network Id
94     pldm::MctpInfo m4(12, "", "", 1, std::nullopt);
95     pldm::MctpInfo m5(12, "", "", 2, std::nullopt);
96     auto mappedTid4 = terminusManager.mapTid(m4);
97     auto mappedTid5 = terminusManager.mapTid(m5);
98     EXPECT_NE(mappedTid4.value(), mappedTid5.value());
99 
100     // map same mctpInfo twice
101     pldm::MctpInfo m6(12, "", "", 3, std::nullopt);
102     auto mappedTid6 = terminusManager.mapTid(m6);
103     auto mappedTid6_1 = terminusManager.mapTid(m6);
104     EXPECT_EQ(mappedTid6.value(), mappedTid6_1.value());
105 
106     // look up an unmapped MctpInfo to TID
107     pldm::MctpInfo m7(1, "", "", 0, std::nullopt);
108     auto mappedTid7 = terminusManager.toTid(m7);
109     EXPECT_EQ(mappedTid7, std::nullopt);
110 
111     // look up reserved TID(0)
112     auto mappedEid = terminusManager.toMctpInfo(0);
113     EXPECT_EQ(mappedEid, std::nullopt);
114 
115     // look up reserved TID(0xff)
116     mappedEid = terminusManager.toMctpInfo(0xff);
117     EXPECT_EQ(mappedEid, std::nullopt);
118 
119     // look up an unmapped TID
120     terminusManager.unmapTid(1);
121     mappedEid = terminusManager.toMctpInfo(1);
122     EXPECT_EQ(mappedEid, std::nullopt);
123 
124     // unmap reserved TID(0)
125     auto ret = terminusManager.unmapTid(0);
126     EXPECT_EQ(ret, false);
127 
128     // unmap reserved TID(0)
129     ret = terminusManager.unmapTid(0xff);
130     EXPECT_EQ(ret, false);
131 }
132 
TEST_F(TerminusManagerTest,discoverMctpTerminusTest)133 TEST_F(TerminusManagerTest, discoverMctpTerminusTest)
134 {
135     const size_t getTidRespLen = PLDM_GET_TID_RESP_BYTES;
136     const size_t setTidRespLen = PLDM_SET_TID_RESP_BYTES;
137     const size_t getPldmTypesRespLen = PLDM_GET_TYPES_RESP_BYTES;
138 
139     // 0.discover a mctp list
140     auto rc = mockTerminusManager.clearQueuedResponses();
141     EXPECT_EQ(rc, PLDM_SUCCESS);
142 
143     std::array<uint8_t, sizeof(pldm_msg_hdr) + getTidRespLen> getTidResp0{
144         0x00, 0x02, 0x02, 0x00, 0x00};
145     rc = mockTerminusManager.enqueueResponse(new (getTidResp0.data()) pldm_msg,
146                                              sizeof(getTidResp0));
147     EXPECT_EQ(rc, PLDM_SUCCESS);
148     std::array<uint8_t, sizeof(pldm_msg_hdr) + setTidRespLen> setTidResp0{
149         0x00, 0x02, 0x01, 0x00};
150     rc = mockTerminusManager.enqueueResponse(new (setTidResp0.data()) pldm_msg,
151                                              sizeof(setTidResp0));
152     EXPECT_EQ(rc, PLDM_SUCCESS);
153     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmTypesRespLen>
154         getPldmTypesResp0{0x00, 0x02, 0x04, 0x00, 0x01, 0x00,
155                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
156     rc = mockTerminusManager.enqueueResponse(
157         new (getPldmTypesResp0.data()) pldm_msg, sizeof(getPldmTypesResp0));
158     EXPECT_EQ(rc, PLDM_SUCCESS);
159 
160     pldm::MctpInfos mctpInfos{};
161     mctpInfos.emplace_back(pldm::MctpInfo(12, "", "", 1, std::nullopt));
162     mockTerminusManager.discoverMctpTerminus(mctpInfos);
163     EXPECT_EQ(1, termini.size());
164 
165     // 1.discover the same mctp list again
166     rc = mockTerminusManager.clearQueuedResponses();
167     EXPECT_EQ(rc, PLDM_SUCCESS);
168 
169     std::array<uint8_t, sizeof(pldm_msg_hdr) + getTidRespLen> getTidResp1{
170         0x00, 0x02, 0x02, 0x00, 0x01};
171     rc = mockTerminusManager.enqueueResponse(new (getTidResp1.data()) pldm_msg,
172                                              sizeof(getTidResp1));
173     EXPECT_EQ(rc, PLDM_SUCCESS);
174     rc = mockTerminusManager.enqueueResponse(new (setTidResp0.data()) pldm_msg,
175                                              sizeof(setTidResp0));
176     EXPECT_EQ(rc, PLDM_SUCCESS);
177     rc = mockTerminusManager.enqueueResponse(
178         new (getPldmTypesResp0.data()) pldm_msg, sizeof(getPldmTypesResp0));
179     EXPECT_EQ(rc, PLDM_SUCCESS);
180 
181     mockTerminusManager.discoverMctpTerminus(mctpInfos);
182     EXPECT_EQ(1, termini.size());
183 
184     // 2.discover an empty mctp list
185     rc = mockTerminusManager.clearQueuedResponses();
186     EXPECT_EQ(rc, PLDM_SUCCESS);
187 
188     mockTerminusManager.removeMctpTerminus(mctpInfos);
189     EXPECT_EQ(0, termini.size());
190 }
191 
TEST_F(TerminusManagerTest,negativeDiscoverMctpTerminusTest)192 TEST_F(TerminusManagerTest, negativeDiscoverMctpTerminusTest)
193 {
194     const size_t getTidRespLen = PLDM_GET_TID_RESP_BYTES;
195     const size_t setTidRespLen = PLDM_SET_TID_RESP_BYTES;
196     const size_t getPldmTypesRespLen = PLDM_GET_TYPES_RESP_BYTES;
197 
198     // 0.terminus returns reserved tid
199     std::array<uint8_t, sizeof(pldm_msg_hdr) + getTidRespLen> getTidResp0{
200         0x00, 0x02, 0x02, 0x00, PLDM_TID_RESERVED};
201     auto rc = mockTerminusManager.enqueueResponse(
202         new (getTidResp0.data()) pldm_msg, sizeof(getTidResp0));
203     EXPECT_EQ(rc, PLDM_SUCCESS);
204 
205     pldm::MctpInfos mctpInfos{};
206     mctpInfos.emplace_back(pldm::MctpInfo(12, "", "", 1, std::nullopt));
207     mockTerminusManager.discoverMctpTerminus(mctpInfos);
208     EXPECT_EQ(0, termini.size());
209 
210     // 1.terminus return cc=pldm_error for set tid
211     std::array<uint8_t, sizeof(pldm_msg_hdr) + getTidRespLen> getTidResp1{
212         0x00, 0x02, 0x02, 0x00, 0x00};
213     std::array<uint8_t, sizeof(pldm_msg_hdr) + setTidRespLen> setTidResp1{
214         0x00, 0x02, 0x01, PLDM_ERROR};
215 
216     rc = mockTerminusManager.enqueueResponse(new (getTidResp1.data()) pldm_msg,
217                                              sizeof(getTidResp1));
218     EXPECT_EQ(rc, PLDM_SUCCESS);
219     rc = mockTerminusManager.enqueueResponse(new (setTidResp1.data()) pldm_msg,
220                                              sizeof(setTidResp1));
221     EXPECT_EQ(rc, PLDM_SUCCESS);
222     mockTerminusManager.removeMctpTerminus(mctpInfos);
223     EXPECT_EQ(0, termini.size());
224 
225     // 2.terminus return cc=unsupported_pldm_cmd for set tid cmd and return
226     // cc=pldm_error for get pldm types cmd
227     std::array<uint8_t, sizeof(pldm_msg_hdr) + getTidRespLen> getTidResp2{
228         0x00, 0x02, 0x02, 0x00, 0x00};
229     std::array<uint8_t, sizeof(pldm_msg_hdr) + setTidRespLen> setTidResp2{
230         0x00, 0x02, 0x01, PLDM_ERROR_UNSUPPORTED_PLDM_CMD};
231     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmTypesRespLen>
232         getPldmTypesResp2{0x00, 0x02, 0x04, PLDM_ERROR, 0x01, 0x00,
233                           0x00, 0x00, 0x00, 0x00,       0x00, 0x00};
234     rc = mockTerminusManager.enqueueResponse(new (getTidResp2.data()) pldm_msg,
235                                              sizeof(getTidResp2));
236     EXPECT_EQ(rc, PLDM_SUCCESS);
237     rc = mockTerminusManager.enqueueResponse(new (setTidResp2.data()) pldm_msg,
238                                              sizeof(setTidResp2));
239     EXPECT_EQ(rc, PLDM_SUCCESS);
240 
241     rc = mockTerminusManager.enqueueResponse(
242         new (getPldmTypesResp2.data()) pldm_msg, sizeof(getPldmTypesResp2));
243     EXPECT_EQ(rc, PLDM_SUCCESS);
244     mockTerminusManager.removeMctpTerminus(mctpInfos);
245     EXPECT_EQ(0, termini.size());
246 }
247 
TEST_F(TerminusManagerTest,doesSupportTypeTest)248 TEST_F(TerminusManagerTest, doesSupportTypeTest)
249 {
250     const size_t getTidRespLen = PLDM_GET_TID_RESP_BYTES;
251     const size_t setTidRespLen = PLDM_SET_TID_RESP_BYTES;
252     const size_t getPldmTypesRespLen = PLDM_GET_TYPES_RESP_BYTES;
253 
254     // 0.discover a mctp list
255     auto rc = mockTerminusManager.clearQueuedResponses();
256     EXPECT_EQ(rc, PLDM_SUCCESS);
257 
258     std::array<uint8_t, sizeof(pldm_msg_hdr) + getTidRespLen> getTidResp0{
259         0x00, 0x02, 0x02, 0x00, 0x00};
260     rc = mockTerminusManager.enqueueResponse(new (getTidResp0.data()) pldm_msg,
261                                              sizeof(getTidResp0));
262     EXPECT_EQ(rc, PLDM_SUCCESS);
263 
264     std::array<uint8_t, sizeof(pldm_msg_hdr) + setTidRespLen> setTidResp0{
265         0x00, 0x02, 0x01, 0x00};
266     rc = mockTerminusManager.enqueueResponse(new (setTidResp0.data()) pldm_msg,
267                                              sizeof(setTidResp0));
268     EXPECT_EQ(rc, PLDM_SUCCESS);
269 
270     uint8_t supportedType1Byte =
271         (1 << (PLDM_BASE % 8)) + (1 << (PLDM_PLATFORM % 8)) +
272         (1 << (PLDM_BIOS % 8)) + (1 << (PLDM_FRU % 8));
273     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmTypesRespLen>
274         getPldmTypesResp0{0x00, 0x02, 0x04, 0x00, supportedType1Byte,
275                           0x00, 0x00, 0x00, 0x00, 0x00,
276                           0x00, 0x00};
277     rc = mockTerminusManager.enqueueResponse(
278         new (getPldmTypesResp0.data()) pldm_msg, sizeof(getPldmTypesResp0));
279     EXPECT_EQ(rc, PLDM_SUCCESS);
280 
281     pldm::MctpInfos mctpInfos{};
282     mctpInfos.emplace_back(pldm::MctpInfo(12, "", "", 1, std::nullopt));
283     mockTerminusManager.discoverMctpTerminus(mctpInfos);
284     EXPECT_EQ(1, termini.size());
285 
286     EXPECT_EQ(true, termini.contains(1));
287     EXPECT_EQ(false, termini.contains(0));
288     EXPECT_EQ(false, termini.contains(2));
289 
290     EXPECT_EQ(true, termini[1]->doesSupportType(PLDM_BASE));
291     EXPECT_EQ(true, termini[1]->doesSupportType(PLDM_PLATFORM));
292     EXPECT_EQ(true, termini[1]->doesSupportType(PLDM_BIOS));
293     EXPECT_EQ(true, termini[1]->doesSupportType(PLDM_FRU));
294     EXPECT_EQ(false, termini[1]->doesSupportType(PLDM_FWUP));
295     EXPECT_EQ(false, termini[1]->doesSupportType(PLDM_OEM));
296 }
297 
TEST_F(TerminusManagerTest,doesSupportCommandTest)298 TEST_F(TerminusManagerTest, doesSupportCommandTest)
299 {
300     const size_t getTidRespLen = PLDM_GET_TID_RESP_BYTES;
301     const size_t setTidRespLen = PLDM_SET_TID_RESP_BYTES;
302     const size_t getPldmTypesRespLen = PLDM_GET_TYPES_RESP_BYTES;
303     const size_t getPldmCommandRespLen = PLDM_GET_COMMANDS_RESP_BYTES;
304     /* PLDM_GET_VERSION_RESP_BYTES does not include 4 bytes check sum */
305     const size_t getPldmVersionRespLen =
306         PLDM_GET_VERSION_RESP_BYTES + sizeof(uint32_t);
307 
308     // 0.discover a mctp list
309     auto rc = mockTerminusManager.clearQueuedResponses();
310     EXPECT_EQ(rc, PLDM_SUCCESS);
311 
312     std::array<uint8_t, sizeof(pldm_msg_hdr) + getTidRespLen> getTidResp0{
313         0x00, 0x02, 0x02, 0x00, 0x00};
314     rc = mockTerminusManager.enqueueResponse(new (getTidResp0.data()) pldm_msg,
315                                              sizeof(getTidResp0));
316     EXPECT_EQ(rc, PLDM_SUCCESS);
317 
318     std::array<uint8_t, sizeof(pldm_msg_hdr) + setTidRespLen> setTidResp0{
319         0x00, 0x02, 0x01, 0x00};
320     rc = mockTerminusManager.enqueueResponse(new (setTidResp0.data()) pldm_msg,
321                                              sizeof(setTidResp0));
322     EXPECT_EQ(rc, PLDM_SUCCESS);
323 
324     uint8_t byte0 = (1 << (PLDM_BASE % 8)) + (1 << (PLDM_PLATFORM % 8)) +
325                     (1 << (PLDM_BIOS % 8)) + (1 << (PLDM_FRU % 8));
326     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmTypesRespLen>
327         getPldmTypesResp0{0x00, 0x02, 0x04, 0x00, byte0, 0x00,
328                           0x00, 0x00, 0x00, 0x00, 0x00,  0x00};
329     rc = mockTerminusManager.enqueueResponse(
330         new (getPldmTypesResp0.data()) pldm_msg, sizeof(getPldmTypesResp0));
331     EXPECT_EQ(rc, PLDM_SUCCESS);
332 
333     /* Response GetPLDMVersion BASE, CC=0 */
334     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmVersionRespLen>
335         getPldmVersionBaseResp0{0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
336                                 0x00, 0x00, 0x05, 0x00, 0xf0, 0xf1,
337                                 0xf1, 0xba, 0xbe, 0x9d, 0x53};
338 
339     rc = mockTerminusManager.enqueueResponse(
340         (pldm_msg*)getPldmVersionBaseResp0.data(),
341         sizeof(getPldmVersionBaseResp0));
342     EXPECT_EQ(rc, PLDM_SUCCESS);
343 
344     /* Response GetPLDMCommand BASE, CC=0,
345      * SetTID/GetTID/GetPLDMTypes/GetPLDMCommands */
346     byte0 = (1 << (PLDM_SET_TID % 8)) + (1 << (PLDM_GET_TID % 8)) +
347             (1 << (PLDM_GET_PLDM_TYPES % 8)) +
348             (1 << (PLDM_GET_PLDM_COMMANDS % 8));
349     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmCommandRespLen>
350         getPldmCommandBaseResp0{
351             0x00, 0x02, 0x05, 0x00, byte0, 0x00, 0x00, 0x00, 0x00,
352             0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
353             0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
354             0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00};
355     rc = mockTerminusManager.enqueueResponse(
356         new (getPldmCommandBaseResp0.data()) pldm_msg,
357         sizeof(getPldmCommandBaseResp0));
358     EXPECT_EQ(rc, PLDM_SUCCESS);
359 
360     /* Response GetPLDMVersion PLATFORM, CC=0 */
361     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmVersionRespLen>
362         getPldmVersionPlatformResp0{0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
363                                     0x00, 0x00, 0x05, 0x00, 0xf1, 0xf2,
364                                     0xf1, 0x4e, 0x87, 0x72, 0x79};
365 
366     rc = mockTerminusManager.enqueueResponse(
367         (pldm_msg*)getPldmVersionPlatformResp0.data(),
368         sizeof(getPldmVersionPlatformResp0));
369     EXPECT_EQ(rc, PLDM_SUCCESS);
370     /* Response GetPLDMCommand PLATFORM, CC=0,
371      * SetEventReceiver/PlatformEventMessage/GetSensorReading/SetNumericEffecterValue/GetNumericEffecterValue/GetPDR
372      */
373     /* byte0 command from 0x00 to 0x07 */
374     byte0 = (1 << (PLDM_SET_EVENT_RECEIVER % 8)); // byte0 = 0x10
375     /* byte1 command from 0x08 to 0xf */
376     uint8_t byte1 = (1 << (PLDM_PLATFORM_EVENT_MESSAGE % 8)) +
377                     (1 << (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE % 8)) +
378                     (1 << (PLDM_EVENT_MESSAGE_SUPPORTED % 8)) +
379                     (1 << (PLDM_EVENT_MESSAGE_BUFFER_SIZE % 8)); // byte1 = 0x3c
380     /* byte2 command from 0x10 to 0x17 */
381     uint8_t byte2 = (1 << (PLDM_GET_SENSOR_READING % 8)); // byte2 = 0x02
382     /* byte3 command from 0x18 to 0x1f */
383     /* byte4 command from 0x20 to 0x27 */
384     uint8_t byte4 = (1 << (PLDM_GET_STATE_SENSOR_READINGS % 8)); // byte4 = 0x02
385     /* byte5 command from 0x28 to 0x2f */
386     /* byte6 command from 0x30 to 0x37 */
387     uint8_t byte6 =
388         (1 << (PLDM_SET_NUMERIC_EFFECTER_VALUE % 8)) +
389         (1 << (PLDM_GET_NUMERIC_EFFECTER_VALUE % 8)); // byte6 = 0x06
390     /* byte7 command from 0x38 to 0x3f */
391     uint8_t byte7 = (0 << (PLDM_SET_STATE_EFFECTER_STATES % 8)); // byte7 = 0
392     /* byte8 command from 0x40 to 0x47 */
393     /* byte9 command from 0x48 to 0x4f */
394     /* byte10 command from 0x50 to 0x57 */
395     uint8_t byte10 = (1 << (PLDM_GET_PDR_REPOSITORY_INFO % 8)) +
396                      (1 << (PLDM_GET_PDR % 8)); // byte10 = 0x03
397     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmCommandRespLen>
398         getPldmCommandPlatResp0{
399             0x00, 0x02,  0x05,  0x00, byte0, byte1,  byte2, 0x00, byte4,
400             0x00, byte6, byte7, 0x00, 0x00,  byte10, 0x00,  0x00, 0x00,
401             0x00, 0x00,  0x00,  0x00, 0x00,  0x00,   0x00,  0x00, 0x00,
402             0x00, 0x00,  0x00,  0x00, 0x00,  0x00,   0x00,  0x00, 0x00};
403     rc = mockTerminusManager.enqueueResponse(
404         new (getPldmCommandPlatResp0.data()) pldm_msg,
405         sizeof(getPldmCommandPlatResp0));
406     EXPECT_EQ(rc, PLDM_SUCCESS);
407 
408     /* Response GetPLDMVersion BIOS, CC=0 */
409     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmVersionRespLen>
410         getPldmVersionBiosResp0{0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
411                                 0x00, 0x00, 0x05, 0x00, 0xf0, 0xf0,
412                                 0xf1, 0xfb, 0x8f, 0x86, 0x4a};
413 
414     rc = mockTerminusManager.enqueueResponse(
415         (pldm_msg*)getPldmVersionBiosResp0.data(),
416         sizeof(getPldmVersionBiosResp0));
417     EXPECT_EQ(rc, PLDM_SUCCESS);
418     /* Response GetPLDMCommand BIOS, CC=0, GetDateTime/SetDateTime */
419     /* byte0 command from 1 to 7 */
420     byte0 = (0 << (PLDM_GET_BIOS_TABLE % 8)) +
421             (0 << (PLDM_SET_BIOS_TABLE % 8)) +
422             (0 << (PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE % 8));
423     /* byte1 command from 8 to 15 */
424     byte1 = (0 << (PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE % 8)) +
425             (1 << (PLDM_GET_DATE_TIME % 8)) + (1 << (PLDM_SET_DATE_TIME % 8));
426     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmCommandRespLen>
427         getPldmCommandBiosResp0{
428             0x00, 0x02, 0x05, 0x00, byte0, byte1, 0x00, 0x00, 0x00,
429             0x00, 0x00, 0x00, 0x00, 0x00,  0x00,  0x00, 0x00, 0x00,
430             0x00, 0x00, 0x00, 0x00, 0x00,  0x00,  0x00, 0x00, 0x00,
431             0x00, 0x00, 0x00, 0x00, 0x00,  0x00,  0x00, 0x00};
432     rc = mockTerminusManager.enqueueResponse(
433         new (getPldmCommandBiosResp0.data()) pldm_msg,
434         sizeof(getPldmCommandBiosResp0));
435     EXPECT_EQ(rc, PLDM_SUCCESS);
436 
437     /* Response GetPLDMVersion FRU, CC=0 */
438     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmVersionRespLen>
439         getPldmVersionFruResp0{0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
440                                0x00, 0x00, 0x05, 0x00, 0xf1, 0xf0,
441                                0xf1, 0xcc, 0xe5, 0x44, 0x4b};
442 
443     rc = mockTerminusManager.enqueueResponse(
444         (pldm_msg*)getPldmVersionFruResp0.data(),
445         sizeof(getPldmVersionFruResp0));
446     EXPECT_EQ(rc, PLDM_SUCCESS);
447     /* Response GetPLDMCommand FRU, CC=0,
448      * GetFRURecordTableMetadata/GetFRURecordTable */
449     /* byte0 command from 1 to 7 */
450     byte0 = (1 << (PLDM_GET_FRU_RECORD_TABLE_METADATA % 8)) +
451             (1 << (PLDM_GET_FRU_RECORD_TABLE % 8)) +
452             (0 << (PLDM_SET_FRU_RECORD_TABLE % 8)) +
453             (0 << (PLDM_GET_FRU_RECORD_BY_OPTION % 8));
454     /* byte0 command from 8 to 15 */
455     byte1 = 0;
456     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPldmCommandRespLen>
457         getPldmCommandFruResp0{
458             0x00, 0x02, 0x05, 0x00, byte0, 0x00, 0x00, 0x00, 0x00,
459             0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
460             0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
461             0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00};
462     rc = mockTerminusManager.enqueueResponse(
463         new (getPldmCommandFruResp0.data()) pldm_msg,
464         sizeof(getPldmCommandFruResp0));
465     EXPECT_EQ(rc, PLDM_SUCCESS);
466 
467     pldm::MctpInfos mctpInfos{};
468     mctpInfos.emplace_back(pldm::MctpInfo(12, "", "", 1, std::nullopt));
469     mockTerminusManager.discoverMctpTerminus(mctpInfos);
470     EXPECT_EQ(1, termini.size());
471     EXPECT_EQ(true, termini.contains(1));
472     EXPECT_EQ(false, termini.contains(0));
473     EXPECT_EQ(false, termini.contains(2));
474 
475     EXPECT_EQ(true, termini[1]->doesSupportType(PLDM_BASE));
476     EXPECT_EQ(true, termini[1]->doesSupportType(PLDM_PLATFORM));
477     EXPECT_EQ(true, termini[1]->doesSupportType(PLDM_BIOS));
478     EXPECT_EQ(true, termini[1]->doesSupportType(PLDM_FRU));
479     /* Check PLDM Base commands */
480     EXPECT_EQ(true, termini[1]->doesSupportCommand(PLDM_BASE, PLDM_SET_TID));
481     EXPECT_EQ(true, termini[1]->doesSupportCommand(PLDM_BASE, PLDM_GET_TID));
482     EXPECT_EQ(false,
483               termini[1]->doesSupportCommand(PLDM_BASE, PLDM_GET_PLDM_VERSION));
484     EXPECT_EQ(true,
485               termini[1]->doesSupportCommand(PLDM_BASE, PLDM_GET_PLDM_TYPES));
486 
487     EXPECT_EQ(true, termini[1]->doesSupportCommand(PLDM_BASE,
488                                                    PLDM_GET_PLDM_COMMANDS));
489     EXPECT_EQ(false, termini[1]->doesSupportCommand(PLDM_BASE,
490                                                     PLDM_MULTIPART_RECEIVE));
491 
492     /* Check PLDM Platform commands */
493     EXPECT_EQ(true, termini[1]->doesSupportCommand(PLDM_PLATFORM,
494                                                    PLDM_SET_EVENT_RECEIVER));
495     EXPECT_EQ(true, termini[1]->doesSupportCommand(
496                         PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE));
497     EXPECT_EQ(true, termini[1]->doesSupportCommand(
498                         PLDM_PLATFORM, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE));
499     EXPECT_EQ(true, termini[1]->doesSupportCommand(
500                         PLDM_PLATFORM, PLDM_EVENT_MESSAGE_SUPPORTED));
501     EXPECT_EQ(true, termini[1]->doesSupportCommand(
502                         PLDM_PLATFORM, PLDM_EVENT_MESSAGE_BUFFER_SIZE));
503     EXPECT_EQ(true, termini[1]->doesSupportCommand(PLDM_PLATFORM,
504                                                    PLDM_GET_SENSOR_READING));
505     EXPECT_EQ(true, termini[1]->doesSupportCommand(
506                         PLDM_PLATFORM, PLDM_GET_STATE_SENSOR_READINGS));
507     EXPECT_EQ(true, termini[1]->doesSupportCommand(
508                         PLDM_PLATFORM, PLDM_SET_NUMERIC_EFFECTER_VALUE));
509     EXPECT_EQ(true, termini[1]->doesSupportCommand(
510                         PLDM_PLATFORM, PLDM_GET_NUMERIC_EFFECTER_VALUE));
511     EXPECT_EQ(false, termini[1]->doesSupportCommand(
512                          PLDM_PLATFORM, PLDM_SET_STATE_EFFECTER_STATES));
513     EXPECT_EQ(true, termini[1]->doesSupportCommand(
514                         PLDM_PLATFORM, PLDM_GET_PDR_REPOSITORY_INFO));
515     EXPECT_EQ(true,
516               termini[1]->doesSupportCommand(PLDM_PLATFORM, PLDM_GET_PDR));
517 
518     /* Check PLDM Bios commands */
519     EXPECT_EQ(false,
520               termini[1]->doesSupportCommand(PLDM_BIOS, PLDM_GET_BIOS_TABLE));
521     EXPECT_EQ(false,
522               termini[1]->doesSupportCommand(PLDM_BIOS, PLDM_SET_BIOS_TABLE));
523     EXPECT_EQ(false, termini[1]->doesSupportCommand(
524                          PLDM_BIOS, PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE));
525     EXPECT_EQ(false,
526               termini[1]->doesSupportCommand(
527                   PLDM_BIOS, PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE));
528     EXPECT_EQ(true,
529               termini[1]->doesSupportCommand(PLDM_BIOS, PLDM_GET_DATE_TIME));
530     EXPECT_EQ(true,
531               termini[1]->doesSupportCommand(PLDM_BIOS, PLDM_SET_DATE_TIME));
532 
533     /* Check PLDM Fru commands */
534     EXPECT_EQ(true, termini[1]->doesSupportCommand(
535                         PLDM_FRU, PLDM_GET_FRU_RECORD_TABLE_METADATA));
536     EXPECT_EQ(true, termini[1]->doesSupportCommand(PLDM_FRU,
537                                                    PLDM_GET_FRU_RECORD_TABLE));
538     EXPECT_EQ(false, termini[1]->doesSupportCommand(PLDM_FRU,
539                                                     PLDM_SET_FRU_RECORD_TABLE));
540     EXPECT_EQ(false, termini[1]->doesSupportCommand(
541                          PLDM_FRU, PLDM_GET_FRU_RECORD_BY_OPTION));
542 }
543 
TEST_F(TerminusManagerTest,getActiveEidByNameTest)544 TEST_F(TerminusManagerTest, getActiveEidByNameTest)
545 {
546     // Add terminus
547     pldm::MctpInfo mctpInfo(10, "", "", 1, std::nullopt);
548     auto mappedTid = mockTerminusManager.mapTid(mctpInfo);
549     auto tid = mappedTid.value();
550     termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
551         tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM, event);
552     auto terminus = termini[tid];
553 
554     auto mappedTid1 = terminusManager.mapTid(mctpInfo);
555     EXPECT_EQ(mappedTid1, mappedTid);
556 
557     auto mctpInfo1 = terminusManager.toMctpInfo(tid);
558     EXPECT_EQ(mctpInfo, mctpInfo1.value());
559 
560     /* Set supported command by terminus */
561     auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
562     std::vector<uint8_t> pldmCmds(size);
563     uint8_t type = PLDM_PLATFORM;
564     uint8_t cmd = PLDM_GET_PDR;
565     auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
566     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
567     cmd = PLDM_GET_PDR_REPOSITORY_INFO;
568     idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
569     pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
570     termini[tid]->setSupportedCommands(pldmCmds);
571 
572     // queue getPDRRepositoryInfo response
573     const size_t getPDRRepositoryInfoLen =
574         PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
575     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen>
576         getPDRRepositoryInfoResp{
577             0x0, 0x02, 0x50, PLDM_SUCCESS,
578             0x0,                                     // repositoryState
579             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, 0x0,
580             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, // updateTime
581             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, 0x0,
582             0x0, 0x0,  0x0,  0x0,          0x0, 0x0, // OEMUpdateTime
583             2,   0x0,  0x0,  0x0,                    // recordCount
584             0x0, 0x1,  0x0,  0x0,                    // repositorySize
585             59,  0x0,  0x0,  0x0,                    // largestRecordSize
586             0x0 // dataTransferHandleTimeout
587         };
588     auto rc = mockTerminusManager.enqueueResponse(
589         reinterpret_cast<pldm_msg*>(getPDRRepositoryInfoResp.data()),
590         sizeof(getPDRRepositoryInfoResp));
591     EXPECT_EQ(rc, PLDM_SUCCESS);
592 
593     // queue getPDR responses
594     const size_t getPdrRespLen = 81;
595     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{
596         0x0, 0x02, 0x51, PLDM_SUCCESS, 0x1, 0x0, 0x0, 0x0, // nextRecordHandle
597         0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
598         0x5,                // transferFlag
599         69, 0x0,            // responseCount
600         // numeric Sensor PDR
601         0x0, 0x0, 0x0,
602         0x0,                     // record handle
603         0x1,                     // PDRHeaderVersion
604         PLDM_NUMERIC_SENSOR_PDR, // PDRType
605         0x0,
606         0x0,                     // recordChangeNumber
607         PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
608             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
609             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
610         0,                             // dataLength
611         0,
612         0,                             // PLDMTerminusHandle
613         0x1,
614         0x0,                           // sensorID=1
615         120,
616         0,                             // entityType=Power Supply(120)
617         1,
618         0,                             // entityInstanceNumber
619         0x1,
620         0x0,                           // containerID=1
621         PLDM_NO_INIT,                  // sensorInit
622         false,                         // sensorAuxiliaryNamesPDR
623         PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
624         1,                             // unitModifier = 1
625         0,                             // rateUnit
626         0,                             // baseOEMUnitHandle
627         0,                             // auxUnit
628         0,                             // auxUnitModifier
629         0,                             // auxRateUnit
630         0,                             // rel
631         0,                             // auxOEMUnitHandle
632         true,                          // isLinear
633         PLDM_SENSOR_DATA_SIZE_UINT8,   // sensorDataSize
634         0, 0, 0xc0,
635         0x3f,                          // resolution=1.5
636         0, 0, 0x80,
637         0x3f,                          // offset=1.0
638         0,
639         0,                             // accuracy
640         0,                             // plusTolerance
641         0,                             // minusTolerance
642         2,                             // hysteresis
643         0,                             // supportedThresholds
644         0,                             // thresholdAndHysteresisVolatility
645         0, 0, 0x80,
646         0x3f,                          // stateTransistionInterval=1.0
647         0, 0, 0x80,
648         0x3f,                          // updateInverval=1.0
649         255,                           // maxReadable
650         0,                             // minReadable
651         PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
652         0,                             // rangeFieldsupport
653         0,                             // nominalValue
654         0,                             // normalMax
655         0,                             // normalMin
656         0,                             // warningHigh
657         0,                             // warningLow
658         0,                             // criticalHigh
659         0,                             // criticalLow
660         0,                             // fatalHigh
661         0                              // fatalLow
662     };
663     rc = mockTerminusManager.enqueueResponse(
664         reinterpret_cast<pldm_msg*>(getPdrResp.data()), sizeof(getPdrResp));
665     EXPECT_EQ(rc, PLDM_SUCCESS);
666 
667     const size_t getPdrAuxNameRespLen = 39;
668     std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrAuxNameRespLen>
669         getPdrAuxNameResp{
670             0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0,
671             0x0,                // nextRecordHandle
672             0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
673             0x5,                // transferFlag
674             0x1b, 0x0,          // responseCount
675             // Common PDR Header
676             0x1, 0x0, 0x0,
677             0x0,                             // record handle
678             0x1,                             // PDRHeaderVersion
679             PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType
680             0x1,
681             0x0,                             // recordChangeNumber
682             0x11,
683             0,                               // dataLength
684             /* Entity Auxiliary Names PDR Data*/
685             3,
686             0x80, // entityType system software
687             0x1,
688             0x0,  // Entity instance number =1
689             0,
690             0,    // Overall system
691             0,    // shared Name Count one name only
692             01,   // nameStringCount
693             0x65, 0x6e, 0x00,
694             0x00, // Language Tag "en"
695             0x53, 0x00, 0x30, 0x00,
696             0x00  // Entity Name "S0"
697         };
698     rc = mockTerminusManager.enqueueResponse(
699         reinterpret_cast<pldm_msg*>(getPdrAuxNameResp.data()),
700         sizeof(getPdrAuxNameResp));
701     EXPECT_EQ(rc, PLDM_SUCCESS);
702 
703     mockTerminusManager.updateMctpEndpointAvailability(mctpInfo, true);
704     terminusManager.updateMctpEndpointAvailability(mctpInfo, true);
705 
706     stdexec::sync_wait(platformManager.initTerminus());
707     EXPECT_EQ(true, terminus->initialized);
708     EXPECT_EQ(2, terminus->pdrs.size());
709     EXPECT_EQ(1, termini.size());
710     EXPECT_EQ("S0", terminus->getTerminusName().value());
711     EXPECT_EQ(10, terminusManager.getActiveEidByName("S0").value());
712     EXPECT_EQ(false, terminusManager.getActiveEidByName("S1").has_value());
713 }
714