blob: 1c6b3fdef298e6c1e242c80f66223d3ef4844d83 [file] [log] [blame]
Sampa Misraaea5dde2020-08-31 08:33:47 -05001#include "oem_ibm_handler.hpp"
2
3#include "libpldm/entity.h"
Varsha Kaverappabb585b22020-09-10 06:15:42 -05004#include "libpldm/requester/pldm.h"
Sampa Misraaea5dde2020-08-31 08:33:47 -05005
Sagar Srinivascfdbca72020-09-22 10:03:35 -05006#include "file_io_type_lid.hpp"
7#include "libpldmresponder/file_io.hpp"
Sagar Srinivas78a225a2020-08-27 00:52:20 -05008#include "libpldmresponder/pdr_utils.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -05009namespace pldm
10{
Sampa Misraaea5dde2020-08-31 08:33:47 -050011namespace responder
12{
Sampa Misraaea5dde2020-08-31 08:33:47 -050013namespace oem_ibm_platform
14{
15
16int pldm::responder::oem_ibm_platform::Handler::
17 getOemStateSensorReadingsHandler(
18 EntityType entityType, EntityInstance entityInstance,
19 StateSetId stateSetId, CompositeCount compSensorCnt,
20 std::vector<get_sensor_state_field>& stateField)
21{
22 int rc = PLDM_SUCCESS;
23 stateField.clear();
24
25 for (size_t i = 0; i < compSensorCnt; i++)
26 {
27 uint8_t sensorOpState{};
Sagar Srinivas78a225a2020-08-27 00:52:20 -050028 if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
Sampa Misraaea5dde2020-08-31 08:33:47 -050029 stateSetId == PLDM_OEM_IBM_BOOT_STATE)
30 {
31 sensorOpState = fetchBootSide(entityInstance, codeUpdate);
32 }
33 else
34 {
35 rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
36 break;
37 }
38 stateField.push_back({PLDM_SENSOR_ENABLED, PLDM_SENSOR_UNKNOWN,
39 PLDM_SENSOR_UNKNOWN, sensorOpState});
40 }
41 return rc;
42}
43
44int pldm::responder::oem_ibm_platform::Handler::
45 oemSetStateEffecterStatesHandler(
46 EntityType entityType, EntityInstance entityInstance,
47 StateSetId stateSetId, CompositeCount compEffecterCnt,
48 const std::vector<set_effecter_state_field>& stateField)
49{
50 int rc = PLDM_SUCCESS;
51
52 for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
53 {
54 if (stateField[currState].set_request == PLDM_REQUEST_SET)
55 {
Sagar Srinivas78a225a2020-08-27 00:52:20 -050056 if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
Sampa Misraaea5dde2020-08-31 08:33:47 -050057 stateSetId == PLDM_OEM_IBM_BOOT_STATE)
58 {
59 rc = setBootSide(entityInstance, currState, stateField,
60 codeUpdate);
61 }
Sagar Srinivascfdbca72020-09-22 10:03:35 -050062 else if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
63 stateSetId == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
64 {
65 if (stateField[currState].effecter_state ==
66 uint8_t(CodeUpdateState::START))
67 {
68 codeUpdate->setCodeUpdateProgress(true);
69 rc = codeUpdate->setRequestedApplyTime();
70 }
71 else if (stateField[currState].effecter_state ==
72 uint8_t(CodeUpdateState::END))
73 {
74 codeUpdate->setCodeUpdateProgress(false);
75 }
76 else if (stateField[currState].effecter_state ==
77 uint8_t(CodeUpdateState::ABORT))
78 {
79 codeUpdate->setCodeUpdateProgress(false);
80 codeUpdate->clearDirPath(LID_STAGING_DIR);
81 }
82 else if (stateField[currState].effecter_state ==
83 uint8_t(CodeUpdateState::ACCEPT))
84 {
85 // TODO Set new Dbus property provided by code update app
86 }
87 else if (stateField[currState].effecter_state ==
88 uint8_t(CodeUpdateState::REJECT))
89 {
90 // TODO Set new Dbus property provided by code update app
91 }
92 }
Sampa Misraaea5dde2020-08-31 08:33:47 -050093 else
94 {
95 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
96 }
97 }
98 if (rc != PLDM_SUCCESS)
99 {
100 break;
101 }
102 }
103 return rc;
104}
105
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500106void buildAllCodeUpdateEffecterPDR(platform::Handler* platformHandler,
107 uint16_t entityInstance, uint16_t stateSetID,
108 pdr_utils::Repo& repo)
109{
110 size_t pdrSize = 0;
111 pdrSize = sizeof(pldm_state_effecter_pdr) +
112 sizeof(state_effecter_possible_states);
113 std::vector<uint8_t> entry{};
114 entry.resize(pdrSize);
115 pldm_state_effecter_pdr* pdr =
116 reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
117 if (!pdr)
118 {
119 std::cerr << "Failed to get record by PDR type, ERROR:"
120 << PLDM_PLATFORM_INVALID_EFFECTER_ID << std::endl;
121 }
122 pdr->hdr.record_handle = 0;
123 pdr->hdr.version = 1;
124 pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
125 pdr->hdr.record_change_num = 0;
126 pdr->hdr.length = sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
127 pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
128 pdr->effecter_id = platformHandler->getNextEffecterId();
129 pdr->entity_type = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
130 pdr->entity_instance = entityInstance;
131 pdr->container_id = 0;
132 pdr->effecter_semantic_id = 0;
133 pdr->effecter_init = PLDM_NO_INIT;
134 pdr->has_description_pdr = false;
135 pdr->composite_effecter_count = 1;
136
137 auto* possibleStatesPtr = pdr->possible_states;
138 auto possibleStates =
139 reinterpret_cast<state_effecter_possible_states*>(possibleStatesPtr);
140 possibleStates->state_set_id = stateSetID;
141 possibleStates->possible_states_size = 2;
142 auto state =
143 reinterpret_cast<state_effecter_possible_states*>(possibleStates);
144 if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
145 state->states[0].byte = 6;
146 else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
147 state->states[0].byte = 126;
148 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
149 pdrEntry.data = entry.data();
150 pdrEntry.size = pdrSize;
151 repo.addRecord(pdrEntry);
152}
153
154void buildAllCodeUpdateSensorPDR(platform::Handler* platformHandler,
155 uint16_t entityInstance, uint16_t stateSetID,
156 pdr_utils::Repo& repo)
157{
158 size_t pdrSize = 0;
159 pdrSize =
160 sizeof(pldm_state_sensor_pdr) + sizeof(state_sensor_possible_states);
161 std::vector<uint8_t> entry{};
162 entry.resize(pdrSize);
163 pldm_state_sensor_pdr* pdr =
164 reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
165 if (!pdr)
166 {
167 std::cerr << "Failed to get record by PDR type, ERROR:"
168 << PLDM_PLATFORM_INVALID_SENSOR_ID << std::endl;
169 }
170 pdr->hdr.record_handle = 0;
171 pdr->hdr.version = 1;
172 pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
173 pdr->hdr.record_change_num = 0;
174 pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
175 pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
176 pdr->sensor_id = platformHandler->getNextSensorId();
177 pdr->entity_type = PLDM_ENTITY_VIRTUAL_MACHINE_MANAGER;
178 pdr->entity_instance = entityInstance;
179 pdr->container_id = 0;
180 pdr->sensor_init = PLDM_NO_INIT;
181 pdr->sensor_auxiliary_names_pdr = false;
182 pdr->composite_sensor_count = 1;
183
184 auto* possibleStatesPtr = pdr->possible_states;
185 auto possibleStates =
186 reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
187 possibleStates->state_set_id = stateSetID;
188 possibleStates->possible_states_size = 2;
189 auto state =
190 reinterpret_cast<state_sensor_possible_states*>(possibleStates);
191 if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
192 state->states[0].byte = 6;
193 else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
194 state->states[0].byte = 126;
195 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
196 pdrEntry.data = entry.data();
197 pdrEntry.size = pdrSize;
198 repo.addRecord(pdrEntry);
199}
200
201void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
202 pdr_utils::Repo& repo)
203{
204 buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_0,
205 PLDM_OEM_IBM_BOOT_STATE, repo);
206 buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_1,
207 PLDM_OEM_IBM_BOOT_STATE, repo);
208 buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_0,
209 PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
210
211 buildAllCodeUpdateSensorPDR(platformHandler, ENTITY_INSTANCE_0,
212 PLDM_OEM_IBM_BOOT_STATE, repo);
213 buildAllCodeUpdateSensorPDR(platformHandler, ENTITY_INSTANCE_1,
214 PLDM_OEM_IBM_BOOT_STATE, repo);
215 buildAllCodeUpdateSensorPDR(platformHandler, ENTITY_INSTANCE_0,
216 PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
217}
218
Sampa Misraaea5dde2020-08-31 08:33:47 -0500219void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(
220 pldm::responder::platform::Handler* handler)
221{
222 platformHandler = handler;
223}
224
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500225int pldm::responder::oem_ibm_platform::Handler::sendEventToHost(
226 std::vector<uint8_t>& requestMsg)
227{
228 uint8_t* responseMsg = nullptr;
229 size_t responseMsgSize{};
230 if (requestMsg.size())
231 {
232 std::ostringstream tempStream;
233 for (int byte : requestMsg)
234 {
235 tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
236 << " ";
237 }
238 std::cout << tempStream.str() << std::endl;
239 }
240
241 auto requesterRc =
242 pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(), requestMsg.size(),
243 &responseMsg, &responseMsgSize);
244 std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
245 std::free};
246 if (requesterRc != PLDM_REQUESTER_SUCCESS)
247 {
248 std::cerr << "Failed to send message/receive response. RC = "
249 << requesterRc << ", errno = " << errno
250 << "for sending event to host \n";
251 return requesterRc;
252 }
253 uint8_t completionCode{};
254 uint8_t status{};
255 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
256 auto rc = decode_platform_event_message_resp(
257 responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode,
258 &status);
259
260 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
261 {
262 std::cerr << "Failure in decode platform event message response, rc= "
263 << rc << " cc=" << static_cast<unsigned>(completionCode)
264 << "\n";
265 return rc;
266 }
267 std::cout << "returning rc= " << rc << " from sendEventToHost \n";
268
269 return rc;
270}
271
272void pldm::responder::oem_ibm_platform::Handler::sendStateSensorEvent(
273 uint16_t sensorId, enum sensor_event_class_states sensorEventClass,
274 uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState)
275{
276
277 std::vector<uint8_t> sensorEventDataVec{};
278 size_t sensorEventSize = PLDM_SENSOR_EVENT_DATA_MIN_LENGTH + 1;
279 sensorEventDataVec.resize(sensorEventSize);
280 auto eventData = reinterpret_cast<struct pldm_sensor_event_data*>(
281 sensorEventDataVec.data());
282 eventData->sensor_id = sensorId;
283 eventData->sensor_event_class_type = sensorEventClass;
284 auto eventClassStart = eventData->event_class;
285 auto eventClass =
286 reinterpret_cast<struct pldm_sensor_event_state_sensor_state*>(
287 eventClassStart);
288 eventClass->sensor_offset = sensorOffset;
289 eventClass->event_state = eventState;
290 eventClass->previous_event_state = prevEventState;
291 auto instanceId = requester.getInstanceId(mctp_eid);
292 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
293 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
294 sensorEventDataVec.size());
295 auto rc = encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg,
296 instanceId);
297 if (rc != PLDM_SUCCESS)
298 {
299 std::cerr << "Failed to encode state sensor event, rc = " << rc
300 << std::endl;
301 return;
302 }
303 rc = sendEventToHost(requestMsg);
304 if (rc != PLDM_SUCCESS)
305 {
306 std::cerr << "Failed to send event to host: "
307 << "rc=" << rc << std::endl;
308 }
309 requester.markFree(mctp_eid, instanceId);
310 return;
311}
312
313int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec,
314 std::vector<uint8_t>& requestMsg, uint8_t instanceId)
315{
316 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
317
318 auto rc = encode_platform_event_message_req(
319 instanceId, 1 /*formatVersion*/, pldm::responder::pdr::BmcTerminusId,
320 eventType, eventDataVec.data(), eventDataVec.size(), request,
321 eventDataVec.size() + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
322
323 return rc;
324}
325
Sampa Misraaea5dde2020-08-31 08:33:47 -0500326} // namespace oem_ibm_platform
327
328} // namespace responder
329
330} // namespace pldm