1 #include "libpldm/base.h" 2 3 #include "base.hpp" 4 5 #include <array> 6 #include <cstring> 7 #include <map> 8 #include <stdexcept> 9 #include <vector> 10 11 namespace pldm 12 { 13 namespace responder 14 { 15 16 using Cmd = std::vector<uint8_t>; 17 18 static const std::map<Type, Cmd> capabilities{ 19 {PLDM_BASE, {PLDM_GET_PLDM_TYPES, PLDM_GET_PLDM_COMMANDS}}}; 20 21 static const std::map<Type, ver32_t> versions{ 22 {PLDM_BASE, {0xF1, 0xF0, 0xF0, 0x00}}, 23 }; 24 25 Response getPLDMTypes(const pldm_msg* request, size_t payloadLength) 26 { 27 // DSP0240 has this as a bitfield8[N], where N = 0 to 7 28 std::array<bitfield8_t, 8> types{}; 29 for (const auto& type : capabilities) 30 { 31 auto index = type.first / 8; 32 // <Type Number> = <Array Index> * 8 + <bit position> 33 auto bit = type.first - (index * 8); 34 types[index].byte |= 1 << bit; 35 } 36 37 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES, 0); 38 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 39 encode_get_types_resp(0, PLDM_SUCCESS, types.data(), responsePtr); 40 41 return response; 42 } 43 44 Response getPLDMCommands(const pldm_msg* request, size_t payloadLength) 45 { 46 ver32_t version{}; 47 Type type; 48 49 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES, 0); 50 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 51 52 auto rc = decode_get_commands_req(request->payload, payloadLength, &type, 53 &version); 54 55 if (rc != PLDM_SUCCESS) 56 { 57 encode_get_commands_resp(0, rc, nullptr, responsePtr); 58 return response; 59 } 60 61 // DSP0240 has this as a bitfield8[N], where N = 0 to 31 62 std::array<bitfield8_t, 32> cmds{}; 63 if (capabilities.find(type) == capabilities.end()) 64 { 65 encode_get_commands_resp(0, PLDM_ERROR_INVALID_PLDM_TYPE, nullptr, 66 responsePtr); 67 return response; 68 } 69 70 for (const auto& cmd : capabilities.at(type)) 71 { 72 auto index = cmd / 8; 73 // <Type Number> = <Array Index> * 8 + <bit position> 74 auto bit = cmd - (index * 8); 75 cmds[index].byte |= 1 << bit; 76 } 77 78 encode_get_commands_resp(0, PLDM_SUCCESS, cmds.data(), responsePtr); 79 80 return response; 81 } 82 83 Response getPLDMVersion(const pldm_msg* request, size_t payloadLength) 84 { 85 uint32_t transferHandle; 86 Type type; 87 uint8_t transferFlag; 88 89 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES, 0); 90 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 91 92 uint8_t rc = decode_get_version_req(request->payload, payloadLength, 93 &transferHandle, &transferFlag, &type); 94 95 if (rc != PLDM_SUCCESS) 96 { 97 encode_get_version_resp(0, rc, 0, 0, nullptr, 4, responsePtr); 98 return response; 99 } 100 101 ver32_t version{}; 102 auto search = versions.find(type); 103 104 if (search == versions.end()) 105 { 106 encode_get_version_resp(0, PLDM_ERROR_INVALID_PLDM_TYPE, 0, 0, nullptr, 107 4, responsePtr); 108 return response; 109 } 110 111 memcpy(&version, &(search->second), sizeof(version)); 112 encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END, &version, 113 sizeof(pldm_version), responsePtr); 114 115 return response; 116 } 117 118 } // namespace responder 119 } // namespace pldm 120