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