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