blob: da6605d9cd45944484469eba66bf841e4579a777 [file] [log] [blame]
George Liud6649362019-11-27 19:06:51 +08001#include "pldm_cmd_helper.hpp"
2
3#include <string>
4#include <vector>
5
6namespace pldmtool
7{
8
9namespace platform
10{
11
12namespace
13{
14
15using namespace pldmtool::helper;
16std::vector<std::unique_ptr<CommandInterface>> commands;
17
18} // namespace
19
20class GetPDR : public CommandInterface
21{
22 public:
23 ~GetPDR() = default;
24 GetPDR() = delete;
25 GetPDR(const GetPDR&) = delete;
26 GetPDR(GetPDR&&) = default;
27 GetPDR& operator=(const GetPDR&) = delete;
28 GetPDR& operator=(GetPDR&&) = default;
29
30 using CommandInterface::CommandInterface;
31
32 // The maximum number of record bytes requested to be returned in the
33 // response to this instance of the GetPDR command.
34 static constexpr uint16_t requestCount = 128;
35
36 explicit GetPDR(const char* type, const char* name, CLI::App* app) :
37 CommandInterface(type, name, app)
38 {
39 app->add_option(
40 "-d,--data", recordHandle,
41 "retrieve individual PDRs from a PDR Repository\n"
42 "eg: The recordHandle value for the PDR to be retrieved and 0 "
43 "means get first PDR in the repository.")
44 ->required();
45 }
46
47 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
48 {
49 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
50 PLDM_GET_PDR_REQ_BYTES);
51 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
52
53 auto rc = encode_get_pdr_req(PLDM_LOCAL_INSTANCE_ID, recordHandle, 0,
54 PLDM_GET_FIRSTPART, requestCount, 0,
55 request, PLDM_GET_PDR_REQ_BYTES);
56 return {rc, requestMsg};
57 }
58
59 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
60 {
61 uint8_t completionCode = 0;
62 uint8_t recordData[255] = {0};
63 uint32_t nextRecordHndl = 0;
64 uint32_t nextDataTransferHndl = 0;
65 uint8_t transferFlag = 0;
66 uint16_t respCnt = 0;
67 uint8_t transferCRC = 0;
68
69 auto rc = decode_get_pdr_resp(
70 responsePtr, payloadLength, &completionCode, &nextRecordHndl,
71 &nextDataTransferHndl, &transferFlag, &respCnt, recordData,
72 sizeof(recordData), &transferCRC);
73
74 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
75 {
76 std::cerr << "Response Message Error: "
77 << "rc=" << rc << ",cc=" << (int)completionCode
78 << std::endl;
79 return;
80 }
81
82 printPDRMsg(nextRecordHndl, respCnt, recordData, sizeof(recordData));
83 }
84
85 private:
86 void printPDR11(uint8_t* data, size_t len)
87 {
88 if (data == NULL || len == 0)
89 {
90 return;
91 }
92
93 struct pldm_state_effecter_pdr* pdr =
94 (struct pldm_state_effecter_pdr*)data;
95 std::cout << "recordHandle: " << pdr->hdr.record_handle << std::endl;
96 std::cout << "PDRHeaderVersion: " << unsigned(pdr->hdr.version)
97 << std::endl;
98 std::cout << "PDRType: " << unsigned(pdr->hdr.type) << std::endl;
99 std::cout << "recordChangeNumber: " << pdr->hdr.record_change_num
100 << std::endl;
101 std::cout << "dataLength: " << pdr->hdr.length << std::endl;
102 std::cout << "PLDMTerminusHandle: " << pdr->terminus_handle
103 << std::endl;
104 std::cout << "effecterID: " << pdr->effecter_id << std::endl;
105 std::cout << "entityType: " << pdr->entity_type << std::endl;
106 std::cout << "entityInstanceNumber: " << pdr->entity_instance
107 << std::endl;
108 std::cout << "containerID: " << pdr->container_id << std::endl;
109 std::cout << "effecterSemanticID: " << pdr->effecter_semantic_id
110 << std::endl;
111 std::cout << "effecterInit: " << unsigned(pdr->effecter_init)
112 << std::endl;
113 std::cout << "effecterDescriptionPDR: "
114 << (unsigned(pdr->has_description_pdr) ? "true" : "false")
115 << std::endl;
116 std::cout << "compositeEffecterCount: "
117 << unsigned(pdr->composite_effecter_count) << std::endl;
118
119 for (size_t i = 0; i < pdr->composite_effecter_count; ++i)
120 {
121 struct state_effecter_possible_states* state =
122 (struct state_effecter_possible_states*)pdr->possible_states +
123 i * sizeof(state_effecter_possible_states);
124 std::cout << "stateSetID: " << state->state_set_id << std::endl;
125 std::cout << "possibleStatesSize: "
126 << unsigned(state->possible_states_size) << std::endl;
127 bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(state->states);
128 std::cout << "possibleStates: " << unsigned(bf->byte) << std::endl;
129 }
130 }
131
132 void printPDRMsg(const uint32_t nextRecordHndl, const uint16_t respCnt,
133 uint8_t* data, size_t len)
134 {
135 if (data == NULL || len == 0)
136 {
137 return;
138 }
139
140 std::cout << "Parsed Response Msg: " << std::endl;
141 std::cout << "nextRecordHandle: " << nextRecordHndl << std::endl;
142 std::cout << "responseCount: " << respCnt << std::endl;
143
144 struct pldm_pdr_hdr* pdr = (struct pldm_pdr_hdr*)data;
145 switch (pdr->type)
146 {
147 case PLDM_STATE_EFFECTER_PDR:
148 printPDR11(data, len);
149 break;
150 default:
151 break;
152 }
153 }
154
155 private:
156 uint32_t recordHandle;
157};
158
159class SetStateEffecter : public CommandInterface
160{
161 public:
162 ~SetStateEffecter() = default;
163 SetStateEffecter() = delete;
164 SetStateEffecter(const SetStateEffecter&) = delete;
165 SetStateEffecter(SetStateEffecter&&) = default;
166 SetStateEffecter& operator=(const SetStateEffecter&) = delete;
167 SetStateEffecter& operator=(SetStateEffecter&&) = default;
168
169 // effecterID(1) + compositeEffecterCount(value: 0x01 to 0x08) *
170 // stateField(2)
171 static constexpr auto maxEffecterDataSize = 17;
172 explicit SetStateEffecter(const char* type, const char* name,
173 CLI::App* app) :
174 CommandInterface(type, name, app)
175 {
176 app->add_option(
177 "-d,--data", effecterData,
178 "set effecter state data, the noChange value is 0 and the "
179 "requestSet value is 1 and access up to eight sets of state "
180 "effector information. \n"
181 "eg1: effecterID, requestSet0, effecterState0... \n"
182 "eg2: effecterID, noChange0, requestSet1, effecterState1...")
183 ->required()
184 ->expected(-1);
185 }
186
187 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
188 {
189 std::vector<uint8_t> requestMsg(
190 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES);
191 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
192
193 if (effecterData.size() > maxEffecterDataSize)
194 {
195 std::cerr << "Request Message Error: effecterData size "
196 << effecterData.size() << std::endl;
197 auto rc = PLDM_ERROR_INVALID_DATA;
198 return {rc, requestMsg};
199 }
200
201 uint16_t effecterId = 0;
202 std::vector<set_effecter_state_field> stateField = {};
203 if (!decodeEffecterData(effecterData, effecterId, stateField))
204 {
205 auto rc = PLDM_ERROR_INVALID_DATA;
206 return {rc, requestMsg};
207 }
208
209 auto rc = encode_set_state_effecter_states_req(
210 PLDM_LOCAL_INSTANCE_ID, effecterId, stateField.size(),
211 stateField.data(), request);
212 return {rc, requestMsg};
213 }
214
215 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
216 {
217 uint8_t completionCode = 0;
218 auto rc = decode_set_state_effecter_states_resp(
219 responsePtr, payloadLength, &completionCode);
220
221 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
222 {
223 std::cerr << "Response Message Error: "
224 << "rc=" << rc << ",cc=" << (int)completionCode
225 << std::endl;
226 return;
227 }
228
229 std::cout << "SetStateEffecterStates: SUCCESS" << std::endl;
230 }
231
232 private:
233 std::vector<uint8_t> effecterData;
234};
235
236void registerCommand(CLI::App& app)
237{
238 auto platform = app.add_subcommand("platform", "platform type command");
239 platform->require_subcommand(1);
240
241 auto getPDR =
242 platform->add_subcommand("GetPDR", "get platform descriptor records");
243 commands.push_back(std::make_unique<GetPDR>("platform", "getPDR", getPDR));
244
245 auto setStateEffecterStates = platform->add_subcommand(
246 "SetStateEffecterStates", "set effecter states");
247 commands.push_back(std::make_unique<SetStateEffecter>(
248 "platform", "setStateEffecterStates", setStateEffecterStates));
249}
250
251} // namespace platform
252} // namespace pldmtool