10d7aca8cSGeorge Liu #pragma once 20d7aca8cSGeorge Liu 3d130e1a3SDeepak Kodihalli #include "common/utils.hpp" 40d7aca8cSGeorge Liu #include "libpldmresponder/pdr.hpp" 50d7aca8cSGeorge Liu #include "pdr_utils.hpp" 61521f6d1SDeepak Kodihalli #include "pldmd/handler.hpp" 70d7aca8cSGeorge Liu 8c453e164SGeorge Liu #include <libpldm/platform.h> 9c453e164SGeorge Liu #include <libpldm/states.h> 10c453e164SGeorge Liu 1149cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp> 1249cfb138SRiya Dixit 130d7aca8cSGeorge Liu #include <cstdint> 140d7aca8cSGeorge Liu #include <map> 150d7aca8cSGeorge Liu 1649cfb138SRiya Dixit PHOSPHOR_LOG2_USING; 1749cfb138SRiya Dixit 180d7aca8cSGeorge Liu namespace pldm 190d7aca8cSGeorge Liu { 200d7aca8cSGeorge Liu namespace responder 210d7aca8cSGeorge Liu { 220d7aca8cSGeorge Liu namespace platform_state_effecter 230d7aca8cSGeorge Liu { 240d7aca8cSGeorge Liu /** @brief Function to set the effecter requested by pldm requester 250d7aca8cSGeorge Liu * 260d7aca8cSGeorge Liu * @tparam[in] DBusInterface - DBus interface type 270d7aca8cSGeorge Liu * @tparam[in] Handler - pldm::responder::platform::Handler 280d7aca8cSGeorge Liu * @param[in] dBusIntf - The interface object of DBusInterface 290d7aca8cSGeorge Liu * @param[in] handler - The interface object of 300d7aca8cSGeorge Liu * pldm::responder::platform::Handler 310d7aca8cSGeorge Liu * @param[in] effecterId - Effecter ID sent by the requester to act on 320d7aca8cSGeorge Liu * @param[in] stateField - The state field data for each of the states, 330d7aca8cSGeorge Liu * equal to composite effecter count in number 340d7aca8cSGeorge Liu * @return - Success or failure in setting the states. Returns failure in 350d7aca8cSGeorge Liu * terms of PLDM completion codes if atleast one state fails to be set 360d7aca8cSGeorge Liu */ 370d7aca8cSGeorge Liu template <class DBusInterface, class Handler> 380d7aca8cSGeorge Liu int setStateEffecterStatesHandler( 390d7aca8cSGeorge Liu const DBusInterface& dBusIntf, Handler& handler, uint16_t effecterId, 400d7aca8cSGeorge Liu const std::vector<set_effecter_state_field>& stateField) 410d7aca8cSGeorge Liu { 420d7aca8cSGeorge Liu using namespace pldm::responder::pdr; 430d7aca8cSGeorge Liu using namespace pldm::utils; 440d7aca8cSGeorge Liu using StateSetNum = uint8_t; 450d7aca8cSGeorge Liu 460d7aca8cSGeorge Liu state_effecter_possible_states* states = nullptr; 470d7aca8cSGeorge Liu pldm_state_effecter_pdr* pdr = nullptr; 480d7aca8cSGeorge Liu uint8_t compEffecterCnt = stateField.size(); 490d7aca8cSGeorge Liu 500d7aca8cSGeorge Liu std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo( 510d7aca8cSGeorge Liu pldm_pdr_init(), pldm_pdr_destroy); 52acb20299SAndrew Jeffery if (!stateEffecterPdrRepo) 53acb20299SAndrew Jeffery { 54acb20299SAndrew Jeffery throw std::runtime_error( 55acb20299SAndrew Jeffery "Failed to instantiate state effecter PDR repository"); 56acb20299SAndrew Jeffery } 575079ac4aSBrad Bishop pldm::responder::pdr_utils::Repo stateEffecterPDRs( 585079ac4aSBrad Bishop stateEffecterPdrRepo.get()); 590d7aca8cSGeorge Liu getRepoByType(handler.getRepo(), stateEffecterPDRs, 600d7aca8cSGeorge Liu PLDM_STATE_EFFECTER_PDR); 610d7aca8cSGeorge Liu if (stateEffecterPDRs.empty()) 620d7aca8cSGeorge Liu { 63*89644441SRiya Dixit error("Failed to get StateEffecterPDR record"); 640d7aca8cSGeorge Liu return PLDM_PLATFORM_INVALID_EFFECTER_ID; 650d7aca8cSGeorge Liu } 660d7aca8cSGeorge Liu 675079ac4aSBrad Bishop pldm::responder::pdr_utils::PdrEntry pdrEntry{}; 680d7aca8cSGeorge Liu auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry); 690d7aca8cSGeorge Liu while (pdrRecord) 700d7aca8cSGeorge Liu { 710d7aca8cSGeorge Liu pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data); 720d7aca8cSGeorge Liu if (pdr->effecter_id != effecterId) 730d7aca8cSGeorge Liu { 740d7aca8cSGeorge Liu pdr = nullptr; 750d7aca8cSGeorge Liu pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry); 760d7aca8cSGeorge Liu continue; 770d7aca8cSGeorge Liu } 780d7aca8cSGeorge Liu 790d7aca8cSGeorge Liu states = reinterpret_cast<state_effecter_possible_states*>( 800d7aca8cSGeorge Liu pdr->possible_states); 810d7aca8cSGeorge Liu if (compEffecterCnt > pdr->composite_effecter_count) 820d7aca8cSGeorge Liu { 8349cfb138SRiya Dixit error( 84*89644441SRiya Dixit "The requester sent wrong composite effecter count '{COMPOSITE_EFFECTER_COUNT}' for the effecter ID '{EFFECTERID}'", 85*89644441SRiya Dixit "EFFECTERID", effecterId, "COMPOSITE_EFFECTER_COUNT", 86*89644441SRiya Dixit compEffecterCnt); 870d7aca8cSGeorge Liu return PLDM_ERROR_INVALID_DATA; 880d7aca8cSGeorge Liu } 890d7aca8cSGeorge Liu break; 900d7aca8cSGeorge Liu } 910d7aca8cSGeorge Liu 920d7aca8cSGeorge Liu if (!pdr) 930d7aca8cSGeorge Liu { 940d7aca8cSGeorge Liu return PLDM_PLATFORM_INVALID_EFFECTER_ID; 950d7aca8cSGeorge Liu } 960d7aca8cSGeorge Liu 970d7aca8cSGeorge Liu int rc = PLDM_SUCCESS; 980d7aca8cSGeorge Liu try 990d7aca8cSGeorge Liu { 1006da4f91bSPatrick Williams const auto& [dbusMappings, 1016da4f91bSPatrick Williams dbusValMaps] = handler.getDbusObjMaps(effecterId); 1023daf7a1cSManojkiran Eda if (dbusMappings.empty() || dbusValMaps.empty()) 1033daf7a1cSManojkiran Eda { 104*89644441SRiya Dixit error("DbusMappings for effecter ID '{EFFECTER_ID}' is missing", 1053daf7a1cSManojkiran Eda "EFFECTER_ID", effecterId); 1063daf7a1cSManojkiran Eda return PLDM_ERROR; 1073daf7a1cSManojkiran Eda } 1083daf7a1cSManojkiran Eda 1093daf7a1cSManojkiran Eda for (uint8_t currState = 0; 1103daf7a1cSManojkiran Eda currState < compEffecterCnt && currState < dbusMappings.size() && 1113daf7a1cSManojkiran Eda currState < dbusValMaps.size(); 1123daf7a1cSManojkiran Eda ++currState) 1130d7aca8cSGeorge Liu { 1140d7aca8cSGeorge Liu std::vector<StateSetNum> allowed{}; 1150d7aca8cSGeorge Liu // computation is based on table 79 from DSP0248 v1.1.1 1160d7aca8cSGeorge Liu uint8_t bitfieldIndex = stateField[currState].effecter_state / 8; 1176da4f91bSPatrick Williams uint8_t bit = stateField[currState].effecter_state - 1186da4f91bSPatrick Williams (8 * bitfieldIndex); 1190d7aca8cSGeorge Liu if (states->possible_states_size < bitfieldIndex || 1200d7aca8cSGeorge Liu !(states->states[bitfieldIndex].byte & (1 << bit))) 1210d7aca8cSGeorge Liu { 1220d7aca8cSGeorge Liu rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE; 123*89644441SRiya Dixit error( 124*89644441SRiya Dixit "Invalid state set value for effecter ID '{EFFECTER_ID}', effecter state '{EFFECTER_STATE}', composite effecter ID '{COMPOSITE_EFFECTER_ID}' and path '{PATH}', response code '{RC}'", 125*89644441SRiya Dixit "EFFECTER_ID", effecterId, "EFFECTER_STATE", 126*89644441SRiya Dixit stateField[currState].effecter_state, 127*89644441SRiya Dixit "COMPOSITE_EFFECTER_ID", currState, "PATH", 128*89644441SRiya Dixit dbusMappings[currState].objectPath.c_str(), "RC", rc); 1290d7aca8cSGeorge Liu break; 1300d7aca8cSGeorge Liu } 1310d7aca8cSGeorge Liu const DBusMapping& dbusMapping = dbusMappings[currState]; 1325079ac4aSBrad Bishop const pldm::responder::pdr_utils::StatestoDbusVal& dbusValToMap = 1335079ac4aSBrad Bishop dbusValMaps[currState]; 1340d7aca8cSGeorge Liu 1350d7aca8cSGeorge Liu if (stateField[currState].set_request == PLDM_REQUEST_SET) 1360d7aca8cSGeorge Liu { 1370d7aca8cSGeorge Liu try 1380d7aca8cSGeorge Liu { 1390d7aca8cSGeorge Liu dBusIntf.setDbusProperty( 1400d7aca8cSGeorge Liu dbusMapping, 1410d7aca8cSGeorge Liu dbusValToMap.at(stateField[currState].effecter_state)); 1420d7aca8cSGeorge Liu } 1430d7aca8cSGeorge Liu catch (const std::exception& e) 1440d7aca8cSGeorge Liu { 14549cfb138SRiya Dixit error( 146*89644441SRiya Dixit "Failed to set property '{PROPERTY}', interface '{INTERFACE}' and path '{PATH}', error - '{ERROR}'", 147*89644441SRiya Dixit "PROPERTY", dbusMapping.propertyName, "INTERFACE", 148*89644441SRiya Dixit dbusMapping.interface, "PATH", 149*89644441SRiya Dixit dbusMapping.objectPath.c_str(), "ERROR", e); 1500d7aca8cSGeorge Liu return PLDM_ERROR; 1510d7aca8cSGeorge Liu } 1520d7aca8cSGeorge Liu } 1530d7aca8cSGeorge Liu uint8_t* nextState = 1540d7aca8cSGeorge Liu reinterpret_cast<uint8_t*>(states) + 1550d7aca8cSGeorge Liu sizeof(state_effecter_possible_states) - 1560d7aca8cSGeorge Liu sizeof(states->states) + 1570d7aca8cSGeorge Liu (states->possible_states_size * sizeof(states->states)); 1580d7aca8cSGeorge Liu states = 1590d7aca8cSGeorge Liu reinterpret_cast<state_effecter_possible_states*>(nextState); 1600d7aca8cSGeorge Liu } 1610d7aca8cSGeorge Liu } 1620d7aca8cSGeorge Liu catch (const std::out_of_range& e) 1630d7aca8cSGeorge Liu { 164*89644441SRiya Dixit error("Unknown effecter ID '{EFFECTERID}', error - {ERROR}", 165*89644441SRiya Dixit "EFFECTERID", effecterId, "ERROR", e); 166bd5e2eaaSGeorge Liu return PLDM_ERROR; 1670d7aca8cSGeorge Liu } 1680d7aca8cSGeorge Liu 1690d7aca8cSGeorge Liu return rc; 1700d7aca8cSGeorge Liu } 1710d7aca8cSGeorge Liu 1720d7aca8cSGeorge Liu } // namespace platform_state_effecter 1730d7aca8cSGeorge Liu } // namespace responder 1740d7aca8cSGeorge Liu } // namespace pldm 175