| Deepak Kodihalli | 557dfb0 | 2019-05-12 13:11:17 +0530 | [diff] [blame] | 1 | #pragma once | 
 | 2 |  | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 3 | #include "config.h" | 
 | 4 |  | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 5 | #include "handler.hpp" | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 6 | #include "libpldmresponder/pdr.hpp" | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 7 | #include "libpldmresponder/pdr_utils.hpp" | 
| George Liu | 8340957 | 2019-12-24 18:42:54 +0800 | [diff] [blame] | 8 | #include "utils.hpp" | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 9 |  | 
| Deepak Kodihalli | 557dfb0 | 2019-05-12 13:11:17 +0530 | [diff] [blame] | 10 | #include <stdint.h> | 
 | 11 |  | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 12 | #include <map> | 
| Deepak Kodihalli | 557dfb0 | 2019-05-12 13:11:17 +0530 | [diff] [blame] | 13 |  | 
 | 14 | #include "libpldm/platform.h" | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 15 | #include "libpldm/states.h" | 
| Deepak Kodihalli | 557dfb0 | 2019-05-12 13:11:17 +0530 | [diff] [blame] | 16 |  | 
 | 17 | namespace pldm | 
 | 18 | { | 
| Deepak Kodihalli | 557dfb0 | 2019-05-12 13:11:17 +0530 | [diff] [blame] | 19 | namespace responder | 
 | 20 | { | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 21 | namespace platform | 
 | 22 | { | 
 | 23 |  | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 24 | using namespace pldm::utils; | 
 | 25 | using namespace pldm::responder::pdr_utils; | 
 | 26 |  | 
 | 27 | using EffecterId = uint16_t; | 
 | 28 | using DbusMappings = std::vector<DBusMapping>; | 
 | 29 | using DbusValMaps = std::vector<StatestoDbusVal>; | 
 | 30 | using DbusObjMaps = std::map<EffecterId, std::tuple<DbusMappings, DbusValMaps>>; | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 31 |  | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 32 | class Handler : public CmdHandler | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 33 | { | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 34 |   public: | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 35 |     Handler(const std::string& dir, pldm_pdr* repo) : pdrRepo(repo) | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 36 |     { | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 37 |         generate(dir, pdrRepo); | 
 | 38 |  | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 39 |         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 Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 48 |     } | 
 | 49 |  | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 50 |     pdr_utils::Repo& getRepo() | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 51 |     { | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 52 |         return this->pdrRepo; | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 53 |     } | 
 | 54 |  | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 55 |     /** @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 Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 75 |  | 
 | 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 Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 95 |     /** @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 Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 102 |  | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 103 |     /** @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 Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 122 |         const DBusInterface& dBusIntf, uint16_t effecterId, | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 123 |         const std::vector<set_effecter_state_field>& stateField) | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 124 |     { | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 125 |         using namespace pldm::responder::pdr; | 
| George Liu | 1e44c73 | 2020-02-28 20:20:06 +0800 | [diff] [blame] | 126 |         using namespace pldm::utils; | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 127 |         using StateSetNum = uint8_t; | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 128 |  | 
 | 129 |         state_effecter_possible_states* states = nullptr; | 
 | 130 |         pldm_state_effecter_pdr* pdr = nullptr; | 
 | 131 |         uint8_t compEffecterCnt = stateField.size(); | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 132 |  | 
 | 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 Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 143 |         PdrEntry pdrEntry{}; | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 144 |         auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry); | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 145 |         while (pdrRecord) | 
 | 146 |         { | 
 | 147 |             pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data); | 
 | 148 |             if (pdr->effecter_id != effecterId) | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 149 |             { | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 150 |                 pdr = nullptr; | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 151 |                 pdrRecord = | 
 | 152 |                     stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry); | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 153 |                 continue; | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 154 |             } | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 155 |  | 
 | 156 |             states = reinterpret_cast<state_effecter_possible_states*>( | 
 | 157 |                 pdr->possible_states); | 
 | 158 |             if (compEffecterCnt > pdr->composite_effecter_count) | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 159 |             { | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 160 |                 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 Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 165 |             } | 
| George Liu | e53193f | 2020-02-24 09:23:26 +0800 | [diff] [blame] | 166 |             break; | 
 | 167 |         } | 
 | 168 |  | 
 | 169 |         if (!pdr) | 
 | 170 |         { | 
 | 171 |             return PLDM_PLATFORM_INVALID_EFFECTER_ID; | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 172 |         } | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 173 |  | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 174 |         int rc = PLDM_SUCCESS; | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 175 |         try | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 176 |         { | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 177 |             const auto& [dbusMappings, dbusValMaps] = | 
 | 178 |                 dbusObjMaps.at(effecterId); | 
 | 179 |             for (uint8_t currState = 0; currState < compEffecterCnt; | 
 | 180 |                  ++currState) | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 181 |             { | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 182 |                 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 Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 190 |                 { | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 191 |                     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 Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 198 |                     break; | 
 | 199 |                 } | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 200 |                 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 Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 230 |             } | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 231 |         } | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 232 |         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 Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 238 |         return rc; | 
 | 239 |     } | 
| Deepak Kodihalli | c682fe2 | 2020-03-04 00:42:54 -0600 | [diff] [blame] | 240 |  | 
 | 241 |   private: | 
 | 242 |     pdr_utils::Repo pdrRepo; | 
 | 243 |     uint16_t nextEffecterId{}; | 
| George Liu | 1ec85d4 | 2020-02-12 16:05:32 +0800 | [diff] [blame^] | 244 |     DbusObjMaps dbusObjMaps{}; | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 245 | }; | 
 | 246 |  | 
 | 247 | } // namespace platform | 
| Deepak Kodihalli | 557dfb0 | 2019-05-12 13:11:17 +0530 | [diff] [blame] | 248 | } // namespace responder | 
 | 249 | } // namespace pldm |