blob: 247dbfd5d0e42f90550da58353d855d5021fba6e [file] [log] [blame]
George Liu0d7aca82020-03-30 15:01:36 +08001#pragma once
2
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05003#include "common/utils.hpp"
George Liu0d7aca82020-03-30 15:01:36 +08004#include "libpldmresponder/pdr.hpp"
5#include "pdr_utils.hpp"
Deepak Kodihalli1521f6d2020-06-16 08:51:02 -05006#include "pldmd/handler.hpp"
George Liu0d7aca82020-03-30 15:01:36 +08007
George Liuc453e162022-12-21 17:16:23 +08008#include <libpldm/platform.h>
9#include <libpldm/states.h>
10
Riya Dixit49cfb132023-03-02 04:26:53 -060011#include <phosphor-logging/lg2.hpp>
12
George Liu0d7aca82020-03-30 15:01:36 +080013#include <cstdint>
14#include <map>
15
Riya Dixit49cfb132023-03-02 04:26:53 -060016PHOSPHOR_LOG2_USING;
17
George Liu0d7aca82020-03-30 15:01:36 +080018namespace pldm
19{
20namespace responder
21{
22namespace platform_state_effecter
23{
24/** @brief Function to set the effecter requested by pldm requester
25 *
26 * @tparam[in] DBusInterface - DBus interface type
27 * @tparam[in] Handler - pldm::responder::platform::Handler
28 * @param[in] dBusIntf - The interface object of DBusInterface
29 * @param[in] handler - The interface object of
30 * pldm::responder::platform::Handler
31 * @param[in] effecterId - Effecter ID sent by the requester to act on
32 * @param[in] stateField - The state field data for each of the states,
33 * equal to composite effecter count in number
34 * @return - Success or failure in setting the states. Returns failure in
35 * terms of PLDM completion codes if atleast one state fails to be set
36 */
37template <class DBusInterface, class Handler>
38int setStateEffecterStatesHandler(
39 const DBusInterface& dBusIntf, Handler& handler, uint16_t effecterId,
40 const std::vector<set_effecter_state_field>& stateField)
41{
42 using namespace pldm::responder::pdr;
43 using namespace pldm::utils;
44 using StateSetNum = uint8_t;
45
46 state_effecter_possible_states* states = nullptr;
47 pldm_state_effecter_pdr* pdr = nullptr;
48 uint8_t compEffecterCnt = stateField.size();
49
50 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
51 pldm_pdr_init(), pldm_pdr_destroy);
Andrew Jefferyacb20292023-06-30 11:47:44 +093052 if (!stateEffecterPdrRepo)
53 {
54 throw std::runtime_error(
55 "Failed to instantiate state effecter PDR repository");
56 }
Brad Bishop5079ac42021-08-19 18:35:06 -040057 pldm::responder::pdr_utils::Repo stateEffecterPDRs(
58 stateEffecterPdrRepo.get());
George Liu0d7aca82020-03-30 15:01:36 +080059 getRepoByType(handler.getRepo(), stateEffecterPDRs,
60 PLDM_STATE_EFFECTER_PDR);
61 if (stateEffecterPDRs.empty())
62 {
Riya Dixit49cfb132023-03-02 04:26:53 -060063 error("Failed to get record by PDR type");
George Liu0d7aca82020-03-30 15:01:36 +080064 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
65 }
66
Brad Bishop5079ac42021-08-19 18:35:06 -040067 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
George Liu0d7aca82020-03-30 15:01:36 +080068 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
69 while (pdrRecord)
70 {
71 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
72 if (pdr->effecter_id != effecterId)
73 {
74 pdr = nullptr;
75 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
76 continue;
77 }
78
79 states = reinterpret_cast<state_effecter_possible_states*>(
80 pdr->possible_states);
81 if (compEffecterCnt > pdr->composite_effecter_count)
82 {
Riya Dixit49cfb132023-03-02 04:26:53 -060083 error(
84 "The requester sent wrong composite effecter count for the effecter, EFFECTER_ID={EFFECTER_ID} COMP_EFF_CNT={COMP_EFF_CNT}",
85 "EFFECTER_ID", effecterId, "COMP_EFF_CNT", compEffecterCnt);
George Liu0d7aca82020-03-30 15:01:36 +080086 return PLDM_ERROR_INVALID_DATA;
87 }
88 break;
89 }
90
91 if (!pdr)
92 {
93 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
94 }
95
96 int rc = PLDM_SUCCESS;
97 try
98 {
Patrick Williams6da4f912023-05-10 07:50:53 -050099 const auto& [dbusMappings,
100 dbusValMaps] = handler.getDbusObjMaps(effecterId);
Manojkiran Eda3daf7a12024-04-17 20:33:44 +0530101 if (dbusMappings.empty() || dbusValMaps.empty())
102 {
103 error("dbusMappings for effecter id : {EFFECTER_ID} is missing",
104 "EFFECTER_ID", effecterId);
105 return PLDM_ERROR;
106 }
107
108 for (uint8_t currState = 0;
109 currState < compEffecterCnt && currState < dbusMappings.size() &&
110 currState < dbusValMaps.size();
111 ++currState)
George Liu0d7aca82020-03-30 15:01:36 +0800112 {
113 std::vector<StateSetNum> allowed{};
114 // computation is based on table 79 from DSP0248 v1.1.1
115 uint8_t bitfieldIndex = stateField[currState].effecter_state / 8;
Patrick Williams6da4f912023-05-10 07:50:53 -0500116 uint8_t bit = stateField[currState].effecter_state -
117 (8 * bitfieldIndex);
George Liu0d7aca82020-03-30 15:01:36 +0800118 if (states->possible_states_size < bitfieldIndex ||
119 !(states->states[bitfieldIndex].byte & (1 << bit)))
120 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600121 error(
122 "Invalid state set value, EFFECTER_ID={EFFECTER_ID} VALUE={EFFECTER_STATE} COMPOSITE_EFFECTER_ID={CURR_STATE} DBUS_PATH={DBUS_OBJ_PATH}",
123 "EFFECTER_ID", effecterId, "EFFECTER_STATE",
124 stateField[currState].effecter_state, "CURR_STATE",
125 currState, "DBUS_OBJ_PATH",
126 dbusMappings[currState].objectPath.c_str());
George Liu0d7aca82020-03-30 15:01:36 +0800127 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
128 break;
129 }
130 const DBusMapping& dbusMapping = dbusMappings[currState];
Brad Bishop5079ac42021-08-19 18:35:06 -0400131 const pldm::responder::pdr_utils::StatestoDbusVal& dbusValToMap =
132 dbusValMaps[currState];
George Liu0d7aca82020-03-30 15:01:36 +0800133
134 if (stateField[currState].set_request == PLDM_REQUEST_SET)
135 {
136 try
137 {
138 dBusIntf.setDbusProperty(
139 dbusMapping,
140 dbusValToMap.at(stateField[currState].effecter_state));
141 }
142 catch (const std::exception& e)
143 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600144 error(
145 "Error setting property, ERROR={ERR_EXCEP} PROPERTY={DBUS_PROP} INTERFACE={DBUS_INTF} PATH={DBUS_OBJ_PATH}",
146 "ERR_EXCEP", e.what(), "DBUS_PROP",
147 dbusMapping.propertyName, "DBUS_INTF",
148 dbusMapping.interface, "DBUS_OBJ_PATH",
149 dbusMapping.objectPath.c_str());
George Liu0d7aca82020-03-30 15:01:36 +0800150 return PLDM_ERROR;
151 }
152 }
153 uint8_t* nextState =
154 reinterpret_cast<uint8_t*>(states) +
155 sizeof(state_effecter_possible_states) -
156 sizeof(states->states) +
157 (states->possible_states_size * sizeof(states->states));
158 states =
159 reinterpret_cast<state_effecter_possible_states*>(nextState);
160 }
161 }
162 catch (const std::out_of_range& e)
163 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600164 error("Unknown effecter ID : {EFFECTER_ID} {ERR_EXCEP}", "EFFECTER_ID",
165 effecterId, "ERR_EXCEP", e.what());
George Liubd5e2ea2021-04-22 20:33:06 +0800166 return PLDM_ERROR;
George Liu0d7aca82020-03-30 15:01:36 +0800167 }
168
169 return rc;
170}
171
172} // namespace platform_state_effecter
173} // namespace responder
174} // namespace pldm