blob: 9c8860efab5cf669afa6a0dfd8c3dcf3a3e4adbd [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
27using EffecterId = uint16_t;
28using DbusMappings = std::vector<DBusMapping>;
29using DbusValMaps = std::vector<StatestoDbusVal>;
30using DbusObjMaps = std::map<EffecterId, std::tuple<DbusMappings, DbusValMaps>>;
Deepak Kodihallic682fe22020-03-04 00:42:54 -060031
Deepak Kodihallibc669f12019-11-28 08:52:07 -060032class Handler : public CmdHandler
Sampa Misraa2fa0702019-05-31 01:28:55 -050033{
Deepak Kodihallibc669f12019-11-28 08:52:07 -060034 public:
Deepak Kodihallic682fe22020-03-04 00:42:54 -060035 Handler(const std::string& dir, pldm_pdr* repo) : pdrRepo(repo)
Sampa Misraa2fa0702019-05-31 01:28:55 -050036 {
Deepak Kodihallic682fe22020-03-04 00:42:54 -060037 generate(dir, pdrRepo);
38
Deepak Kodihallibc669f12019-11-28 08:52:07 -060039 handlers.emplace(PLDM_GET_PDR,
40 [this](const pldm_msg* request, size_t payloadLength) {
41 return this->getPDR(request, payloadLength);
42 });
43 handlers.emplace(PLDM_SET_STATE_EFFECTER_STATES,
44 [this](const pldm_msg* request, size_t payloadLength) {
45 return this->setStateEffecterStates(request,
46 payloadLength);
47 });
Sampa Misraa2fa0702019-05-31 01:28:55 -050048 }
49
George Liu1ec85d42020-02-12 16:05:32 +080050 pdr_utils::Repo& getRepo()
Deepak Kodihallic682fe22020-03-04 00:42:54 -060051 {
George Liu1ec85d42020-02-12 16:05:32 +080052 return this->pdrRepo;
Deepak Kodihallic682fe22020-03-04 00:42:54 -060053 }
54
George Liu1ec85d42020-02-12 16:05:32 +080055 /** @brief Add D-Bus mapping and value mapping(stateId to D-Bus) for the
56 * effecterId. If the same id is added, the previous dbusObjs will
57 * be "over-written".
58 *
59 * @param[in] effecterId - effecter id
60 * @param[in] dbusObj - list of D-Bus object structure and list of D-Bus
61 * property value to attribute value
62 */
63 void addDbusObjMaps(uint16_t effecterId,
64 std::tuple<DbusMappings, DbusValMaps> dbusObj);
65
66 /** @brief Retrieve an effecter id -> D-Bus objects mapping
67 *
68 * @param[in] effecterId - effecter id
69 *
70 * @return std::tuple<DbusMappings, DbusValMaps> - list of D-Bus object
71 * structure and list of D-Bus property value to attribute value
72 */
73 const std::tuple<DbusMappings, DbusValMaps>&
74 getDbusObjMaps(uint16_t effecterId) const;
Deepak Kodihallic682fe22020-03-04 00:42:54 -060075
76 uint16_t getNextEffecterId()
77 {
78 return ++nextEffecterId;
79 }
80
81 /** @brief Parse PDR JSONs and build PDR repository
82 *
83 * @param[in] dir - directory housing platform specific PDR JSON files
84 * @param[in] repo - instance of concrete implementation of Repo
85 */
86 void generate(const std::string& dir, Repo& repo);
87
88 /** @brief Parse PDR JSONs and build state effecter PDR repository
89 *
90 * @param[in] json - platform specific PDR JSON files
91 * @param[in] repo - instance of state effecter implementation of Repo
92 */
93 void generateStateEffecterRepo(const Json& json, Repo& repo);
94
Deepak Kodihallibc669f12019-11-28 08:52:07 -060095 /** @brief Handler for GetPDR
96 *
97 * @param[in] request - Request message payload
98 * @param[in] payloadLength - Request payload length
99 * @param[out] Response - Response message written here
100 */
101 Response getPDR(const pldm_msg* request, size_t payloadLength);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500102
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600103 /** @brief Handler for setStateEffecterStates
104 *
105 * @param[in] request - Request message
106 * @param[in] payloadLength - Request payload length
107 * @return Response - PLDM Response message
108 */
109 Response setStateEffecterStates(const pldm_msg* request,
110 size_t payloadLength);
111
112 /** @brief Function to set the effecter requested by pldm requester
113 * @param[in] dBusIntf - The interface object
114 * @param[in] effecterId - Effecter ID sent by the requester to act on
115 * @param[in] stateField - The state field data for each of the states,
116 * equal to composite effecter count in number
117 * @return - Success or failure in setting the states. Returns failure in
118 * terms of PLDM completion codes if atleast one state fails to be set
119 */
120 template <class DBusInterface>
121 int setStateEffecterStatesHandler(
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600122 const DBusInterface& dBusIntf, uint16_t effecterId,
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600123 const std::vector<set_effecter_state_field>& stateField)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500124 {
George Liue53193f2020-02-24 09:23:26 +0800125 using namespace pldm::responder::pdr;
George Liu1e44c732020-02-28 20:20:06 +0800126 using namespace pldm::utils;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600127 using StateSetNum = uint8_t;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600128
129 state_effecter_possible_states* states = nullptr;
130 pldm_state_effecter_pdr* pdr = nullptr;
131 uint8_t compEffecterCnt = stateField.size();
George Liu1ec85d42020-02-12 16:05:32 +0800132
133 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)>
134 stateEffecterPdrRepo(pldm_pdr_init(), pldm_pdr_destroy);
135 Repo stateEffecterPDRs(stateEffecterPdrRepo.get());
136 getRepoByType(pdrRepo, stateEffecterPDRs, PLDM_STATE_EFFECTER_PDR);
137 if (stateEffecterPDRs.empty())
138 {
139 std::cerr << "Failed to get record by PDR type\n";
140 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
141 }
142
George Liue53193f2020-02-24 09:23:26 +0800143 PdrEntry pdrEntry{};
George Liu1ec85d42020-02-12 16:05:32 +0800144 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
George Liue53193f2020-02-24 09:23:26 +0800145 while (pdrRecord)
146 {
147 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
148 if (pdr->effecter_id != effecterId)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500149 {
George Liue53193f2020-02-24 09:23:26 +0800150 pdr = nullptr;
George Liu1ec85d42020-02-12 16:05:32 +0800151 pdrRecord =
152 stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
George Liue53193f2020-02-24 09:23:26 +0800153 continue;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600154 }
George Liue53193f2020-02-24 09:23:26 +0800155
156 states = reinterpret_cast<state_effecter_possible_states*>(
157 pdr->possible_states);
158 if (compEffecterCnt > pdr->composite_effecter_count)
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600159 {
George Liue53193f2020-02-24 09:23:26 +0800160 std::cerr << "The requester sent wrong composite effecter"
161 << " count for the effecter, EFFECTER_ID="
162 << effecterId << "COMP_EFF_CNT=" << compEffecterCnt
163 << "\n";
164 return PLDM_ERROR_INVALID_DATA;
Sampa Misraa2fa0702019-05-31 01:28:55 -0500165 }
George Liue53193f2020-02-24 09:23:26 +0800166 break;
167 }
168
169 if (!pdr)
170 {
171 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
Sampa Misraa2fa0702019-05-31 01:28:55 -0500172 }
Sampa Misraa2fa0702019-05-31 01:28:55 -0500173
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600174 int rc = PLDM_SUCCESS;
George Liu1ec85d42020-02-12 16:05:32 +0800175 try
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600176 {
George Liu1ec85d42020-02-12 16:05:32 +0800177 const auto& [dbusMappings, dbusValMaps] =
178 dbusObjMaps.at(effecterId);
179 for (uint8_t currState = 0; currState < compEffecterCnt;
180 ++currState)
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600181 {
George Liu1ec85d42020-02-12 16:05:32 +0800182 std::vector<StateSetNum> allowed{};
183 // computation is based on table 79 from DSP0248 v1.1.1
184 uint8_t bitfieldIndex =
185 stateField[currState].effecter_state / 8;
186 uint8_t bit =
187 stateField[currState].effecter_state - (8 * bitfieldIndex);
188 if (states->possible_states_size < bitfieldIndex ||
189 !(states->states[bitfieldIndex].byte & (1 << bit)))
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600190 {
George Liu1ec85d42020-02-12 16:05:32 +0800191 std::cerr
192 << "Invalid state set value, EFFECTER_ID=" << effecterId
193 << " VALUE=" << stateField[currState].effecter_state
194 << " COMPOSITE_EFFECTER_ID=" << currState
195 << " DBUS_PATH=" << dbusMappings[currState].objectPath
196 << "\n";
197 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600198 break;
199 }
George Liu1ec85d42020-02-12 16:05:32 +0800200 const DBusMapping& dbusMapping = dbusMappings[currState];
201 const StatestoDbusVal& dbusValToMap = dbusValMaps[currState];
202
203 if (stateField[currState].set_request == PLDM_REQUEST_SET)
204 {
205 try
206 {
207 dBusIntf.setDbusProperty(
208 dbusMapping,
209 dbusValToMap.at(
210 stateField[currState].effecter_state));
211 }
212 catch (const std::exception& e)
213 {
214 std::cerr
215 << "Error setting property, ERROR=" << e.what()
216 << " PROPERTY=" << dbusMapping.propertyName
217 << " INTERFACE="
218 << dbusMapping.interface << " PATH="
219 << dbusMapping.objectPath << "\n";
220 return PLDM_ERROR;
221 }
222 }
223 uint8_t* nextState =
224 reinterpret_cast<uint8_t*>(states) +
225 sizeof(state_effecter_possible_states) -
226 sizeof(states->states) +
227 (states->possible_states_size * sizeof(states->states));
228 states = reinterpret_cast<state_effecter_possible_states*>(
229 nextState);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600230 }
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600231 }
George Liu1ec85d42020-02-12 16:05:32 +0800232 catch (const std::out_of_range& e)
233 {
234 std::cerr << "the effecterId does not exist. effecter id: "
235 << effecterId << e.what() << '\n';
236 }
237
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600238 return rc;
239 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600240
241 private:
242 pdr_utils::Repo pdrRepo;
243 uint16_t nextEffecterId{};
George Liu1ec85d42020-02-12 16:05:32 +0800244 DbusObjMaps dbusObjMaps{};
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600245};
246
247} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530248} // namespace responder
249} // namespace pldm