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