blob: b44d4463c96c1ccf2d07d78238aaeaf802c1c9fc [file] [log] [blame]
George Liu0d7aca82020-03-30 15:01:36 +08001#pragma once
2
3#include "config.h"
4
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05005#include "common/utils.hpp"
George Liu0d7aca82020-03-30 15:01:36 +08006#include "libpldmresponder/pdr.hpp"
7#include "pdr_utils.hpp"
Deepak Kodihalli1521f6d2020-06-16 08:51:02 -05008#include "pldmd/handler.hpp"
George Liu0d7aca82020-03-30 15:01:36 +08009
George Liuc453e162022-12-21 17:16:23 +080010#include <libpldm/platform.h>
11#include <libpldm/states.h>
12
Riya Dixit49cfb132023-03-02 04:26:53 -060013#include <phosphor-logging/lg2.hpp>
14
George Liu0d7aca82020-03-30 15:01:36 +080015#include <cstdint>
16#include <map>
17
Riya Dixit49cfb132023-03-02 04:26:53 -060018PHOSPHOR_LOG2_USING;
19
George Liu0d7aca82020-03-30 15:01:36 +080020namespace pldm
21{
22namespace responder
23{
24namespace platform_state_effecter
25{
26/** @brief Function to set the effecter requested by pldm requester
27 *
28 * @tparam[in] DBusInterface - DBus interface type
29 * @tparam[in] Handler - pldm::responder::platform::Handler
30 * @param[in] dBusIntf - The interface object of DBusInterface
31 * @param[in] handler - The interface object of
32 * pldm::responder::platform::Handler
33 * @param[in] effecterId - Effecter ID sent by the requester to act on
34 * @param[in] stateField - The state field data for each of the states,
35 * equal to composite effecter count in number
36 * @return - Success or failure in setting the states. Returns failure in
37 * terms of PLDM completion codes if atleast one state fails to be set
38 */
39template <class DBusInterface, class Handler>
40int setStateEffecterStatesHandler(
41 const DBusInterface& dBusIntf, Handler& handler, uint16_t effecterId,
42 const std::vector<set_effecter_state_field>& stateField)
43{
44 using namespace pldm::responder::pdr;
45 using namespace pldm::utils;
46 using StateSetNum = uint8_t;
47
48 state_effecter_possible_states* states = nullptr;
49 pldm_state_effecter_pdr* pdr = nullptr;
50 uint8_t compEffecterCnt = stateField.size();
51
52 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo(
53 pldm_pdr_init(), pldm_pdr_destroy);
Brad Bishop5079ac42021-08-19 18:35:06 -040054 pldm::responder::pdr_utils::Repo stateEffecterPDRs(
55 stateEffecterPdrRepo.get());
George Liu0d7aca82020-03-30 15:01:36 +080056 getRepoByType(handler.getRepo(), stateEffecterPDRs,
57 PLDM_STATE_EFFECTER_PDR);
58 if (stateEffecterPDRs.empty())
59 {
Riya Dixit49cfb132023-03-02 04:26:53 -060060 error("Failed to get record by PDR type");
George Liu0d7aca82020-03-30 15:01:36 +080061 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
62 }
63
Brad Bishop5079ac42021-08-19 18:35:06 -040064 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
George Liu0d7aca82020-03-30 15:01:36 +080065 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
66 while (pdrRecord)
67 {
68 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
69 if (pdr->effecter_id != effecterId)
70 {
71 pdr = nullptr;
72 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
73 continue;
74 }
75
76 states = reinterpret_cast<state_effecter_possible_states*>(
77 pdr->possible_states);
78 if (compEffecterCnt > pdr->composite_effecter_count)
79 {
Riya Dixit49cfb132023-03-02 04:26:53 -060080 error(
81 "The requester sent wrong composite effecter count for the effecter, EFFECTER_ID={EFFECTER_ID} COMP_EFF_CNT={COMP_EFF_CNT}",
82 "EFFECTER_ID", effecterId, "COMP_EFF_CNT", compEffecterCnt);
George Liu0d7aca82020-03-30 15:01:36 +080083 return PLDM_ERROR_INVALID_DATA;
84 }
85 break;
86 }
87
88 if (!pdr)
89 {
90 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
91 }
92
93 int rc = PLDM_SUCCESS;
94 try
95 {
Patrick Williams6da4f912023-05-10 07:50:53 -050096 const auto& [dbusMappings,
97 dbusValMaps] = handler.getDbusObjMaps(effecterId);
George Liu0d7aca82020-03-30 15:01:36 +080098 for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
99 {
100 std::vector<StateSetNum> allowed{};
101 // computation is based on table 79 from DSP0248 v1.1.1
102 uint8_t bitfieldIndex = stateField[currState].effecter_state / 8;
Patrick Williams6da4f912023-05-10 07:50:53 -0500103 uint8_t bit = stateField[currState].effecter_state -
104 (8 * bitfieldIndex);
George Liu0d7aca82020-03-30 15:01:36 +0800105 if (states->possible_states_size < bitfieldIndex ||
106 !(states->states[bitfieldIndex].byte & (1 << bit)))
107 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600108 error(
109 "Invalid state set value, EFFECTER_ID={EFFECTER_ID} VALUE={EFFECTER_STATE} COMPOSITE_EFFECTER_ID={CURR_STATE} DBUS_PATH={DBUS_OBJ_PATH}",
110 "EFFECTER_ID", effecterId, "EFFECTER_STATE",
111 stateField[currState].effecter_state, "CURR_STATE",
112 currState, "DBUS_OBJ_PATH",
113 dbusMappings[currState].objectPath.c_str());
George Liu0d7aca82020-03-30 15:01:36 +0800114 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
115 break;
116 }
117 const DBusMapping& dbusMapping = dbusMappings[currState];
Brad Bishop5079ac42021-08-19 18:35:06 -0400118 const pldm::responder::pdr_utils::StatestoDbusVal& dbusValToMap =
119 dbusValMaps[currState];
George Liu0d7aca82020-03-30 15:01:36 +0800120
121 if (stateField[currState].set_request == PLDM_REQUEST_SET)
122 {
123 try
124 {
125 dBusIntf.setDbusProperty(
126 dbusMapping,
127 dbusValToMap.at(stateField[currState].effecter_state));
128 }
129 catch (const std::exception& e)
130 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600131 error(
132 "Error setting property, ERROR={ERR_EXCEP} PROPERTY={DBUS_PROP} INTERFACE={DBUS_INTF} PATH={DBUS_OBJ_PATH}",
133 "ERR_EXCEP", e.what(), "DBUS_PROP",
134 dbusMapping.propertyName, "DBUS_INTF",
135 dbusMapping.interface, "DBUS_OBJ_PATH",
136 dbusMapping.objectPath.c_str());
George Liu0d7aca82020-03-30 15:01:36 +0800137 return PLDM_ERROR;
138 }
139 }
140 uint8_t* nextState =
141 reinterpret_cast<uint8_t*>(states) +
142 sizeof(state_effecter_possible_states) -
143 sizeof(states->states) +
144 (states->possible_states_size * sizeof(states->states));
145 states =
146 reinterpret_cast<state_effecter_possible_states*>(nextState);
147 }
148 }
149 catch (const std::out_of_range& e)
150 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600151 error("Unknown effecter ID : {EFFECTER_ID} {ERR_EXCEP}", "EFFECTER_ID",
152 effecterId, "ERR_EXCEP", e.what());
George Liubd5e2ea2021-04-22 20:33:06 +0800153 return PLDM_ERROR;
George Liu0d7aca82020-03-30 15:01:36 +0800154 }
155
156 return rc;
157}
158
159} // namespace platform_state_effecter
160} // namespace responder
161} // namespace pldm