blob: cfcd539b5205db78b4d2053fe7bce33d98d791b9 [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);
Brad Bishop5079ac42021-08-19 18:35:06 -040052 pldm::responder::pdr_utils::Repo stateEffecterPDRs(
53 stateEffecterPdrRepo.get());
George Liu0d7aca82020-03-30 15:01:36 +080054 getRepoByType(handler.getRepo(), stateEffecterPDRs,
55 PLDM_STATE_EFFECTER_PDR);
56 if (stateEffecterPDRs.empty())
57 {
Riya Dixit49cfb132023-03-02 04:26:53 -060058 error("Failed to get record by PDR type");
George Liu0d7aca82020-03-30 15:01:36 +080059 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
60 }
61
Brad Bishop5079ac42021-08-19 18:35:06 -040062 pldm::responder::pdr_utils::PdrEntry pdrEntry{};
George Liu0d7aca82020-03-30 15:01:36 +080063 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry);
64 while (pdrRecord)
65 {
66 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
67 if (pdr->effecter_id != effecterId)
68 {
69 pdr = nullptr;
70 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry);
71 continue;
72 }
73
74 states = reinterpret_cast<state_effecter_possible_states*>(
75 pdr->possible_states);
76 if (compEffecterCnt > pdr->composite_effecter_count)
77 {
Riya Dixit49cfb132023-03-02 04:26:53 -060078 error(
79 "The requester sent wrong composite effecter count for the effecter, EFFECTER_ID={EFFECTER_ID} COMP_EFF_CNT={COMP_EFF_CNT}",
80 "EFFECTER_ID", effecterId, "COMP_EFF_CNT", compEffecterCnt);
George Liu0d7aca82020-03-30 15:01:36 +080081 return PLDM_ERROR_INVALID_DATA;
82 }
83 break;
84 }
85
86 if (!pdr)
87 {
88 return PLDM_PLATFORM_INVALID_EFFECTER_ID;
89 }
90
91 int rc = PLDM_SUCCESS;
92 try
93 {
Patrick Williams6da4f912023-05-10 07:50:53 -050094 const auto& [dbusMappings,
95 dbusValMaps] = handler.getDbusObjMaps(effecterId);
George Liu0d7aca82020-03-30 15:01:36 +080096 for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
97 {
98 std::vector<StateSetNum> allowed{};
99 // computation is based on table 79 from DSP0248 v1.1.1
100 uint8_t bitfieldIndex = stateField[currState].effecter_state / 8;
Patrick Williams6da4f912023-05-10 07:50:53 -0500101 uint8_t bit = stateField[currState].effecter_state -
102 (8 * bitfieldIndex);
George Liu0d7aca82020-03-30 15:01:36 +0800103 if (states->possible_states_size < bitfieldIndex ||
104 !(states->states[bitfieldIndex].byte & (1 << bit)))
105 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600106 error(
107 "Invalid state set value, EFFECTER_ID={EFFECTER_ID} VALUE={EFFECTER_STATE} COMPOSITE_EFFECTER_ID={CURR_STATE} DBUS_PATH={DBUS_OBJ_PATH}",
108 "EFFECTER_ID", effecterId, "EFFECTER_STATE",
109 stateField[currState].effecter_state, "CURR_STATE",
110 currState, "DBUS_OBJ_PATH",
111 dbusMappings[currState].objectPath.c_str());
George Liu0d7aca82020-03-30 15:01:36 +0800112 rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
113 break;
114 }
115 const DBusMapping& dbusMapping = dbusMappings[currState];
Brad Bishop5079ac42021-08-19 18:35:06 -0400116 const pldm::responder::pdr_utils::StatestoDbusVal& dbusValToMap =
117 dbusValMaps[currState];
George Liu0d7aca82020-03-30 15:01:36 +0800118
119 if (stateField[currState].set_request == PLDM_REQUEST_SET)
120 {
121 try
122 {
123 dBusIntf.setDbusProperty(
124 dbusMapping,
125 dbusValToMap.at(stateField[currState].effecter_state));
126 }
127 catch (const std::exception& e)
128 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600129 error(
130 "Error setting property, ERROR={ERR_EXCEP} PROPERTY={DBUS_PROP} INTERFACE={DBUS_INTF} PATH={DBUS_OBJ_PATH}",
131 "ERR_EXCEP", e.what(), "DBUS_PROP",
132 dbusMapping.propertyName, "DBUS_INTF",
133 dbusMapping.interface, "DBUS_OBJ_PATH",
134 dbusMapping.objectPath.c_str());
George Liu0d7aca82020-03-30 15:01:36 +0800135 return PLDM_ERROR;
136 }
137 }
138 uint8_t* nextState =
139 reinterpret_cast<uint8_t*>(states) +
140 sizeof(state_effecter_possible_states) -
141 sizeof(states->states) +
142 (states->possible_states_size * sizeof(states->states));
143 states =
144 reinterpret_cast<state_effecter_possible_states*>(nextState);
145 }
146 }
147 catch (const std::out_of_range& e)
148 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600149 error("Unknown effecter ID : {EFFECTER_ID} {ERR_EXCEP}", "EFFECTER_ID",
150 effecterId, "ERR_EXCEP", e.what());
George Liubd5e2ea2021-04-22 20:33:06 +0800151 return PLDM_ERROR;
George Liu0d7aca82020-03-30 15:01:36 +0800152 }
153
154 return rc;
155}
156
157} // namespace platform_state_effecter
158} // namespace responder
159} // namespace pldm