blob: 3c82cef788f8ef6f76f2c6b6b48b50fb93f9c6d3 [file] [log] [blame]
George Liucae18662020-05-15 09:32:57 +08001#include "dbus_to_event_handler.hpp"
2
George Liucae18662020-05-15 09:32:57 +08003#include "libpldmresponder/pdr.hpp"
4
Riya Dixit49cfb132023-03-02 04:26:53 -06005#include <phosphor-logging/lg2.hpp>
6
7PHOSPHOR_LOG2_USING;
8
George Liucae18662020-05-15 09:32:57 +08009namespace pldm
10{
Brad Bishop5079ac42021-08-19 18:35:06 -040011using namespace pldm::responder;
George Liucae18662020-05-15 09:32:57 +080012using namespace pldm::responder::pdr;
Brad Bishop5079ac42021-08-19 18:35:06 -040013using namespace pldm::responder::pdr_utils;
George Liucae18662020-05-15 09:32:57 +080014using namespace pldm::utils;
15using namespace sdbusplus::bus::match::rules;
16
17namespace state_sensor
18{
19const std::vector<uint8_t> pdrTypes{PLDM_STATE_SENSOR_PDR};
20
Sampa Misrac0c79482021-06-02 08:01:54 -050021DbusToPLDMEvent::DbusToPLDMEvent(
Andrew Jefferybb9daa42024-07-25 22:40:46 +093022 int /* mctp_fd */, uint8_t mctp_eid, pldm::InstanceIdDb& instanceIdDb,
Sampa Misrac0c79482021-06-02 08:01:54 -050023 pldm::requester::Handler<pldm::requester::Request>* handler) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040024 mctp_eid(mctp_eid), instanceIdDb(instanceIdDb), handler(handler)
George Liucae18662020-05-15 09:32:57 +080025{}
26
27void DbusToPLDMEvent::sendEventMsg(uint8_t eventType,
28 const std::vector<uint8_t>& eventDataVec)
29{
Eric Yang70262ed2025-07-02 06:35:03 +000030 auto instanceIdResult =
31 pldm::utils::getInstanceId(instanceIdDb.next(mctp_eid));
32 if (!instanceIdResult)
33 {
34 return;
35 }
36 auto instanceId = instanceIdResult.value();
Patrick Williams16c2a0a2024-08-16 15:20:59 -040037 std::vector<uint8_t> requestMsg(
38 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
39 eventDataVec.size());
Pavithra Barithaya49575832025-01-29 16:27:30 +053040 auto request = new (requestMsg.data()) pldm_msg;
George Liucae18662020-05-15 09:32:57 +080041
42 auto rc = encode_platform_event_message_req(
ArchanaKakani6c39c7a2022-12-05 04:36:35 -060043 instanceId, 1 /*formatVersion*/, TERMINUS_ID /*tId*/, eventType,
George Liucae18662020-05-15 09:32:57 +080044 eventDataVec.data(), eventDataVec.size(), request,
45 eventDataVec.size() + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES);
46 if (rc != PLDM_SUCCESS)
47 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093048 instanceIdDb.free(mctp_eid, instanceId);
Riya Dixitd6e10ad2024-03-28 19:44:16 -050049 error(
50 "Failed to encode platform event message request, response code '{RC}'",
51 "RC", rc);
George Liucae18662020-05-15 09:32:57 +080052 return;
53 }
54
Patrick Williams16c2a0a2024-08-16 15:20:59 -040055 auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,
56 const pldm_msg* response,
57 size_t respMsgLen) {
Sampa Misrac0c79482021-06-02 08:01:54 -050058 if (response == nullptr || !respMsgLen)
59 {
Riya Dixit49cfb132023-03-02 04:26:53 -060060 error("Failed to receive response for platform event message");
Sampa Misrac0c79482021-06-02 08:01:54 -050061 return;
62 }
63 uint8_t completionCode{};
64 uint8_t status{};
65 auto rc = decode_platform_event_message_resp(response, respMsgLen,
66 &completionCode, &status);
67 if (rc || completionCode)
68 {
Riya Dixit49cfb132023-03-02 04:26:53 -060069 error(
Riya Dixit1e5c81e2024-05-03 07:54:00 -050070 "Failed to decode response of platform event message, response code '{RC}' and completion code '{CC}'",
Riya Dixitd6e10ad2024-03-28 19:44:16 -050071 "RC", rc, "CC", completionCode);
Sampa Misrac0c79482021-06-02 08:01:54 -050072 }
73 };
George Liucae18662020-05-15 09:32:57 +080074
Sampa Misrac0c79482021-06-02 08:01:54 -050075 rc = handler->registerRequest(
76 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
77 std::move(requestMsg), std::move(platformEventMessageResponseHandler));
78 if (rc)
George Liucae18662020-05-15 09:32:57 +080079 {
Riya Dixitd6e10ad2024-03-28 19:44:16 -050080 error("Failed to send the platform event message, response code '{RC}'",
81 "RC", rc);
George Liucae18662020-05-15 09:32:57 +080082 }
83}
84
85void DbusToPLDMEvent::sendStateSensorEvent(SensorId sensorId,
86 const DbusObjMaps& dbusMaps)
87{
88 // Encode PLDM platform event msg to indicate a state sensor change.
89 // DSP0248_1.2.0 Table 19
George Liubd5e2ea2021-04-22 20:33:06 +080090 if (!dbusMaps.contains(sensorId))
91 {
Manojkiran Edaf34867d2021-12-12 15:15:07 +053092 // this is not an error condition, if we end up here
93 // that means that the sensor with the sensor id has
94 // custom behaviour(or probably an oem sensor) in
95 // sending events that cannot be captured via standard
96 // dbus-json infastructure
George Liubd5e2ea2021-04-22 20:33:06 +080097 return;
98 }
99
George Liucae18662020-05-15 09:32:57 +0800100 size_t sensorEventSize = PLDM_SENSOR_EVENT_DATA_MIN_LENGTH + 1;
101 const auto& [dbusMappings, dbusValMaps] = dbusMaps.at(sensorId);
Pavithra Barithaya03b02d52023-07-11 10:08:26 -0500102 for (size_t offset = 0; offset < dbusMappings.size(); ++offset)
George Liucae18662020-05-15 09:32:57 +0800103 {
104 std::vector<uint8_t> sensorEventDataVec{};
105 sensorEventDataVec.resize(sensorEventSize);
Pavithra Barithaya49575832025-01-29 16:27:30 +0530106 auto eventData = new (sensorEventDataVec.data()) pldm_sensor_event_data;
George Liucae18662020-05-15 09:32:57 +0800107 eventData->sensor_id = sensorId;
108 eventData->sensor_event_class_type = PLDM_STATE_SENSOR_STATE;
Pavithra Barithaya03b02d52023-07-11 10:08:26 -0500109 eventData->event_class[0] = static_cast<uint8_t>(offset);
George Liucae18662020-05-15 09:32:57 +0800110 eventData->event_class[1] = PLDM_SENSOR_UNKNOWN;
111 eventData->event_class[2] = PLDM_SENSOR_UNKNOWN;
112
113 const auto& dbusMapping = dbusMappings[offset];
114 const auto& dbusValueMapping = dbusValMaps[offset];
Patrick Williams84b790c2022-07-22 19:26:56 -0500115 auto stateSensorMatch = std::make_unique<sdbusplus::bus::match_t>(
George Liucae18662020-05-15 09:32:57 +0800116 pldm::utils::DBusHandler::getBus(),
117 propertiesChanged(dbusMapping.objectPath.c_str(),
118 dbusMapping.interface.c_str()),
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530119 [this, sensorEventDataVec, dbusValueMapping, dbusMapping, sensorId,
120 offset](auto& msg) mutable {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400121 DbusChangedProps props{};
122 std::string intf;
123 uint8_t previousState = PLDM_SENSOR_UNKNOWN;
124 msg.read(intf, props);
125 if (!props.contains(dbusMapping.propertyName))
George Liu681715c2021-11-25 16:00:55 +0800126 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400127 return;
128 }
129 for (const auto& itr : dbusValueMapping)
130 {
131 bool findValue = false;
132 if (dbusMapping.propertyType == "string")
Patrick Williams6da4f912023-05-10 07:50:53 -0500133 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400134 std::string src = std::get<std::string>(itr.second);
135 std::string dst = std::get<std::string>(
136 props.at(dbusMapping.propertyName));
137
138 auto values = pldm::utils::split(src, "||", " ");
139 for (const auto& value : values)
George Liu99999912021-11-25 16:39:57 +0800140 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400141 if (value == dst)
142 {
143 findValue = true;
144 break;
145 }
George Liu99999912021-11-25 16:39:57 +0800146 }
147 }
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530148 else
149 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400150 findValue =
151 itr.second == props.at(dbusMapping.propertyName)
152 ? true
153 : false;
Manojkiran Edaae933cc2024-02-21 17:19:21 +0530154 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400155
156 if (findValue)
157 {
Pavithra Barithaya49575832025-01-29 16:27:30 +0530158 auto eventData = new (sensorEventDataVec.data())
159 pldm_sensor_event_data;
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400160 eventData->event_class[1] = itr.first;
161 if (sensorCacheMap.contains(sensorId) &&
162 sensorCacheMap[sensorId][offset] !=
163 PLDM_SENSOR_UNKNOWN)
164 {
165 previousState = sensorCacheMap[sensorId][offset];
166 }
167 else
168 {
169 previousState = itr.first;
170 }
171 eventData->event_class[2] = previousState;
172 this->sendEventMsg(PLDM_SENSOR_EVENT,
173 sensorEventDataVec);
174 updateSensorCacheMaps(sensorId, offset, previousState);
175 break;
176 }
Patrick Williams6da4f912023-05-10 07:50:53 -0500177 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400178 });
George Liucae18662020-05-15 09:32:57 +0800179 stateSensorMatchs.emplace_back(std::move(stateSensorMatch));
180 }
181}
182
183void DbusToPLDMEvent::listenSensorEvent(const pdr_utils::Repo& repo,
184 const DbusObjMaps& dbusMaps)
185{
186 const std::map<Type, sensorEvent> sensorHandlers = {
187 {PLDM_STATE_SENSOR_PDR,
188 [this](SensorId sensorId, const DbusObjMaps& dbusMaps) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400189 this->sendStateSensorEvent(sensorId, dbusMaps);
190 }}};
George Liucae18662020-05-15 09:32:57 +0800191
192 pldm_state_sensor_pdr* pdr = nullptr;
193 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> sensorPdrRepo(
194 pldm_pdr_init(), pldm_pdr_destroy);
Andrew Jefferyacb20292023-06-30 11:47:44 +0930195 if (!sensorPdrRepo)
196 {
197 throw std::runtime_error("Unable to instantiate sensor PDR repository");
198 }
George Liucae18662020-05-15 09:32:57 +0800199
200 for (auto pdrType : pdrTypes)
201 {
202 Repo sensorPDRs(sensorPdrRepo.get());
203 getRepoByType(repo, sensorPDRs, pdrType);
204 if (sensorPDRs.empty())
205 {
206 return;
207 }
208
209 PdrEntry pdrEntry{};
210 auto pdrRecord = sensorPDRs.getFirstRecord(pdrEntry);
211 while (pdrRecord)
212 {
Pavithra Barithaya49575832025-01-29 16:27:30 +0530213 pdr = new (pdrEntry.data) pldm_state_sensor_pdr;
George Liucae18662020-05-15 09:32:57 +0800214 SensorId sensorId = LE16TOH(pdr->sensor_id);
George Liubd5e2ea2021-04-22 20:33:06 +0800215 if (sensorHandlers.contains(pdrType))
216 {
217 sensorHandlers.at(pdrType)(sensorId, dbusMaps);
218 }
219
George Liucae18662020-05-15 09:32:57 +0800220 pdrRecord = sensorPDRs.getNextRecord(pdrRecord, pdrEntry);
221 }
222 }
223}
224
225} // namespace state_sensor
226} // namespace pldm