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: 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 53 TEST_F(TerminusManagerTest, mapTidTest) 54 { 55 pldm::MctpInfo mctpInfo1(8, "", "", 0); 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 73 TEST_F(TerminusManagerTest, negativeMapTidTest) 74 { 75 // map null EID(0) to TID 76 pldm::MctpInfo m0(0, "", "", 0); 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); 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); 87 pldm::MctpInfo m3(10, "", "", 1); 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); 95 pldm::MctpInfo m5(12, "", "", 2); 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); 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); 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 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)); 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 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)); 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 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)); 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 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)); 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 544 TEST_F(TerminusManagerTest, getActiveEidByNameTest) 545 { 546 // Add terminus 547 pldm::MctpInfo mctpInfo(10, "", "", 1); 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