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