blob: 75a1ad33c5570bb5cba6df93305246959933728d [file] [log] [blame]
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05301#pragma once
2
Sampa Misraa2fa0702019-05-31 01:28:55 -05003#include "config.h"
4
Deepak Kodihallibc669f12019-11-28 08:52:07 -06005#include "handler.hpp"
Sampa Misraa2fa0702019-05-31 01:28:55 -05006#include "libpldmresponder/pdr.hpp"
George Liue53193f2020-02-24 09:23:26 +08007#include "libpldmresponder/pdr_utils.hpp"
George Liu83409572019-12-24 18:42:54 +08008#include "utils.hpp"
Sampa Misraa2fa0702019-05-31 01:28:55 -05009
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053010#include <stdint.h>
11
Sampa Misraa2fa0702019-05-31 01:28:55 -050012#include <map>
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053013
14#include "libpldm/platform.h"
Sampa Misraa2fa0702019-05-31 01:28:55 -050015#include "libpldm/states.h"
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053016
17namespace pldm
18{
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053019namespace responder
20{
Sampa Misraa2fa0702019-05-31 01:28:55 -050021namespace platform
22{
23
George Liu1ec85d42020-02-12 16:05:32 +080024using namespace pldm::utils;
25using namespace pldm::responder::pdr_utils;
26
George Liua2870722020-02-11 11:09:30 +080027using generatePDR =
28 std::function<void(const Json& json, pdr_utils::RepoInterface& repo)>;
29
George Liu1ec85d42020-02-12 16:05:32 +080030using EffecterId = uint16_t;
George Liua2870722020-02-11 11:09:30 +080031using DbusObjMaps =
32 std::map<EffecterId,
33 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>>;
Deepak Kodihallic682fe22020-03-04 00:42:54 -060034
Deepak Kodihallibc669f12019-11-28 08:52:07 -060035class Handler : public CmdHandler
Sampa Misraa2fa0702019-05-31 01:28:55 -050036{
Deepak Kodihallibc669f12019-11-28 08:52:07 -060037 public:
Deepak Kodihallic682fe22020-03-04 00:42:54 -060038 Handler(const std::string& dir, pldm_pdr* repo) : pdrRepo(repo)
Sampa Misraa2fa0702019-05-31 01:28:55 -050039 {
Deepak Kodihallic682fe22020-03-04 00:42:54 -060040 generate(dir, pdrRepo);
41
Deepak Kodihallibc669f12019-11-28 08:52:07 -060042 handlers.emplace(PLDM_GET_PDR,
43 [this](const pldm_msg* request, size_t payloadLength) {
44 return this->getPDR(request, payloadLength);
45 });
46 handlers.emplace(PLDM_SET_STATE_EFFECTER_STATES,
47 [this](const pldm_msg* request, size_t payloadLength) {
48 return this->setStateEffecterStates(request,
49 payloadLength);
50 });
Sampa Misraa2fa0702019-05-31 01:28:55 -050051 }
52
George Liu1ec85d42020-02-12 16:05:32 +080053 pdr_utils::Repo& getRepo()
Deepak Kodihallic682fe22020-03-04 00:42:54 -060054 {
George Liu1ec85d42020-02-12 16:05:32 +080055 return this->pdrRepo;
Deepak Kodihallic682fe22020-03-04 00:42:54 -060056 }
57
George Liu1ec85d42020-02-12 16:05:32 +080058 /** @brief Add D-Bus mapping and value mapping(stateId to D-Bus) for the
59 * effecterId. If the same id is added, the previous dbusObjs will
60 * be "over-written".
61 *
62 * @param[in] effecterId - effecter id
63 * @param[in] dbusObj - list of D-Bus object structure and list of D-Bus
64 * property value to attribute value
65 */
George Liua2870722020-02-11 11:09:30 +080066 void addDbusObjMaps(
67 uint16_t effecterId,
68 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj);
George Liu1ec85d42020-02-12 16:05:32 +080069
70 /** @brief Retrieve an effecter id -> D-Bus objects mapping
71 *
72 * @param[in] effecterId - effecter id
73 *
George Liua2870722020-02-11 11:09:30 +080074 * @return std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> -
75 * list of D-Bus object structure and list of D-Bus property value
76 * to attribute value
George Liu1ec85d42020-02-12 16:05:32 +080077 */
George Liua2870722020-02-11 11:09:30 +080078 const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
George Liu1ec85d42020-02-12 16:05:32 +080079 getDbusObjMaps(uint16_t effecterId) const;
Deepak Kodihallic682fe22020-03-04 00:42:54 -060080
81 uint16_t getNextEffecterId()
82 {
83 return ++nextEffecterId;
84 }
85
86 /** @brief Parse PDR JSONs and build PDR repository
87 *
88 * @param[in] dir - directory housing platform specific PDR JSON files
89 * @param[in] repo - instance of concrete implementation of Repo
90 */
91 void generate(const std::string& dir, Repo& repo);
92
93 /** @brief Parse PDR JSONs and build state effecter PDR repository
94 *
95 * @param[in] json - platform specific PDR JSON files
96 * @param[in] repo - instance of state effecter implementation of Repo
97 */
98 void generateStateEffecterRepo(const Json& json, Repo& repo);
99
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600100 /** @brief Handler for GetPDR
101 *
102 * @param[in] request - Request message payload
103 * @param[in] payloadLength - Request payload length
104 * @param[out] Response - Response message written here
105 */
106 Response getPDR(const pldm_msg* request, size_t payloadLength);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500107
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600108 /** @brief Handler for setStateEffecterStates
109 *
110 * @param[in] request - Request message
111 * @param[in] payloadLength - Request payload length
112 * @return Response - PLDM Response message
113 */
114 Response setStateEffecterStates(const pldm_msg* request,
115 size_t payloadLength);
116
117 /** @brief Function to set the effecter requested by pldm requester
118 * @param[in] dBusIntf - The interface object
119 * @param[in] effecterId - Effecter ID sent by the requester to act on
120 * @param[in] stateField - The state field data for each of the states,
121 * equal to composite effecter count in number
122 * @return - Success or failure in setting the states. Returns failure in
123 * terms of PLDM completion codes if atleast one state fails to be set
124 */
125 template <class DBusInterface>
126 int setStateEffecterStatesHandler(
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600127 const DBusInterface& dBusIntf, uint16_t effecterId,
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600128 const std::vector<set_effecter_state_field>& stateField)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500129 {
George Liue53193f2020-02-24 09:23:26 +0800130 using namespace pldm::responder::pdr;
George Liu1e44c732020-02-28 20:20:06 +0800131 using namespace pldm::utils;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600132 using StateSetNum = uint8_t;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600133
134 state_effecter_possible_states* states = nullptr;
135 pldm_state_effecter_pdr* pdr = nullptr;
136 uint8_t compEffecterCnt = stateField.size();
George Liu1ec85d42020-02-12 16:05:32 +0800137
138 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)>
139 stateEffecterPdrRepo(pldm_pdr_init(), pldm_pdr_destroy);
140 Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
141 getRepoByType(pdrRepo, stateEffecterPDRs, PLDM_STATE_EFFECTER_PDR);
142 if (stateEffecterPDRs.empty())
143 {
144 std::cerr << "Failed to get record by PDR type\n";
145 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
146 }
147
George Liue53193f2020-02-24 09:23:26 +0800148 PdrEntry pdrEntry{};
George Liu1ec85d42020-02-12 16:05:32 +0800149 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
George Liue53193f2020-02-24 09:23:26 +0800150 while (pdrRecord)
151 {
152 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
153 if (pdr->effecter_id != effecterId)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500154 {
George Liue53193f2020-02-24 09:23:26 +0800155 pdr = nullptr;
George Liu1ec85d42020-02-12 16:05:32 +0800156 pdrRecord =
157 stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
George Liue53193f2020-02-24 09:23:26 +0800158 continue;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600159 }
George Liue53193f2020-02-24 09:23:26 +0800160
161 states = reinterpret_cast<state_effecter_possible_states*>(
162 pdr->possible_states);
163 if (compEffecterCnt > pdr->composite_effecter_count)
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600164 {
George Liue53193f2020-02-24 09:23:26 +0800165 std::cerr << "The requester sent wrong composite effecter"
166 << " count for the effecter, EFFECTER_ID="
167 << effecterId << "COMP_EFF_CNT=" << compEffecterCnt
168 << "\n";
169 return PLDM_ERROR_INVALID_DATA;
Sampa Misraa2fa0702019-05-31 01:28:55 -0500170 }
George Liue53193f2020-02-24 09:23:26 +0800171 break;
172 }
173
174 if (!pdr)
175 {
176 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
Sampa Misraa2fa0702019-05-31 01:28:55 -0500177 }
Sampa Misraa2fa0702019-05-31 01:28:55 -0500178
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600179 int rc = PLDM_SUCCESS;
George Liu1ec85d42020-02-12 16:05:32 +0800180 try
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600181 {
George Liu1ec85d42020-02-12 16:05:32 +0800182 const auto& [dbusMappings, dbusValMaps] =
183 dbusObjMaps.at(effecterId);
184 for (uint8_t currState = 0; currState < compEffecterCnt;
185 ++currState)
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600186 {
George Liu1ec85d42020-02-12 16:05:32 +0800187 std::vector<StateSetNum> allowed{};
188 // computation is based on table 79 from DSP0248 v1.1.1
189 uint8_t bitfieldIndex =
190 stateField[currState].effecter_state / 8;
191 uint8_t bit =
192 stateField[currState].effecter_state - (8 * bitfieldIndex);
193 if (states->possible_states_size < bitfieldIndex ||
194 !(states->states[bitfieldIndex].byte & (1 << bit)))
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600195 {
George Liu1ec85d42020-02-12 16:05:32 +0800196 std::cerr
197 << "Invalid state set value, EFFECTER_ID=" << effecterId
198 << " VALUE=" << stateField[currState].effecter_state
199 << " COMPOSITE_EFFECTER_ID=" << currState
200 << " DBUS_PATH=" << dbusMappings[currState].objectPath
201 << "\n";
202 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600203 break;
204 }
George Liu1ec85d42020-02-12 16:05:32 +0800205 const DBusMapping& dbusMapping = dbusMappings[currState];
206 const StatestoDbusVal& dbusValToMap = dbusValMaps[currState];
207
208 if (stateField[currState].set_request == PLDM_REQUEST_SET)
209 {
210 try
211 {
212 dBusIntf.setDbusProperty(
213 dbusMapping,
214 dbusValToMap.at(
215 stateField[currState].effecter_state));
216 }
217 catch (const std::exception& e)
218 {
219 std::cerr
220 << "Error setting property, ERROR=" << e.what()
221 << " PROPERTY=" << dbusMapping.propertyName
222 << " INTERFACE="
223 << dbusMapping.interface << " PATH="
224 << dbusMapping.objectPath << "\n";
225 return PLDM_ERROR;
226 }
227 }
228 uint8_t* nextState =
229 reinterpret_cast<uint8_t*>(states) +
230 sizeof(state_effecter_possible_states) -
231 sizeof(states->states) +
232 (states->possible_states_size * sizeof(states->states));
233 states = reinterpret_cast<state_effecter_possible_states*>(
234 nextState);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600235 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600236 }
George Liu1ec85d42020-02-12 16:05:32 +0800237 catch (const std::out_of_range& e)
238 {
239 std::cerr << "the effecterId does not exist. effecter id: "
240 << effecterId << e.what() << '\n';
241 }
242
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600243 return rc;
244 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600245
246 private:
247 pdr_utils::Repo pdrRepo;
248 uint16_t nextEffecterId{};
George Liu1ec85d42020-02-12 16:05:32 +0800249 DbusObjMaps dbusObjMaps{};
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600250};
251
252} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530253} // namespace responder
254} // namespace pldm