blob: 9489d47dc4fcdf119d6420d5913f95127eaade4d [file] [log] [blame]
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06001#include "libpldm/base.h"
2
3#include "base.hpp"
4
5#include <array>
Sampa Misra432e1872019-02-13 03:49:43 -06006#include <cstring>
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06007#include <map>
8#include <stdexcept>
9#include <vector>
10
11namespace pldm
12{
13namespace responder
14{
15
16using Cmd = std::vector<uint8_t>;
17
18static const std::map<Type, Cmd> capabilities{
19 {PLDM_BASE, {PLDM_GET_PLDM_TYPES, PLDM_GET_PLDM_COMMANDS}}};
20
Sampa Misra432e1872019-02-13 03:49:43 -060021static const std::map<Type, pldm_version> versions{
22 {PLDM_BASE, {0xF1, 0xF0, 0xF0, 0x00}},
23};
24
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060025void getPLDMTypes(const pldm_msg_payload* request, pldm_msg* response)
26{
27 // DSP0240 has this as a bitfield8[N], where N = 0 to 7
28 std::array<uint8_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] |= 1 << bit;
35 }
36
37 encode_get_types_resp(0, PLDM_SUCCESS, types.data(), response);
38}
39
40void getPLDMCommands(const pldm_msg_payload* request, pldm_msg* response)
41{
42 pldm_version version{};
43 Type type;
44
45 if (request->payload_length != (sizeof(version) + sizeof(type)))
46 {
47 encode_get_commands_resp(0, PLDM_ERROR_INVALID_LENGTH, nullptr,
48 response);
49 return;
50 }
51
52 decode_get_commands_req(request, &type, &version);
53
54 // DSP0240 has this as a bitfield8[N], where N = 0 to 31
55 std::array<uint8_t, 32> cmds{};
56 if (capabilities.find(type) == capabilities.end())
57 {
58 encode_get_commands_resp(0, PLDM_ERROR_INVALID_PLDM_TYPE, nullptr,
59 response);
60 return;
61 }
62
63 for (const auto& cmd : capabilities.at(type))
64 {
65 auto index = cmd / 8;
66 // <Type Number> = <Array Index> * 8 + <bit position>
67 auto bit = cmd - (index * 8);
68 cmds[index] |= 1 << bit;
69 }
70
71 encode_get_commands_resp(0, PLDM_SUCCESS, cmds.data(), response);
72}
73
Sampa Misra432e1872019-02-13 03:49:43 -060074void getPLDMVersion(const pldm_msg_payload* request, pldm_msg* response)
75{
76 uint32_t transferHandle;
77 Type type;
78 uint8_t transferFlag;
79
80 if (request->payload_length !=
81 (sizeof(transferHandle) + sizeof(type) + sizeof(transferFlag)))
82 {
83 encode_get_version_resp(0, PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
84 response);
85 return;
86 }
87
88 decode_get_version_req(request, &transferHandle, &transferFlag, &type);
89
90 pldm_version version{};
91 auto search = versions.find(type);
92
93 if (search == versions.end())
94 {
95 encode_get_version_resp(0, PLDM_ERROR_INVALID_PLDM_TYPE, 0, 0, nullptr,
96 0, response);
97 return;
98 }
99
100 memcpy(&version, &(search->second), sizeof(version));
101 encode_get_version_resp(0, PLDM_SUCCESS, 0, PLDM_START_AND_END, &version,
102 sizeof(pldm_version), response);
103}
104
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600105} // namespace responder
106} // namespace pldm