blob: 2f06bc5506de94fee087a7a6c10da89c200f77a8 [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::
Sampa Misra3a0e3b92020-10-21 05:58:00 -050045 oemSetStateEffecterStatesHandler(
Varsha Kaverappa3fbd39e2020-09-28 01:40:22 -050046 uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
47 uint8_t compEffecterCnt,
48 std::vector<set_effecter_state_field>& stateField,
49 uint16_t /*effecterId*/)
Sampa Misraaea5dde2020-08-31 08:33:47 -050050{
51 int rc = PLDM_SUCCESS;
52
53 for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
54 {
55 if (stateField[currState].set_request == PLDM_REQUEST_SET)
56 {
Sagar Srinivas78a225a2020-08-27 00:52:20 -050057 if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
Sampa Misraaea5dde2020-08-31 08:33:47 -050058 stateSetId == PLDM_OEM_IBM_BOOT_STATE)
59 {
60 rc = setBootSide(entityInstance, currState, stateField,
61 codeUpdate);
62 }
Sagar Srinivascfdbca72020-09-22 10:03:35 -050063 else if (entityType == PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE &&
64 stateSetId == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
65 {
66 if (stateField[currState].effecter_state ==
67 uint8_t(CodeUpdateState::START))
68 {
69 codeUpdate->setCodeUpdateProgress(true);
Sampa Misra3a0e3b92020-10-21 05:58:00 -050070 startUpdateEvent =
71 std::make_unique<sdeventplus::source::Defer>(
72 event,
73 std::bind(std::mem_fn(&oem_ibm_platform::Handler::
74 _processStartUpdate),
75 this, std::placeholders::_1));
Sagar Srinivascfdbca72020-09-22 10:03:35 -050076 }
77 else if (stateField[currState].effecter_state ==
78 uint8_t(CodeUpdateState::END))
79 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -050080 rc = PLDM_SUCCESS;
81 assembleImageEvent = std::make_unique<
82 sdeventplus::source::Defer>(
83 event,
84 std::bind(
85 std::mem_fn(
86 &oem_ibm_platform::Handler::_processEndUpdate),
87 this, std::placeholders::_1));
88
89 // sendCodeUpdateEvent(effecterId, END, START);
Sagar Srinivascfdbca72020-09-22 10:03:35 -050090 }
91 else if (stateField[currState].effecter_state ==
92 uint8_t(CodeUpdateState::ABORT))
93 {
94 codeUpdate->setCodeUpdateProgress(false);
95 codeUpdate->clearDirPath(LID_STAGING_DIR);
Sampa Misra3a0e3b92020-10-21 05:58:00 -050096 auto sensorId = codeUpdate->getFirmwareUpdateSensor();
97 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
98 uint8_t(CodeUpdateState::ABORT),
99 uint8_t(CodeUpdateState::START));
100 // sendCodeUpdateEvent(effecterId, ABORT, END);
Sagar Srinivascfdbca72020-09-22 10:03:35 -0500101 }
102 else if (stateField[currState].effecter_state ==
103 uint8_t(CodeUpdateState::ACCEPT))
104 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500105 auto sensorId = codeUpdate->getFirmwareUpdateSensor();
106 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
107 uint8_t(CodeUpdateState::ACCEPT),
108 uint8_t(CodeUpdateState::END));
Sagar Srinivascfdbca72020-09-22 10:03:35 -0500109 // TODO Set new Dbus property provided by code update app
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500110 // sendCodeUpdateEvent(effecterId, ACCEPT, END);
Sagar Srinivascfdbca72020-09-22 10:03:35 -0500111 }
112 else if (stateField[currState].effecter_state ==
113 uint8_t(CodeUpdateState::REJECT))
114 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500115 auto sensorId = codeUpdate->getFirmwareUpdateSensor();
116 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
117 uint8_t(CodeUpdateState::REJECT),
118 uint8_t(CodeUpdateState::END));
Sagar Srinivascfdbca72020-09-22 10:03:35 -0500119 // TODO Set new Dbus property provided by code update app
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500120 // sendCodeUpdateEvent(effecterId, REJECT, END);
Sagar Srinivascfdbca72020-09-22 10:03:35 -0500121 }
122 }
Sampa Misraaea5dde2020-08-31 08:33:47 -0500123 else
124 {
125 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
126 }
127 }
128 if (rc != PLDM_SUCCESS)
129 {
130 break;
131 }
132 }
133 return rc;
134}
135
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500136void buildAllCodeUpdateEffecterPDR(platform::Handler* platformHandler,
137 uint16_t entityInstance, uint16_t stateSetID,
138 pdr_utils::Repo& repo)
139{
140 size_t pdrSize = 0;
141 pdrSize = sizeof(pldm_state_effecter_pdr) +
142 sizeof(state_effecter_possible_states);
143 std::vector<uint8_t> entry{};
144 entry.resize(pdrSize);
145 pldm_state_effecter_pdr* pdr =
146 reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
147 if (!pdr)
148 {
149 std::cerr << "Failed to get record by PDR type, ERROR:"
150 << PLDM_PLATFORM_INVALID_EFFECTER_ID << std::endl;
151 }
152 pdr->hdr.record_handle = 0;
153 pdr->hdr.version = 1;
154 pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
155 pdr->hdr.record_change_num = 0;
156 pdr->hdr.length = sizeof(pldm_state_effecter_pdr) - sizeof(pldm_pdr_hdr);
157 pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
158 pdr->effecter_id = platformHandler->getNextEffecterId();
159 pdr->entity_type = PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE;
160 pdr->entity_instance = entityInstance;
161 pdr->container_id = 0;
162 pdr->effecter_semantic_id = 0;
163 pdr->effecter_init = PLDM_NO_INIT;
164 pdr->has_description_pdr = false;
165 pdr->composite_effecter_count = 1;
166
167 auto* possibleStatesPtr = pdr->possible_states;
168 auto possibleStates =
169 reinterpret_cast<state_effecter_possible_states*>(possibleStatesPtr);
170 possibleStates->state_set_id = stateSetID;
171 possibleStates->possible_states_size = 2;
172 auto state =
173 reinterpret_cast<state_effecter_possible_states*>(possibleStates);
174 if (stateSetID == PLDM_OEM_IBM_BOOT_STATE)
175 state->states[0].byte = 6;
176 else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
177 state->states[0].byte = 126;
178 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
179 pdrEntry.data = entry.data();
180 pdrEntry.size = pdrSize;
181 repo.addRecord(pdrEntry);
182}
183
184void buildAllCodeUpdateSensorPDR(platform::Handler* platformHandler,
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500185 uint16_t entityType, uint16_t entityInstance,
186 uint16_t stateSetID, pdr_utils::Repo& repo)
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500187{
188 size_t pdrSize = 0;
189 pdrSize =
190 sizeof(pldm_state_sensor_pdr) + sizeof(state_sensor_possible_states);
191 std::vector<uint8_t> entry{};
192 entry.resize(pdrSize);
193 pldm_state_sensor_pdr* pdr =
194 reinterpret_cast<pldm_state_sensor_pdr*>(entry.data());
195 if (!pdr)
196 {
197 std::cerr << "Failed to get record by PDR type, ERROR:"
198 << PLDM_PLATFORM_INVALID_SENSOR_ID << std::endl;
199 }
200 pdr->hdr.record_handle = 0;
201 pdr->hdr.version = 1;
202 pdr->hdr.type = PLDM_STATE_SENSOR_PDR;
203 pdr->hdr.record_change_num = 0;
204 pdr->hdr.length = sizeof(pldm_state_sensor_pdr) - sizeof(pldm_pdr_hdr);
205 pdr->terminus_handle = pdr::BmcPldmTerminusHandle;
206 pdr->sensor_id = platformHandler->getNextSensorId();
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500207 pdr->entity_type = entityType;
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500208 pdr->entity_instance = entityInstance;
209 pdr->container_id = 0;
210 pdr->sensor_init = PLDM_NO_INIT;
211 pdr->sensor_auxiliary_names_pdr = false;
212 pdr->composite_sensor_count = 1;
213
214 auto* possibleStatesPtr = pdr->possible_states;
215 auto possibleStates =
216 reinterpret_cast<state_sensor_possible_states*>(possibleStatesPtr);
217 possibleStates->state_set_id = stateSetID;
218 possibleStates->possible_states_size = 2;
219 auto state =
220 reinterpret_cast<state_sensor_possible_states*>(possibleStates);
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500221 if ((stateSetID == PLDM_OEM_IBM_BOOT_STATE) ||
222 (stateSetID == oem_ibm_platform::PLDM_OEM_IBM_VERIFICATION_STATE))
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500223 state->states[0].byte = 6;
224 else if (stateSetID == PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE)
225 state->states[0].byte = 126;
226 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
227 pdrEntry.data = entry.data();
228 pdrEntry.size = pdrSize;
229 repo.addRecord(pdrEntry);
230}
231
232void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
233 pdr_utils::Repo& repo)
234{
235 buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_0,
236 PLDM_OEM_IBM_BOOT_STATE, repo);
237 buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_1,
238 PLDM_OEM_IBM_BOOT_STATE, repo);
239 buildAllCodeUpdateEffecterPDR(platformHandler, ENTITY_INSTANCE_0,
240 PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
241
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500242 buildAllCodeUpdateSensorPDR(
243 platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_0,
244 PLDM_OEM_IBM_BOOT_STATE, repo);
245 buildAllCodeUpdateSensorPDR(
246 platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_1,
247 PLDM_OEM_IBM_BOOT_STATE, repo);
248 buildAllCodeUpdateSensorPDR(
249 platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_0,
250 PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, repo);
251 buildAllCodeUpdateSensorPDR(
252 platformHandler, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, ENTITY_INSTANCE_0,
253 PLDM_OEM_IBM_VERIFICATION_STATE, repo);
254 auto sensorId = findStateSensorId(
255 repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
256 ENTITY_INSTANCE_0, 0, PLDM_OEM_IBM_VERIFICATION_STATE);
257 codeUpdate->setMarkerLidSensor(sensorId);
258 sensorId = findStateSensorId(
259 repo.getPdr(), 0, PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
260 ENTITY_INSTANCE_0, 0, PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE);
261 codeUpdate->setFirmwareUpdateSensor(sensorId);
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500262}
263
Sampa Misraaea5dde2020-08-31 08:33:47 -0500264void pldm::responder::oem_ibm_platform::Handler::setPlatformHandler(
265 pldm::responder::platform::Handler* handler)
266{
267 platformHandler = handler;
268}
269
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500270int pldm::responder::oem_ibm_platform::Handler::sendEventToHost(
271 std::vector<uint8_t>& requestMsg)
272{
273 uint8_t* responseMsg = nullptr;
274 size_t responseMsgSize{};
275 if (requestMsg.size())
276 {
277 std::ostringstream tempStream;
278 for (int byte : requestMsg)
279 {
280 tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
281 << " ";
282 }
283 std::cout << tempStream.str() << std::endl;
284 }
285
286 auto requesterRc =
287 pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(), requestMsg.size(),
288 &responseMsg, &responseMsgSize);
289 std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
290 std::free};
291 if (requesterRc != PLDM_REQUESTER_SUCCESS)
292 {
293 std::cerr << "Failed to send message/receive response. RC = "
294 << requesterRc << ", errno = " << errno
295 << "for sending event to host \n";
296 return requesterRc;
297 }
298 uint8_t completionCode{};
299 uint8_t status{};
300 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
301 auto rc = decode_platform_event_message_resp(
302 responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode,
303 &status);
304
305 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
306 {
307 std::cerr << "Failure in decode platform event message response, rc= "
308 << rc << " cc=" << static_cast<unsigned>(completionCode)
309 << "\n";
310 return rc;
311 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500312 return rc;
313}
314
315int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec,
316 std::vector<uint8_t>& requestMsg, uint8_t instanceId)
317{
318 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
319
320 auto rc = encode_platform_event_message_req(
321 instanceId, 1 /*formatVersion*/, 0 /*tId*/, eventType,
322 eventDataVec.data(), eventDataVec.size(), request,
323 eventDataVec.size() + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500324
325 return rc;
326}
327
328void pldm::responder::oem_ibm_platform::Handler::sendStateSensorEvent(
329 uint16_t sensorId, enum sensor_event_class_states sensorEventClass,
330 uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState)
331{
332
333 std::vector<uint8_t> sensorEventDataVec{};
334 size_t sensorEventSize = PLDM_SENSOR_EVENT_DATA_MIN_LENGTH + 1;
335 sensorEventDataVec.resize(sensorEventSize);
336 auto eventData = reinterpret_cast<struct pldm_sensor_event_data*>(
337 sensorEventDataVec.data());
338 eventData->sensor_id = sensorId;
339 eventData->sensor_event_class_type = sensorEventClass;
340 auto eventClassStart = eventData->event_class;
341 auto eventClass =
342 reinterpret_cast<struct pldm_sensor_event_state_sensor_state*>(
343 eventClassStart);
344 eventClass->sensor_offset = sensorOffset;
345 eventClass->event_state = eventState;
346 eventClass->previous_event_state = prevEventState;
347 auto instanceId = requester.getInstanceId(mctp_eid);
348 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
349 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
350 sensorEventDataVec.size());
351 auto rc = encodeEventMsg(PLDM_SENSOR_EVENT, sensorEventDataVec, requestMsg,
352 instanceId);
353 if (rc != PLDM_SUCCESS)
354 {
355 std::cerr << "Failed to encode state sensor event, rc = " << rc
356 << std::endl;
357 return;
358 }
359 rc = sendEventToHost(requestMsg);
360 if (rc != PLDM_SUCCESS)
361 {
362 std::cerr << "Failed to send event to host: "
363 << "rc=" << rc << std::endl;
364 }
365 requester.markFree(mctp_eid, instanceId);
366 return;
367}
368
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500369void pldm::responder::oem_ibm_platform::Handler::_processEndUpdate(
370 sdeventplus::source::EventBase& /*source */)
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500371{
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500372 assembleImageEvent.reset();
373 int retc = assembleCodeUpdateImage();
374 if (retc != PLDM_SUCCESS)
375 {
376 codeUpdate->setCodeUpdateProgress(false);
377 auto sensorId = codeUpdate->getFirmwareUpdateSensor();
378 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
379 uint8_t(CodeUpdateState::FAIL),
380 uint8_t(CodeUpdateState::START));
381 }
382}
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500383
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500384void pldm::responder::oem_ibm_platform::Handler::_processStartUpdate(
385 sdeventplus::source::EventBase& /*source */)
386{
387 codeUpdate->deleteImage();
388 CodeUpdateState state = CodeUpdateState::START;
389 auto rc = codeUpdate->setRequestedApplyTime();
390 if (rc != PLDM_SUCCESS)
391 {
392 std::cerr << "setRequestedApplyTime failed \n";
393 state = CodeUpdateState::FAIL;
394 }
395 auto sensorId = codeUpdate->getFirmwareUpdateSensor();
396 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0, uint8_t(state),
397 uint8_t(CodeUpdateState::END));
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500398}
399
Sampa Misraaea5dde2020-08-31 08:33:47 -0500400} // namespace oem_ibm_platform
Sampa Misraaea5dde2020-08-31 08:33:47 -0500401} // namespace responder
Sampa Misraaea5dde2020-08-31 08:33:47 -0500402} // namespace pldm