1*a34a64bbSThu Nguyen #include "dbus_to_terminus_effecters.hpp"
2*a34a64bbSThu Nguyen 
3*a34a64bbSThu Nguyen #include <libpldm/pdr.h>
4*a34a64bbSThu Nguyen #include <libpldm/platform.h>
5*a34a64bbSThu Nguyen 
6*a34a64bbSThu Nguyen #include <phosphor-logging/lg2.hpp>
7*a34a64bbSThu Nguyen #include <xyz/openbmc_project/Common/error.hpp>
8*a34a64bbSThu Nguyen #include <xyz/openbmc_project/State/Boot/Progress/client.hpp>
9*a34a64bbSThu Nguyen #include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>
10*a34a64bbSThu Nguyen 
11*a34a64bbSThu Nguyen #include <fstream>
12*a34a64bbSThu Nguyen 
13*a34a64bbSThu Nguyen PHOSPHOR_LOG2_USING;
14*a34a64bbSThu Nguyen 
15*a34a64bbSThu Nguyen using namespace pldm::utils;
16*a34a64bbSThu Nguyen 
17*a34a64bbSThu Nguyen namespace pldm
18*a34a64bbSThu Nguyen {
19*a34a64bbSThu Nguyen namespace host_effecters
20*a34a64bbSThu Nguyen {
21*a34a64bbSThu Nguyen using InternalFailure =
22*a34a64bbSThu Nguyen     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
23*a34a64bbSThu Nguyen 
24*a34a64bbSThu Nguyen constexpr auto hostEffecterJson = "dbus_to_terminus_effecter.json";
25*a34a64bbSThu Nguyen 
26*a34a64bbSThu Nguyen void HostEffecterParser::populatePropVals(
27*a34a64bbSThu Nguyen     const Json& dBusValues, std::vector<PropertyValue>& propertyValues,
28*a34a64bbSThu Nguyen     const std::string& propertyType)
29*a34a64bbSThu Nguyen 
30*a34a64bbSThu Nguyen {
31*a34a64bbSThu Nguyen     for (const auto& elem : dBusValues)
32*a34a64bbSThu Nguyen     {
33*a34a64bbSThu Nguyen         auto value = jsonEntryToDbusVal(propertyType, elem);
34*a34a64bbSThu Nguyen         propertyValues.emplace_back(value);
35*a34a64bbSThu Nguyen     }
36*a34a64bbSThu Nguyen }
37*a34a64bbSThu Nguyen 
38*a34a64bbSThu Nguyen void HostEffecterParser::parseEffecterJson(const std::string& jsonPath)
39*a34a64bbSThu Nguyen {
40*a34a64bbSThu Nguyen     fs::path jsonDir(jsonPath);
41*a34a64bbSThu Nguyen     if (!fs::exists(jsonDir) || fs::is_empty(jsonDir))
42*a34a64bbSThu Nguyen     {
43*a34a64bbSThu Nguyen         error("Effecter json file for remote terminus '{PATH}' does not exist.",
44*a34a64bbSThu Nguyen               "PATH", jsonPath);
45*a34a64bbSThu Nguyen         return;
46*a34a64bbSThu Nguyen     }
47*a34a64bbSThu Nguyen 
48*a34a64bbSThu Nguyen     fs::path jsonFilePath = jsonDir / hostEffecterJson;
49*a34a64bbSThu Nguyen     if (!fs::exists(jsonFilePath))
50*a34a64bbSThu Nguyen     {
51*a34a64bbSThu Nguyen         error("Json at path '{PATH}' does not exist.", "PATH", jsonFilePath);
52*a34a64bbSThu Nguyen         throw InternalFailure();
53*a34a64bbSThu Nguyen     }
54*a34a64bbSThu Nguyen 
55*a34a64bbSThu Nguyen     std::ifstream jsonFile(jsonFilePath);
56*a34a64bbSThu Nguyen     auto data = Json::parse(jsonFile, nullptr, false);
57*a34a64bbSThu Nguyen     if (data.is_discarded())
58*a34a64bbSThu Nguyen     {
59*a34a64bbSThu Nguyen         error("Failed to parse json file {PATH}", "PATH", jsonFilePath);
60*a34a64bbSThu Nguyen         throw InternalFailure();
61*a34a64bbSThu Nguyen     }
62*a34a64bbSThu Nguyen     const Json empty{};
63*a34a64bbSThu Nguyen     const std::vector<Json> emptyList{};
64*a34a64bbSThu Nguyen 
65*a34a64bbSThu Nguyen     auto entries = data.value("entries", emptyList);
66*a34a64bbSThu Nguyen     for (const auto& entry : entries)
67*a34a64bbSThu Nguyen     {
68*a34a64bbSThu Nguyen         EffecterInfo effecterInfo;
69*a34a64bbSThu Nguyen         effecterInfo.mctpEid = entry.value("mctp_eid", 0xFF);
70*a34a64bbSThu Nguyen         auto jsonEffecterInfo = entry.value("effecter_info", empty);
71*a34a64bbSThu Nguyen         auto effecterId =
72*a34a64bbSThu Nguyen             jsonEffecterInfo.value("effecterID", PLDM_INVALID_EFFECTER_ID);
73*a34a64bbSThu Nguyen         /* default as PLDM_STATE_EFFECTER_PDR */
74*a34a64bbSThu Nguyen         auto effecterPdrType =
75*a34a64bbSThu Nguyen             jsonEffecterInfo.value("effecterPdrType", PLDM_STATE_EFFECTER_PDR);
76*a34a64bbSThu Nguyen         if (effecterPdrType != PLDM_STATE_EFFECTER_PDR &&
77*a34a64bbSThu Nguyen             effecterPdrType != PLDM_NUMERIC_EFFECTER_PDR)
78*a34a64bbSThu Nguyen         {
79*a34a64bbSThu Nguyen             error(
80*a34a64bbSThu Nguyen                 "Effecter PDRType not supported {TYPE} of effecterID '{EFFECTERID}'",
81*a34a64bbSThu Nguyen                 "TYPE", effecterPdrType, "EFFECTERID", effecterId);
82*a34a64bbSThu Nguyen             continue;
83*a34a64bbSThu Nguyen         }
84*a34a64bbSThu Nguyen         effecterInfo.effecterPdrType = effecterPdrType;
85*a34a64bbSThu Nguyen         effecterInfo.containerId = jsonEffecterInfo.value("containerID", 0);
86*a34a64bbSThu Nguyen         effecterInfo.entityType = jsonEffecterInfo.value("entityType", 0);
87*a34a64bbSThu Nguyen         effecterInfo.entityInstance =
88*a34a64bbSThu Nguyen             jsonEffecterInfo.value("entityInstance", 0);
89*a34a64bbSThu Nguyen         effecterInfo.compEffecterCnt =
90*a34a64bbSThu Nguyen             jsonEffecterInfo.value("compositeEffecterCount", 0);
91*a34a64bbSThu Nguyen         effecterInfo.checkHostState =
92*a34a64bbSThu Nguyen             jsonEffecterInfo.value("checkHostState", true);
93*a34a64bbSThu Nguyen         auto effecters = entry.value("effecters", emptyList);
94*a34a64bbSThu Nguyen 
95*a34a64bbSThu Nguyen         if (effecterPdrType == PLDM_NUMERIC_EFFECTER_PDR)
96*a34a64bbSThu Nguyen         {
97*a34a64bbSThu Nguyen             for (const auto& effecter : effecters)
98*a34a64bbSThu Nguyen             {
99*a34a64bbSThu Nguyen                 DBusNumericEffecterMapping dbusInfo{};
100*a34a64bbSThu Nguyen                 auto jsonDbusInfo = effecter.value("dbus_info", empty);
101*a34a64bbSThu Nguyen                 dbusInfo.dataSize = effecter.value("effecterDataSize", 0);
102*a34a64bbSThu Nguyen                 dbusInfo.unitModifier = effecter.value("unitModifier", 0);
103*a34a64bbSThu Nguyen                 dbusInfo.resolution = effecter.value("resolution", 1);
104*a34a64bbSThu Nguyen                 dbusInfo.offset = effecter.value("offset", 0);
105*a34a64bbSThu Nguyen                 dbusInfo.dbusMap.objectPath =
106*a34a64bbSThu Nguyen                     jsonDbusInfo.value("object_path", "");
107*a34a64bbSThu Nguyen                 dbusInfo.dbusMap.interface =
108*a34a64bbSThu Nguyen                     jsonDbusInfo.value("interface", "");
109*a34a64bbSThu Nguyen                 dbusInfo.dbusMap.propertyName =
110*a34a64bbSThu Nguyen                     jsonDbusInfo.value("property_name", "");
111*a34a64bbSThu Nguyen                 dbusInfo.dbusMap.propertyType =
112*a34a64bbSThu Nguyen                     jsonDbusInfo.value("property_type", "");
113*a34a64bbSThu Nguyen                 /**
114*a34a64bbSThu Nguyen                  * Only support these property type for Numeric Effecter D-Bus
115*a34a64bbSThu Nguyen                  * property:
116*a34a64bbSThu Nguyen                  * "uint8_t", "int16_t",  "uint16_t", "int32_t", "uint32_t",
117*a34a64bbSThu Nguyen                  * "int64_t", "uint64_t", "double"
118*a34a64bbSThu Nguyen                  */
119*a34a64bbSThu Nguyen                 if (!dbusValueNumericTypeNames.contains(
120*a34a64bbSThu Nguyen                         dbusInfo.dbusMap.propertyType))
121*a34a64bbSThu Nguyen                 {
122*a34a64bbSThu Nguyen                     lg2::error(
123*a34a64bbSThu Nguyen                         "Invalid PropertyType {TYPE} of object path {PATH} property name {NAME}",
124*a34a64bbSThu Nguyen                         "TYPE", dbusInfo.dbusMap.propertyType, "PATH",
125*a34a64bbSThu Nguyen                         dbusInfo.dbusMap.objectPath, "NAME",
126*a34a64bbSThu Nguyen                         dbusInfo.dbusMap.propertyName);
127*a34a64bbSThu Nguyen                     continue;
128*a34a64bbSThu Nguyen                 }
129*a34a64bbSThu Nguyen 
130*a34a64bbSThu Nguyen                 dbusInfo.propertyValue =
131*a34a64bbSThu Nguyen                     std::numeric_limits<double>::quiet_NaN();
132*a34a64bbSThu Nguyen                 auto effecterInfoIndex = hostEffecterInfo.size();
133*a34a64bbSThu Nguyen                 auto dbusInfoIndex = effecterInfo.dbusInfo.size();
134*a34a64bbSThu Nguyen                 createHostEffecterMatch(
135*a34a64bbSThu Nguyen                     dbusInfo.dbusMap.objectPath, dbusInfo.dbusMap.interface,
136*a34a64bbSThu Nguyen                     effecterInfoIndex, dbusInfoIndex, effecterId);
137*a34a64bbSThu Nguyen                 effecterInfo.dbusNumericEffecterInfo.emplace_back(
138*a34a64bbSThu Nguyen                     std::move(dbusInfo));
139*a34a64bbSThu Nguyen             }
140*a34a64bbSThu Nguyen             hostEffecterInfo.emplace_back(std::move(effecterInfo));
141*a34a64bbSThu Nguyen             continue;
142*a34a64bbSThu Nguyen         }
143*a34a64bbSThu Nguyen 
144*a34a64bbSThu Nguyen         for (const auto& effecter : effecters)
145*a34a64bbSThu Nguyen         {
146*a34a64bbSThu Nguyen             DBusEffecterMapping dbusInfo{};
147*a34a64bbSThu Nguyen             auto jsonDbusInfo = effecter.value("dbus_info", empty);
148*a34a64bbSThu Nguyen             dbusInfo.dbusMap.objectPath = jsonDbusInfo.value("object_path", "");
149*a34a64bbSThu Nguyen             dbusInfo.dbusMap.interface = jsonDbusInfo.value("interface", "");
150*a34a64bbSThu Nguyen             dbusInfo.dbusMap.propertyName =
151*a34a64bbSThu Nguyen                 jsonDbusInfo.value("property_name", "");
152*a34a64bbSThu Nguyen             dbusInfo.dbusMap.propertyType =
153*a34a64bbSThu Nguyen                 jsonDbusInfo.value("property_type", "");
154*a34a64bbSThu Nguyen             Json propertyValues = jsonDbusInfo["property_values"];
155*a34a64bbSThu Nguyen 
156*a34a64bbSThu Nguyen             populatePropVals(propertyValues, dbusInfo.propertyValues,
157*a34a64bbSThu Nguyen                              dbusInfo.dbusMap.propertyType);
158*a34a64bbSThu Nguyen 
159*a34a64bbSThu Nguyen             const std::vector<uint8_t> emptyStates{};
160*a34a64bbSThu Nguyen             auto state = effecter.value("state", empty);
161*a34a64bbSThu Nguyen             dbusInfo.state.stateSetId = state.value("id", 0);
162*a34a64bbSThu Nguyen             auto states = state.value("state_values", emptyStates);
163*a34a64bbSThu Nguyen             if (dbusInfo.propertyValues.size() != states.size())
164*a34a64bbSThu Nguyen             {
165*a34a64bbSThu Nguyen                 error(
166*a34a64bbSThu Nguyen                     "Number of states do not match with number of D-Bus property values in the json. Object path at '{PATH}' and property '{PROPERTY}' will not be monitored",
167*a34a64bbSThu Nguyen                     "PATH", dbusInfo.dbusMap.objectPath, "PROPERTY",
168*a34a64bbSThu Nguyen                     dbusInfo.dbusMap.propertyName);
169*a34a64bbSThu Nguyen                 continue;
170*a34a64bbSThu Nguyen             }
171*a34a64bbSThu Nguyen             for (const auto& s : states)
172*a34a64bbSThu Nguyen             {
173*a34a64bbSThu Nguyen                 dbusInfo.state.states.emplace_back(s);
174*a34a64bbSThu Nguyen             }
175*a34a64bbSThu Nguyen 
176*a34a64bbSThu Nguyen             auto effecterInfoIndex = hostEffecterInfo.size();
177*a34a64bbSThu Nguyen             auto dbusInfoIndex = effecterInfo.dbusInfo.size();
178*a34a64bbSThu Nguyen             createHostEffecterMatch(
179*a34a64bbSThu Nguyen                 dbusInfo.dbusMap.objectPath, dbusInfo.dbusMap.interface,
180*a34a64bbSThu Nguyen                 effecterInfoIndex, dbusInfoIndex, effecterId);
181*a34a64bbSThu Nguyen             effecterInfo.dbusInfo.emplace_back(std::move(dbusInfo));
182*a34a64bbSThu Nguyen         }
183*a34a64bbSThu Nguyen         hostEffecterInfo.emplace_back(std::move(effecterInfo));
184*a34a64bbSThu Nguyen     }
185*a34a64bbSThu Nguyen }
186*a34a64bbSThu Nguyen 
187*a34a64bbSThu Nguyen bool HostEffecterParser::isHostOn(void)
188*a34a64bbSThu Nguyen {
189*a34a64bbSThu Nguyen     using BootProgress =
190*a34a64bbSThu Nguyen         sdbusplus::client::xyz::openbmc_project::state::boot::Progress<>;
191*a34a64bbSThu Nguyen     constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0";
192*a34a64bbSThu Nguyen     try
193*a34a64bbSThu Nguyen     {
194*a34a64bbSThu Nguyen         auto propVal = dbusHandler->getDbusPropertyVariant(
195*a34a64bbSThu Nguyen             hostStatePath, "BootProgress", BootProgress::interface);
196*a34a64bbSThu Nguyen 
197*a34a64bbSThu Nguyen         using Stages = BootProgress::ProgressStages;
198*a34a64bbSThu Nguyen         auto currHostState = sdbusplus::message::convert_from_string<Stages>(
199*a34a64bbSThu Nguyen                                  std::get<std::string>(propVal))
200*a34a64bbSThu Nguyen                                  .value();
201*a34a64bbSThu Nguyen 
202*a34a64bbSThu Nguyen         if (currHostState != Stages::SystemInitComplete &&
203*a34a64bbSThu Nguyen             currHostState != Stages::OSRunning &&
204*a34a64bbSThu Nguyen             currHostState != Stages::SystemSetup &&
205*a34a64bbSThu Nguyen             currHostState != Stages::OEM)
206*a34a64bbSThu Nguyen         {
207*a34a64bbSThu Nguyen             info(
208*a34a64bbSThu Nguyen                 "Remote terminus is not up/active, current remote terminus state is: '{CURRENT_HOST_STATE}'",
209*a34a64bbSThu Nguyen                 "CURRENT_HOST_STATE", currHostState);
210*a34a64bbSThu Nguyen             return false;
211*a34a64bbSThu Nguyen         }
212*a34a64bbSThu Nguyen     }
213*a34a64bbSThu Nguyen     catch (const sdbusplus::exception_t& e)
214*a34a64bbSThu Nguyen     {
215*a34a64bbSThu Nguyen         error(
216*a34a64bbSThu Nguyen             "Error in getting current remote terminus state. Will still continue to set the remote terminus effecter, error - {ERROR}",
217*a34a64bbSThu Nguyen             "ERROR", e);
218*a34a64bbSThu Nguyen         return false;
219*a34a64bbSThu Nguyen     }
220*a34a64bbSThu Nguyen 
221*a34a64bbSThu Nguyen     return true;
222*a34a64bbSThu Nguyen }
223*a34a64bbSThu Nguyen 
224*a34a64bbSThu Nguyen void HostEffecterParser::processHostEffecterChangeNotification(
225*a34a64bbSThu Nguyen     const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex,
226*a34a64bbSThu Nguyen     size_t dbusInfoIndex, uint16_t effecterId)
227*a34a64bbSThu Nguyen {
228*a34a64bbSThu Nguyen     const auto& pdrType = hostEffecterInfo[effecterInfoIndex].effecterPdrType;
229*a34a64bbSThu Nguyen     if (pdrType == PLDM_NUMERIC_EFFECTER_PDR)
230*a34a64bbSThu Nguyen     {
231*a34a64bbSThu Nguyen         processTerminusNumericEffecterChangeNotification(
232*a34a64bbSThu Nguyen             chProperties, effecterInfoIndex, dbusInfoIndex, effecterId);
233*a34a64bbSThu Nguyen         return;
234*a34a64bbSThu Nguyen     }
235*a34a64bbSThu Nguyen     const auto& propertyName = hostEffecterInfo[effecterInfoIndex]
236*a34a64bbSThu Nguyen                                    .dbusInfo[dbusInfoIndex]
237*a34a64bbSThu Nguyen                                    .dbusMap.propertyName;
238*a34a64bbSThu Nguyen 
239*a34a64bbSThu Nguyen     const auto& it = chProperties.find(propertyName);
240*a34a64bbSThu Nguyen 
241*a34a64bbSThu Nguyen     if (it == chProperties.end())
242*a34a64bbSThu Nguyen     {
243*a34a64bbSThu Nguyen         return;
244*a34a64bbSThu Nguyen     }
245*a34a64bbSThu Nguyen 
246*a34a64bbSThu Nguyen     if (effecterId == PLDM_INVALID_EFFECTER_ID)
247*a34a64bbSThu Nguyen     {
248*a34a64bbSThu Nguyen         constexpr auto localOrRemote = false;
249*a34a64bbSThu Nguyen         effecterId = findStateEffecterId(
250*a34a64bbSThu Nguyen             pdrRepo, hostEffecterInfo[effecterInfoIndex].entityType,
251*a34a64bbSThu Nguyen             hostEffecterInfo[effecterInfoIndex].entityInstance,
252*a34a64bbSThu Nguyen             hostEffecterInfo[effecterInfoIndex].containerId,
253*a34a64bbSThu Nguyen             hostEffecterInfo[effecterInfoIndex]
254*a34a64bbSThu Nguyen                 .dbusInfo[dbusInfoIndex]
255*a34a64bbSThu Nguyen                 .state.stateSetId,
256*a34a64bbSThu Nguyen             localOrRemote);
257*a34a64bbSThu Nguyen         if (effecterId == PLDM_INVALID_EFFECTER_ID)
258*a34a64bbSThu Nguyen         {
259*a34a64bbSThu Nguyen             error(
260*a34a64bbSThu Nguyen                 "Effecter ID '{EFFECTERID}' of entity type '{TYPE}', entityInstance '{INSTANCE}' and containerID '{CONTAINER_ID}' not found in pdr repo",
261*a34a64bbSThu Nguyen                 "EFFECTERID", effecterId, "TYPE",
262*a34a64bbSThu Nguyen                 hostEffecterInfo[effecterInfoIndex].entityType, "INSTANCE",
263*a34a64bbSThu Nguyen                 hostEffecterInfo[effecterInfoIndex].entityInstance,
264*a34a64bbSThu Nguyen                 "CONTAINER_ID",
265*a34a64bbSThu Nguyen                 hostEffecterInfo[effecterInfoIndex].containerId);
266*a34a64bbSThu Nguyen             return;
267*a34a64bbSThu Nguyen         }
268*a34a64bbSThu Nguyen     }
269*a34a64bbSThu Nguyen 
270*a34a64bbSThu Nguyen     if (!isHostOn())
271*a34a64bbSThu Nguyen     {
272*a34a64bbSThu Nguyen         return;
273*a34a64bbSThu Nguyen     }
274*a34a64bbSThu Nguyen 
275*a34a64bbSThu Nguyen     uint8_t newState{};
276*a34a64bbSThu Nguyen     try
277*a34a64bbSThu Nguyen     {
278*a34a64bbSThu Nguyen         newState =
279*a34a64bbSThu Nguyen             findNewStateValue(effecterInfoIndex, dbusInfoIndex, it->second);
280*a34a64bbSThu Nguyen     }
281*a34a64bbSThu Nguyen     catch (const std::out_of_range& e)
282*a34a64bbSThu Nguyen     {
283*a34a64bbSThu Nguyen         error("Failed to find new state '{NEW_STATE}' in json, error - {ERROR}",
284*a34a64bbSThu Nguyen               "ERROR", e, "NEW_STATE", newState);
285*a34a64bbSThu Nguyen         return;
286*a34a64bbSThu Nguyen     }
287*a34a64bbSThu Nguyen 
288*a34a64bbSThu Nguyen     std::vector<set_effecter_state_field> stateField;
289*a34a64bbSThu Nguyen     for (uint8_t i = 0; i < hostEffecterInfo[effecterInfoIndex].compEffecterCnt;
290*a34a64bbSThu Nguyen          i++)
291*a34a64bbSThu Nguyen     {
292*a34a64bbSThu Nguyen         if (i == dbusInfoIndex)
293*a34a64bbSThu Nguyen         {
294*a34a64bbSThu Nguyen             stateField.push_back({PLDM_REQUEST_SET, newState});
295*a34a64bbSThu Nguyen         }
296*a34a64bbSThu Nguyen         else
297*a34a64bbSThu Nguyen         {
298*a34a64bbSThu Nguyen             stateField.push_back({PLDM_NO_CHANGE, 0});
299*a34a64bbSThu Nguyen         }
300*a34a64bbSThu Nguyen     }
301*a34a64bbSThu Nguyen     int rc{};
302*a34a64bbSThu Nguyen     try
303*a34a64bbSThu Nguyen     {
304*a34a64bbSThu Nguyen         rc = setHostStateEffecter(effecterInfoIndex, stateField, effecterId);
305*a34a64bbSThu Nguyen     }
306*a34a64bbSThu Nguyen     catch (const std::runtime_error& e)
307*a34a64bbSThu Nguyen     {
308*a34a64bbSThu Nguyen         error(
309*a34a64bbSThu Nguyen             "Failed to set remote terminus state effecter for effecter ID '{EFFECTERID}', error - {ERROR}",
310*a34a64bbSThu Nguyen             "ERROR", e, "EFFECTERID", effecterId);
311*a34a64bbSThu Nguyen         return;
312*a34a64bbSThu Nguyen     }
313*a34a64bbSThu Nguyen     if (rc != PLDM_SUCCESS)
314*a34a64bbSThu Nguyen     {
315*a34a64bbSThu Nguyen         error(
316*a34a64bbSThu Nguyen             "Failed to set the remote terminus state effecter for effecter ID '{EFFECTERID}', response code '{RC}'",
317*a34a64bbSThu Nguyen             "EFFECTERID", effecterId, "RC", rc);
318*a34a64bbSThu Nguyen     }
319*a34a64bbSThu Nguyen }
320*a34a64bbSThu Nguyen 
321*a34a64bbSThu Nguyen double HostEffecterParser::adjustValue(double value, double offset,
322*a34a64bbSThu Nguyen                                        double resolution, int8_t modify)
323*a34a64bbSThu Nguyen {
324*a34a64bbSThu Nguyen     double unitModifier = std::pow(10, signed(modify));
325*a34a64bbSThu Nguyen     return std::round((value - offset) * resolution / unitModifier);
326*a34a64bbSThu Nguyen }
327*a34a64bbSThu Nguyen 
328*a34a64bbSThu Nguyen void HostEffecterParser::processTerminusNumericEffecterChangeNotification(
329*a34a64bbSThu Nguyen     const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex,
330*a34a64bbSThu Nguyen     size_t dbusInfoIndex, uint16_t effecterId)
331*a34a64bbSThu Nguyen {
332*a34a64bbSThu Nguyen     const auto& checkHost = hostEffecterInfo[effecterInfoIndex].checkHostState;
333*a34a64bbSThu Nguyen     const auto& propValues = hostEffecterInfo[effecterInfoIndex]
334*a34a64bbSThu Nguyen                                  .dbusNumericEffecterInfo[dbusInfoIndex];
335*a34a64bbSThu Nguyen     const auto& propertyName = propValues.dbusMap.propertyName;
336*a34a64bbSThu Nguyen     const auto& propertyType = propValues.dbusMap.propertyType;
337*a34a64bbSThu Nguyen 
338*a34a64bbSThu Nguyen     if (effecterId == PLDM_INVALID_EFFECTER_ID)
339*a34a64bbSThu Nguyen     {
340*a34a64bbSThu Nguyen         lg2::error(
341*a34a64bbSThu Nguyen             "Dbus to PLDM Numeric Effecter setting requires valid effecter ID. Invalid effecter ID {EFFECTER_ID}",
342*a34a64bbSThu Nguyen             "EFFECTER_ID", effecterId);
343*a34a64bbSThu Nguyen     }
344*a34a64bbSThu Nguyen 
345*a34a64bbSThu Nguyen     if (!dbusValueNumericTypeNames.contains(propertyType))
346*a34a64bbSThu Nguyen     {
347*a34a64bbSThu Nguyen         lg2::error(
348*a34a64bbSThu Nguyen             "DBus Value to PLDM Numeric Effecter setting only supports D-Bus Numeric data type. Invalid type {TYPE}",
349*a34a64bbSThu Nguyen             "TYPE", propertyType);
350*a34a64bbSThu Nguyen         return;
351*a34a64bbSThu Nguyen     }
352*a34a64bbSThu Nguyen 
353*a34a64bbSThu Nguyen     const auto& it = chProperties.find(propertyName);
354*a34a64bbSThu Nguyen 
355*a34a64bbSThu Nguyen     if (it == chProperties.end())
356*a34a64bbSThu Nguyen     {
357*a34a64bbSThu Nguyen         return;
358*a34a64bbSThu Nguyen     }
359*a34a64bbSThu Nguyen 
360*a34a64bbSThu Nguyen     double val = std::numeric_limits<double>::quiet_NaN();
361*a34a64bbSThu Nguyen     if (!pldm::utils::dbusPropValuesToDouble(propertyType, it->second, &val))
362*a34a64bbSThu Nguyen     {
363*a34a64bbSThu Nguyen         lg2::error(
364*a34a64bbSThu Nguyen             "DBus Value to PLDM Numeric Effecter setting only supports Numeric D-Bus data type. Invalid type {TYPE}",
365*a34a64bbSThu Nguyen             "TYPE", propertyType);
366*a34a64bbSThu Nguyen         return;
367*a34a64bbSThu Nguyen     }
368*a34a64bbSThu Nguyen 
369*a34a64bbSThu Nguyen     /* Update the current value of D-Bus interface*/
370*a34a64bbSThu Nguyen     if (!std::isnan(val) && std::isnan(propValues.propertyValue))
371*a34a64bbSThu Nguyen     {
372*a34a64bbSThu Nguyen         hostEffecterInfo[effecterInfoIndex]
373*a34a64bbSThu Nguyen             .dbusNumericEffecterInfo[dbusInfoIndex]
374*a34a64bbSThu Nguyen             .propertyValue = val;
375*a34a64bbSThu Nguyen         return;
376*a34a64bbSThu Nguyen     }
377*a34a64bbSThu Nguyen 
378*a34a64bbSThu Nguyen     /* Bypass the setting when the current value is NA or settting value is NA*/
379*a34a64bbSThu Nguyen     if (std::isnan(propValues.propertyValue) || std::isnan(val))
380*a34a64bbSThu Nguyen     {
381*a34a64bbSThu Nguyen         return;
382*a34a64bbSThu Nguyen     }
383*a34a64bbSThu Nguyen 
384*a34a64bbSThu Nguyen     /* Setting value equals the D-Bus value which is real value of effecter */
385*a34a64bbSThu Nguyen     if (val == propValues.propertyValue)
386*a34a64bbSThu Nguyen     {
387*a34a64bbSThu Nguyen         return;
388*a34a64bbSThu Nguyen     }
389*a34a64bbSThu Nguyen 
390*a34a64bbSThu Nguyen     double rawValue = adjustValue(val, propValues.offset, propValues.resolution,
391*a34a64bbSThu Nguyen                                   propValues.unitModifier);
392*a34a64bbSThu Nguyen 
393*a34a64bbSThu Nguyen     if (checkHost && !isHostOn())
394*a34a64bbSThu Nguyen     {
395*a34a64bbSThu Nguyen         return;
396*a34a64bbSThu Nguyen     }
397*a34a64bbSThu Nguyen 
398*a34a64bbSThu Nguyen     try
399*a34a64bbSThu Nguyen     {
400*a34a64bbSThu Nguyen         auto rc = setTerminusNumericEffecter(effecterInfoIndex, effecterId,
401*a34a64bbSThu Nguyen                                              propValues.dataSize, rawValue);
402*a34a64bbSThu Nguyen         if (rc)
403*a34a64bbSThu Nguyen         {
404*a34a64bbSThu Nguyen             error(
405*a34a64bbSThu Nguyen                 "Could not set the numeric effecter ID '{EFFECTERID}' return code '{RC}'",
406*a34a64bbSThu Nguyen                 "EFFECTERID", effecterId, "RC", rc);
407*a34a64bbSThu Nguyen             return;
408*a34a64bbSThu Nguyen         }
409*a34a64bbSThu Nguyen     }
410*a34a64bbSThu Nguyen     catch (const std::runtime_error& e)
411*a34a64bbSThu Nguyen     {
412*a34a64bbSThu Nguyen         error("Could not set numeric effecter ID= '{EFFECTERID}'", "EFFECTERID",
413*a34a64bbSThu Nguyen               effecterId);
414*a34a64bbSThu Nguyen         return;
415*a34a64bbSThu Nguyen     }
416*a34a64bbSThu Nguyen 
417*a34a64bbSThu Nguyen     hostEffecterInfo[effecterInfoIndex]
418*a34a64bbSThu Nguyen         .dbusNumericEffecterInfo[dbusInfoIndex]
419*a34a64bbSThu Nguyen         .propertyValue = val;
420*a34a64bbSThu Nguyen 
421*a34a64bbSThu Nguyen     return;
422*a34a64bbSThu Nguyen }
423*a34a64bbSThu Nguyen 
424*a34a64bbSThu Nguyen uint8_t HostEffecterParser::findNewStateValue(
425*a34a64bbSThu Nguyen     size_t effecterInfoIndex, size_t dbusInfoIndex,
426*a34a64bbSThu Nguyen     const PropertyValue& propertyValue)
427*a34a64bbSThu Nguyen {
428*a34a64bbSThu Nguyen     const auto& propValues = hostEffecterInfo[effecterInfoIndex]
429*a34a64bbSThu Nguyen                                  .dbusInfo[dbusInfoIndex]
430*a34a64bbSThu Nguyen                                  .propertyValues;
431*a34a64bbSThu Nguyen     auto it = std::find(propValues.begin(), propValues.end(), propertyValue);
432*a34a64bbSThu Nguyen     uint8_t newState{};
433*a34a64bbSThu Nguyen     if (it != propValues.end())
434*a34a64bbSThu Nguyen     {
435*a34a64bbSThu Nguyen         auto index = std::distance(propValues.begin(), it);
436*a34a64bbSThu Nguyen         newState = hostEffecterInfo[effecterInfoIndex]
437*a34a64bbSThu Nguyen                        .dbusInfo[dbusInfoIndex]
438*a34a64bbSThu Nguyen                        .state.states[index];
439*a34a64bbSThu Nguyen     }
440*a34a64bbSThu Nguyen     else
441*a34a64bbSThu Nguyen     {
442*a34a64bbSThu Nguyen         throw std::out_of_range("new state not found in json");
443*a34a64bbSThu Nguyen     }
444*a34a64bbSThu Nguyen     return newState;
445*a34a64bbSThu Nguyen }
446*a34a64bbSThu Nguyen 
447*a34a64bbSThu Nguyen size_t getEffecterDataSize(uint8_t effecterDataSize)
448*a34a64bbSThu Nguyen {
449*a34a64bbSThu Nguyen     switch (effecterDataSize)
450*a34a64bbSThu Nguyen     {
451*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_UINT8:
452*a34a64bbSThu Nguyen             return sizeof(uint8_t);
453*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_SINT8:
454*a34a64bbSThu Nguyen             return sizeof(int8_t);
455*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_UINT16:
456*a34a64bbSThu Nguyen             return sizeof(uint16_t);
457*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_SINT16:
458*a34a64bbSThu Nguyen             return sizeof(int16_t);
459*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_UINT32:
460*a34a64bbSThu Nguyen             return sizeof(uint32_t);
461*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_SINT32:
462*a34a64bbSThu Nguyen             return sizeof(int32_t);
463*a34a64bbSThu Nguyen         default:
464*a34a64bbSThu Nguyen             return 0;
465*a34a64bbSThu Nguyen     }
466*a34a64bbSThu Nguyen }
467*a34a64bbSThu Nguyen 
468*a34a64bbSThu Nguyen int HostEffecterParser::setTerminusNumericEffecter(
469*a34a64bbSThu Nguyen     size_t effecterInfoIndex, uint16_t effecterId, uint8_t dataSize,
470*a34a64bbSThu Nguyen     double rawValue)
471*a34a64bbSThu Nguyen {
472*a34a64bbSThu Nguyen     uint8_t& mctpEid = hostEffecterInfo[effecterInfoIndex].mctpEid;
473*a34a64bbSThu Nguyen     auto instanceId = instanceIdDb->next(mctpEid);
474*a34a64bbSThu Nguyen     int rc = PLDM_ERROR;
475*a34a64bbSThu Nguyen     std::vector<uint8_t> requestMsg;
476*a34a64bbSThu Nguyen 
477*a34a64bbSThu Nguyen     /**
478*a34a64bbSThu Nguyen      * PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES = 4. It includes the 1 byte
479*a34a64bbSThu Nguyen      * value for effecterValue as `Table 48 - SetNumericEffecterValue command
480*a34a64bbSThu Nguyen      * format` DSP0248 V1.3.0 So the payload_length of `SetNumericEffecterValue`
481*a34a64bbSThu Nguyen      * request message will be payload_length =
482*a34a64bbSThu Nguyen      * PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES - 1 + sizeof(dataType)
483*a34a64bbSThu Nguyen      */
484*a34a64bbSThu Nguyen     size_t payload_length = PLDM_SET_NUMERIC_EFFECTER_VALUE_MIN_REQ_BYTES - 1 +
485*a34a64bbSThu Nguyen                             getEffecterDataSize(dataSize);
486*a34a64bbSThu Nguyen     requestMsg.resize(sizeof(pldm_msg_hdr) + payload_length);
487*a34a64bbSThu Nguyen     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
488*a34a64bbSThu Nguyen     switch (dataSize)
489*a34a64bbSThu Nguyen     {
490*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_UINT8:
491*a34a64bbSThu Nguyen         {
492*a34a64bbSThu Nguyen             auto value_uint8 = (uint8_t)rawValue;
493*a34a64bbSThu Nguyen             rc = encode_set_numeric_effecter_value_req(
494*a34a64bbSThu Nguyen                 instanceId, effecterId, dataSize,
495*a34a64bbSThu Nguyen                 reinterpret_cast<uint8_t*>(&value_uint8), request,
496*a34a64bbSThu Nguyen                 payload_length);
497*a34a64bbSThu Nguyen             break;
498*a34a64bbSThu Nguyen         }
499*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_SINT8:
500*a34a64bbSThu Nguyen         {
501*a34a64bbSThu Nguyen             auto value_int8 = (int8_t)rawValue;
502*a34a64bbSThu Nguyen             rc = encode_set_numeric_effecter_value_req(
503*a34a64bbSThu Nguyen                 instanceId, effecterId, dataSize,
504*a34a64bbSThu Nguyen                 reinterpret_cast<uint8_t*>(&value_int8), request,
505*a34a64bbSThu Nguyen                 payload_length);
506*a34a64bbSThu Nguyen             break;
507*a34a64bbSThu Nguyen         }
508*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_UINT16:
509*a34a64bbSThu Nguyen         {
510*a34a64bbSThu Nguyen             auto value_uint16 = (uint16_t)rawValue;
511*a34a64bbSThu Nguyen             rc = encode_set_numeric_effecter_value_req(
512*a34a64bbSThu Nguyen                 instanceId, effecterId, dataSize,
513*a34a64bbSThu Nguyen                 reinterpret_cast<uint8_t*>(&value_uint16), request,
514*a34a64bbSThu Nguyen                 payload_length);
515*a34a64bbSThu Nguyen             break;
516*a34a64bbSThu Nguyen         }
517*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_SINT16:
518*a34a64bbSThu Nguyen         {
519*a34a64bbSThu Nguyen             auto value_int16 = (int16_t)rawValue;
520*a34a64bbSThu Nguyen             rc = encode_set_numeric_effecter_value_req(
521*a34a64bbSThu Nguyen                 instanceId, effecterId, dataSize,
522*a34a64bbSThu Nguyen                 reinterpret_cast<uint8_t*>(&value_int16), request,
523*a34a64bbSThu Nguyen                 payload_length);
524*a34a64bbSThu Nguyen             break;
525*a34a64bbSThu Nguyen         }
526*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_UINT32:
527*a34a64bbSThu Nguyen         {
528*a34a64bbSThu Nguyen             auto value_uint32 = (uint32_t)rawValue;
529*a34a64bbSThu Nguyen             rc = encode_set_numeric_effecter_value_req(
530*a34a64bbSThu Nguyen                 instanceId, effecterId, dataSize,
531*a34a64bbSThu Nguyen                 reinterpret_cast<uint8_t*>(&value_uint32), request,
532*a34a64bbSThu Nguyen                 payload_length);
533*a34a64bbSThu Nguyen             break;
534*a34a64bbSThu Nguyen         }
535*a34a64bbSThu Nguyen         case PLDM_EFFECTER_DATA_SIZE_SINT32:
536*a34a64bbSThu Nguyen         {
537*a34a64bbSThu Nguyen             auto value_int32 = (int32_t)rawValue;
538*a34a64bbSThu Nguyen             rc = encode_set_numeric_effecter_value_req(
539*a34a64bbSThu Nguyen                 instanceId, effecterId, dataSize,
540*a34a64bbSThu Nguyen                 reinterpret_cast<uint8_t*>(&value_int32), request,
541*a34a64bbSThu Nguyen                 payload_length);
542*a34a64bbSThu Nguyen             break;
543*a34a64bbSThu Nguyen         }
544*a34a64bbSThu Nguyen         default:
545*a34a64bbSThu Nguyen             break;
546*a34a64bbSThu Nguyen     }
547*a34a64bbSThu Nguyen 
548*a34a64bbSThu Nguyen     if (rc)
549*a34a64bbSThu Nguyen     {
550*a34a64bbSThu Nguyen         error(
551*a34a64bbSThu Nguyen             "Failed to encode set numeric effecter request message for effecter ID '{EFFECTERID}' and instanceID '{INSTANCE}' with error code '{RC}'",
552*a34a64bbSThu Nguyen             "EFFECTERID", effecterId, "INSTANCE", instanceId, "RC", lg2::hex,
553*a34a64bbSThu Nguyen             rc);
554*a34a64bbSThu Nguyen 
555*a34a64bbSThu Nguyen         instanceIdDb->free(mctpEid, instanceId);
556*a34a64bbSThu Nguyen         return rc;
557*a34a64bbSThu Nguyen     }
558*a34a64bbSThu Nguyen 
559*a34a64bbSThu Nguyen     auto setNumericEffecterRespHandler = [effecterId](mctp_eid_t /*eid*/,
560*a34a64bbSThu Nguyen                                                       const pldm_msg* response,
561*a34a64bbSThu Nguyen                                                       size_t respMsgLen) {
562*a34a64bbSThu Nguyen         if (response == nullptr || !respMsgLen)
563*a34a64bbSThu Nguyen         {
564*a34a64bbSThu Nguyen             error(
565*a34a64bbSThu Nguyen                 "Failed to receive response for setNumericEffecterValue command");
566*a34a64bbSThu Nguyen             return;
567*a34a64bbSThu Nguyen         }
568*a34a64bbSThu Nguyen         uint8_t completionCode{};
569*a34a64bbSThu Nguyen         auto rc = decode_set_numeric_effecter_value_resp(response, respMsgLen,
570*a34a64bbSThu Nguyen                                                          &completionCode);
571*a34a64bbSThu Nguyen 
572*a34a64bbSThu Nguyen         if (rc)
573*a34a64bbSThu Nguyen         {
574*a34a64bbSThu Nguyen             error(
575*a34a64bbSThu Nguyen                 "Failed to decode set numeric effecter response message for effecter ID '{EFFECTERID}' with error code '{RC}'",
576*a34a64bbSThu Nguyen                 "EFFECTERID", effecterId, "RC", lg2::hex, rc);
577*a34a64bbSThu Nguyen         }
578*a34a64bbSThu Nguyen         if (completionCode)
579*a34a64bbSThu Nguyen         {
580*a34a64bbSThu Nguyen             error(
581*a34a64bbSThu Nguyen                 "Failed to set numeric effecter for effecter ID '{EFFECTERID}' with complete code '{CC}'",
582*a34a64bbSThu Nguyen                 "EFFECTERID", effecterId, "CC", lg2::hex, completionCode);
583*a34a64bbSThu Nguyen         }
584*a34a64bbSThu Nguyen     };
585*a34a64bbSThu Nguyen 
586*a34a64bbSThu Nguyen     rc = handler->registerRequest(
587*a34a64bbSThu Nguyen         mctpEid, instanceId, PLDM_PLATFORM, PLDM_SET_NUMERIC_EFFECTER_VALUE,
588*a34a64bbSThu Nguyen         std::move(requestMsg), std::move(setNumericEffecterRespHandler));
589*a34a64bbSThu Nguyen     if (rc)
590*a34a64bbSThu Nguyen     {
591*a34a64bbSThu Nguyen         error("Failed to send request to set an effecter on Host");
592*a34a64bbSThu Nguyen     }
593*a34a64bbSThu Nguyen     return rc;
594*a34a64bbSThu Nguyen }
595*a34a64bbSThu Nguyen 
596*a34a64bbSThu Nguyen int HostEffecterParser::setHostStateEffecter(
597*a34a64bbSThu Nguyen     size_t effecterInfoIndex, std::vector<set_effecter_state_field>& stateField,
598*a34a64bbSThu Nguyen     uint16_t effecterId)
599*a34a64bbSThu Nguyen {
600*a34a64bbSThu Nguyen     uint8_t& mctpEid = hostEffecterInfo[effecterInfoIndex].mctpEid;
601*a34a64bbSThu Nguyen     uint8_t& compEffCnt = hostEffecterInfo[effecterInfoIndex].compEffecterCnt;
602*a34a64bbSThu Nguyen     auto instanceId = instanceIdDb->next(mctpEid);
603*a34a64bbSThu Nguyen 
604*a34a64bbSThu Nguyen     std::vector<uint8_t> requestMsg(
605*a34a64bbSThu Nguyen         sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(compEffCnt) +
606*a34a64bbSThu Nguyen             sizeof(set_effecter_state_field) * compEffCnt,
607*a34a64bbSThu Nguyen         0);
608*a34a64bbSThu Nguyen     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
609*a34a64bbSThu Nguyen     auto rc = encode_set_state_effecter_states_req(
610*a34a64bbSThu Nguyen         instanceId, effecterId, compEffCnt, stateField.data(), request);
611*a34a64bbSThu Nguyen 
612*a34a64bbSThu Nguyen     if (rc != PLDM_SUCCESS)
613*a34a64bbSThu Nguyen     {
614*a34a64bbSThu Nguyen         error(
615*a34a64bbSThu Nguyen             "Failed to encode set state effecter states message for effecter ID '{EFFECTERID}' and instanceID '{INSTANCE}' with response code '{RC}'",
616*a34a64bbSThu Nguyen             "EFFECTERID", effecterId, "INSTANCE", instanceId, "RC", lg2::hex,
617*a34a64bbSThu Nguyen             rc);
618*a34a64bbSThu Nguyen         instanceIdDb->free(mctpEid, instanceId);
619*a34a64bbSThu Nguyen         return rc;
620*a34a64bbSThu Nguyen     }
621*a34a64bbSThu Nguyen 
622*a34a64bbSThu Nguyen     auto setStateEffecterStatesRespHandler = [](mctp_eid_t /*eid*/,
623*a34a64bbSThu Nguyen                                                 const pldm_msg* response,
624*a34a64bbSThu Nguyen                                                 size_t respMsgLen) {
625*a34a64bbSThu Nguyen         if (response == nullptr || !respMsgLen)
626*a34a64bbSThu Nguyen         {
627*a34a64bbSThu Nguyen             error(
628*a34a64bbSThu Nguyen                 "Failed to receive response for setting state effecter states.");
629*a34a64bbSThu Nguyen             return;
630*a34a64bbSThu Nguyen         }
631*a34a64bbSThu Nguyen         uint8_t completionCode{};
632*a34a64bbSThu Nguyen         auto rc = decode_set_state_effecter_states_resp(response, respMsgLen,
633*a34a64bbSThu Nguyen                                                         &completionCode);
634*a34a64bbSThu Nguyen         if (rc)
635*a34a64bbSThu Nguyen         {
636*a34a64bbSThu Nguyen             error(
637*a34a64bbSThu Nguyen                 "Failed to decode response of set state effecter states, response code '{RC}'",
638*a34a64bbSThu Nguyen                 "RC", rc);
639*a34a64bbSThu Nguyen             pldm::utils::reportError(
640*a34a64bbSThu Nguyen                 "xyz.openbmc_project.bmc.pldm.SetHostEffecterFailed");
641*a34a64bbSThu Nguyen         }
642*a34a64bbSThu Nguyen         if (completionCode)
643*a34a64bbSThu Nguyen         {
644*a34a64bbSThu Nguyen             error(
645*a34a64bbSThu Nguyen                 "Failed to set a remote terminus effecter, completion code '{CC}'",
646*a34a64bbSThu Nguyen                 "CC", completionCode);
647*a34a64bbSThu Nguyen             pldm::utils::reportError(
648*a34a64bbSThu Nguyen                 "xyz.openbmc_project.bmc.pldm.SetHostEffecterFailed");
649*a34a64bbSThu Nguyen         }
650*a34a64bbSThu Nguyen     };
651*a34a64bbSThu Nguyen 
652*a34a64bbSThu Nguyen     rc = handler->registerRequest(
653*a34a64bbSThu Nguyen         mctpEid, instanceId, PLDM_PLATFORM, PLDM_SET_STATE_EFFECTER_STATES,
654*a34a64bbSThu Nguyen         std::move(requestMsg), std::move(setStateEffecterStatesRespHandler));
655*a34a64bbSThu Nguyen     if (rc)
656*a34a64bbSThu Nguyen     {
657*a34a64bbSThu Nguyen         error(
658*a34a64bbSThu Nguyen             "Failed to send request to set an effecter on remote terminus for effecter ID '{EFFECTERID}', response code '{RC}'",
659*a34a64bbSThu Nguyen             "EFFECTERID", effecterId, "RC", rc);
660*a34a64bbSThu Nguyen     }
661*a34a64bbSThu Nguyen     return rc;
662*a34a64bbSThu Nguyen }
663*a34a64bbSThu Nguyen 
664*a34a64bbSThu Nguyen void HostEffecterParser::createHostEffecterMatch(
665*a34a64bbSThu Nguyen     const std::string& objectPath, const std::string& interface,
666*a34a64bbSThu Nguyen     size_t effecterInfoIndex, size_t dbusInfoIndex, uint16_t effecterId)
667*a34a64bbSThu Nguyen {
668*a34a64bbSThu Nguyen     using namespace sdbusplus::bus::match::rules;
669*a34a64bbSThu Nguyen     effecterInfoMatch.emplace_back(std::make_unique<sdbusplus::bus::match_t>(
670*a34a64bbSThu Nguyen         pldm::utils::DBusHandler::getBus(),
671*a34a64bbSThu Nguyen         propertiesChanged(objectPath, interface),
672*a34a64bbSThu Nguyen         [this, effecterInfoIndex, dbusInfoIndex,
673*a34a64bbSThu Nguyen          effecterId](sdbusplus::message_t& msg) {
674*a34a64bbSThu Nguyen             DbusChgHostEffecterProps props;
675*a34a64bbSThu Nguyen             std::string iface;
676*a34a64bbSThu Nguyen             msg.read(iface, props);
677*a34a64bbSThu Nguyen             processHostEffecterChangeNotification(props, effecterInfoIndex,
678*a34a64bbSThu Nguyen                                                   dbusInfoIndex, effecterId);
679*a34a64bbSThu Nguyen         }));
680*a34a64bbSThu Nguyen }
681*a34a64bbSThu Nguyen 
682*a34a64bbSThu Nguyen } // namespace host_effecters
683*a34a64bbSThu Nguyen } // namespace pldm
684