| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 1 | #include "dbus_to_host_effecters.hpp" | 
|  | 2 |  | 
| George Liu | c453e16 | 2022-12-21 17:16:23 +0800 | [diff] [blame] | 3 | #include <libpldm/pdr.h> | 
|  | 4 | #include <libpldm/platform.h> | 
|  | 5 | #include <libpldm/pldm.h> | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 6 |  | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 7 | #include <phosphor-logging/lg2.hpp> | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 8 | #include <xyz/openbmc_project/Common/error.hpp> | 
|  | 9 | #include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp> | 
|  | 10 |  | 
|  | 11 | #include <fstream> | 
|  | 12 | #include <iostream> | 
|  | 13 |  | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 14 | PHOSPHOR_LOG2_USING; | 
|  | 15 |  | 
| Brad Bishop | 5079ac4 | 2021-08-19 18:35:06 -0400 | [diff] [blame] | 16 | using namespace pldm::utils; | 
|  | 17 |  | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 18 | namespace pldm | 
|  | 19 | { | 
|  | 20 | namespace host_effecters | 
|  | 21 | { | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 22 | using InternalFailure = | 
|  | 23 | sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; | 
|  | 24 |  | 
|  | 25 | constexpr auto hostEffecterJson = "dbus_to_host_effecter.json"; | 
|  | 26 |  | 
|  | 27 | void HostEffecterParser::populatePropVals( | 
|  | 28 | const Json& dBusValues, std::vector<PropertyValue>& propertyValues, | 
|  | 29 | const std::string& propertyType) | 
|  | 30 |  | 
|  | 31 | { | 
|  | 32 | for (const auto& elem : dBusValues) | 
|  | 33 | { | 
|  | 34 | auto value = jsonEntryToDbusVal(propertyType, elem); | 
|  | 35 | propertyValues.emplace_back(value); | 
|  | 36 | } | 
|  | 37 | } | 
|  | 38 |  | 
|  | 39 | void HostEffecterParser::parseEffecterJson(const std::string& jsonPath) | 
|  | 40 | { | 
|  | 41 | fs::path jsonDir(jsonPath); | 
|  | 42 | if (!fs::exists(jsonDir) || fs::is_empty(jsonDir)) | 
|  | 43 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 44 | error("Host Effecter json path does not exist, DIR = {JSON_PATH}", | 
|  | 45 | "JSON_PATH", jsonPath.c_str()); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 46 | return; | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | fs::path jsonFilePath = jsonDir / hostEffecterJson; | 
|  | 50 | if (!fs::exists(jsonFilePath)) | 
|  | 51 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 52 | error("json does not exist, PATH = {JSON_PATH}", "JSON_PATH", | 
|  | 53 | jsonFilePath.c_str()); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 54 | throw InternalFailure(); | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | std::ifstream jsonFile(jsonFilePath); | 
|  | 58 | auto data = Json::parse(jsonFile, nullptr, false); | 
|  | 59 | if (data.is_discarded()) | 
|  | 60 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 61 | error("Parsing json file failed, FILE = {JSON_PATH}", "JSON_PATH", | 
|  | 62 | jsonFilePath.c_str()); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 63 | throw InternalFailure(); | 
|  | 64 | } | 
|  | 65 | const Json empty{}; | 
|  | 66 | const std::vector<Json> emptyList{}; | 
|  | 67 |  | 
|  | 68 | auto entries = data.value("entries", emptyList); | 
|  | 69 | for (const auto& entry : entries) | 
|  | 70 | { | 
|  | 71 | EffecterInfo effecterInfo; | 
|  | 72 | effecterInfo.mctpEid = entry.value("mctp_eid", 0xFF); | 
|  | 73 | auto jsonEffecterInfo = entry.value("effecter_info", empty); | 
| Patrick Williams | 6da4f91 | 2023-05-10 07:50:53 -0500 | [diff] [blame] | 74 | auto effecterId = jsonEffecterInfo.value("effecterID", | 
|  | 75 | PLDM_INVALID_EFFECTER_ID); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 76 | effecterInfo.containerId = jsonEffecterInfo.value("containerID", 0); | 
|  | 77 | effecterInfo.entityType = jsonEffecterInfo.value("entityType", 0); | 
| Patrick Williams | 6da4f91 | 2023-05-10 07:50:53 -0500 | [diff] [blame] | 78 | effecterInfo.entityInstance = jsonEffecterInfo.value("entityInstance", | 
|  | 79 | 0); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 80 | effecterInfo.compEffecterCnt = | 
|  | 81 | jsonEffecterInfo.value("compositeEffecterCount", 0); | 
|  | 82 | auto effecters = entry.value("effecters", emptyList); | 
|  | 83 | for (const auto& effecter : effecters) | 
|  | 84 | { | 
|  | 85 | DBusEffecterMapping dbusInfo{}; | 
|  | 86 | auto jsonDbusInfo = effecter.value("dbus_info", empty); | 
|  | 87 | dbusInfo.dbusMap.objectPath = jsonDbusInfo.value("object_path", ""); | 
|  | 88 | dbusInfo.dbusMap.interface = jsonDbusInfo.value("interface", ""); | 
| Patrick Williams | 6da4f91 | 2023-05-10 07:50:53 -0500 | [diff] [blame] | 89 | dbusInfo.dbusMap.propertyName = jsonDbusInfo.value("property_name", | 
|  | 90 | ""); | 
|  | 91 | dbusInfo.dbusMap.propertyType = jsonDbusInfo.value("property_type", | 
|  | 92 | ""); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 93 | Json propertyValues = jsonDbusInfo["property_values"]; | 
|  | 94 |  | 
|  | 95 | populatePropVals(propertyValues, dbusInfo.propertyValues, | 
|  | 96 | dbusInfo.dbusMap.propertyType); | 
|  | 97 |  | 
|  | 98 | const std::vector<uint8_t> emptyStates{}; | 
|  | 99 | auto state = effecter.value("state", empty); | 
|  | 100 | dbusInfo.state.stateSetId = state.value("id", 0); | 
|  | 101 | auto states = state.value("state_values", emptyStates); | 
|  | 102 | if (dbusInfo.propertyValues.size() != states.size()) | 
|  | 103 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 104 | error( | 
|  | 105 | "Number of states do not match with number of D-Bus property values in the json. Object path {OBJ_PATH} and property {PROP_NAME}  will not be monitored", | 
|  | 106 | "OBJ_PATH", dbusInfo.dbusMap.objectPath.c_str(), | 
|  | 107 | "PROP_NAME", dbusInfo.dbusMap.propertyName); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 108 | continue; | 
|  | 109 | } | 
|  | 110 | for (const auto& s : states) | 
|  | 111 | { | 
|  | 112 | dbusInfo.state.states.emplace_back(s); | 
|  | 113 | } | 
|  | 114 |  | 
|  | 115 | auto effecterInfoIndex = hostEffecterInfo.size(); | 
|  | 116 | auto dbusInfoIndex = effecterInfo.dbusInfo.size(); | 
|  | 117 | createHostEffecterMatch( | 
|  | 118 | dbusInfo.dbusMap.objectPath, dbusInfo.dbusMap.interface, | 
|  | 119 | effecterInfoIndex, dbusInfoIndex, effecterId); | 
|  | 120 | effecterInfo.dbusInfo.emplace_back(std::move(dbusInfo)); | 
|  | 121 | } | 
|  | 122 | hostEffecterInfo.emplace_back(std::move(effecterInfo)); | 
|  | 123 | } | 
|  | 124 | } | 
|  | 125 |  | 
|  | 126 | void HostEffecterParser::processHostEffecterChangeNotification( | 
|  | 127 | const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex, | 
|  | 128 | size_t dbusInfoIndex, uint16_t effecterId) | 
|  | 129 | { | 
|  | 130 | const auto& propertyName = hostEffecterInfo[effecterInfoIndex] | 
|  | 131 | .dbusInfo[dbusInfoIndex] | 
|  | 132 | .dbusMap.propertyName; | 
|  | 133 |  | 
|  | 134 | const auto& it = chProperties.find(propertyName); | 
|  | 135 |  | 
|  | 136 | if (it == chProperties.end()) | 
|  | 137 | { | 
|  | 138 | return; | 
|  | 139 | } | 
|  | 140 |  | 
|  | 141 | if (effecterId == PLDM_INVALID_EFFECTER_ID) | 
|  | 142 | { | 
| Sampa Misra | a4a9616 | 2020-07-14 05:33:46 -0500 | [diff] [blame] | 143 | constexpr auto localOrRemote = false; | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 144 | effecterId = findStateEffecterId( | 
|  | 145 | pdrRepo, hostEffecterInfo[effecterInfoIndex].entityType, | 
|  | 146 | hostEffecterInfo[effecterInfoIndex].entityInstance, | 
|  | 147 | hostEffecterInfo[effecterInfoIndex].containerId, | 
|  | 148 | hostEffecterInfo[effecterInfoIndex] | 
|  | 149 | .dbusInfo[dbusInfoIndex] | 
| Sampa Misra | a4a9616 | 2020-07-14 05:33:46 -0500 | [diff] [blame] | 150 | .state.stateSetId, | 
|  | 151 | localOrRemote); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 152 | if (effecterId == PLDM_INVALID_EFFECTER_ID) | 
|  | 153 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 154 | error("Effecter id not found in pdr repo"); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 155 | return; | 
|  | 156 | } | 
|  | 157 | } | 
|  | 158 | constexpr auto hostStateInterface = | 
| Tom Joseph | 5dad5f4 | 2020-12-08 18:23:42 +0530 | [diff] [blame] | 159 | "xyz.openbmc_project.State.Boot.Progress"; | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 160 | constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0"; | 
|  | 161 |  | 
|  | 162 | try | 
|  | 163 | { | 
|  | 164 | auto propVal = dbusHandler->getDbusPropertyVariant( | 
| Tom Joseph | 5dad5f4 | 2020-12-08 18:23:42 +0530 | [diff] [blame] | 165 | hostStatePath, "BootProgress", hostStateInterface); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 166 | const auto& currHostState = std::get<std::string>(propVal); | 
| Tom Joseph | 5dad5f4 | 2020-12-08 18:23:42 +0530 | [diff] [blame] | 167 | if ((currHostState != "xyz.openbmc_project.State.Boot.Progress." | 
|  | 168 | "ProgressStages.SystemInitComplete") && | 
|  | 169 | (currHostState != "xyz.openbmc_project.State.Boot.Progress." | 
|  | 170 | "ProgressStages.OSRunning") && | 
|  | 171 | (currHostState != "xyz.openbmc_project.State.Boot.Progress." | 
| Andrew Geissler | f2704dc | 2022-05-23 16:09:45 -0400 | [diff] [blame] | 172 | "ProgressStages.SystemSetup")) | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 173 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 174 | info("Host is not up. Current host state: {CUR_HOST_STATE}", | 
|  | 175 | "CUR_HOST_STATE", currHostState.c_str()); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 176 | return; | 
|  | 177 | } | 
|  | 178 | } | 
| Patrick Williams | 84b790c | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 179 | catch (const sdbusplus::exception_t& e) | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 180 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 181 | error( | 
|  | 182 | "Error in getting current host state. Will still continue to set the host effecter - {ERR_EXCEP}", | 
|  | 183 | "ERR_EXCEP", e.what()); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 184 | } | 
|  | 185 | uint8_t newState{}; | 
|  | 186 | try | 
|  | 187 | { | 
| Patrick Williams | 6da4f91 | 2023-05-10 07:50:53 -0500 | [diff] [blame] | 188 | newState = findNewStateValue(effecterInfoIndex, dbusInfoIndex, | 
|  | 189 | it->second); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 190 | } | 
|  | 191 | catch (const std::out_of_range& e) | 
|  | 192 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 193 | error("New state not found in json"); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 194 | return; | 
|  | 195 | } | 
|  | 196 |  | 
|  | 197 | std::vector<set_effecter_state_field> stateField; | 
|  | 198 | for (uint8_t i = 0; i < hostEffecterInfo[effecterInfoIndex].compEffecterCnt; | 
|  | 199 | i++) | 
|  | 200 | { | 
|  | 201 | if (i == dbusInfoIndex) | 
|  | 202 | { | 
|  | 203 | stateField.push_back({PLDM_REQUEST_SET, newState}); | 
|  | 204 | } | 
|  | 205 | else | 
|  | 206 | { | 
|  | 207 | stateField.push_back({PLDM_NO_CHANGE, 0}); | 
|  | 208 | } | 
|  | 209 | } | 
|  | 210 | int rc{}; | 
|  | 211 | try | 
|  | 212 | { | 
|  | 213 | rc = setHostStateEffecter(effecterInfoIndex, stateField, effecterId); | 
|  | 214 | } | 
|  | 215 | catch (const std::runtime_error& e) | 
|  | 216 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 217 | error("Could not set host state effecter"); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 218 | return; | 
|  | 219 | } | 
|  | 220 | if (rc != PLDM_SUCCESS) | 
|  | 221 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 222 | error("Could not set the host state effecter, rc= {RC}", "RC", rc); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 223 | } | 
|  | 224 | } | 
|  | 225 |  | 
|  | 226 | uint8_t | 
|  | 227 | HostEffecterParser::findNewStateValue(size_t effecterInfoIndex, | 
|  | 228 | size_t dbusInfoIndex, | 
|  | 229 | const PropertyValue& propertyValue) | 
|  | 230 | { | 
|  | 231 | const auto& propValues = hostEffecterInfo[effecterInfoIndex] | 
|  | 232 | .dbusInfo[dbusInfoIndex] | 
|  | 233 | .propertyValues; | 
|  | 234 | auto it = std::find(propValues.begin(), propValues.end(), propertyValue); | 
|  | 235 | uint8_t newState{}; | 
|  | 236 | if (it != propValues.end()) | 
|  | 237 | { | 
|  | 238 | auto index = std::distance(propValues.begin(), it); | 
|  | 239 | newState = hostEffecterInfo[effecterInfoIndex] | 
|  | 240 | .dbusInfo[dbusInfoIndex] | 
|  | 241 | .state.states[index]; | 
|  | 242 | } | 
|  | 243 | else | 
|  | 244 | { | 
|  | 245 | throw std::out_of_range("new state not found in json"); | 
|  | 246 | } | 
|  | 247 | return newState; | 
|  | 248 | } | 
|  | 249 |  | 
|  | 250 | int HostEffecterParser::setHostStateEffecter( | 
|  | 251 | size_t effecterInfoIndex, std::vector<set_effecter_state_field>& stateField, | 
|  | 252 | uint16_t effecterId) | 
|  | 253 | { | 
|  | 254 | uint8_t& mctpEid = hostEffecterInfo[effecterInfoIndex].mctpEid; | 
|  | 255 | uint8_t& compEffCnt = hostEffecterInfo[effecterInfoIndex].compEffecterCnt; | 
| Andrew Jeffery | a330b2f | 2023-05-04 14:55:37 +0930 | [diff] [blame] | 256 | auto instanceId = instanceIdDb->next(mctpEid); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 257 |  | 
|  | 258 | std::vector<uint8_t> requestMsg( | 
|  | 259 | sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(compEffCnt) + | 
|  | 260 | sizeof(set_effecter_state_field) * compEffCnt, | 
|  | 261 | 0); | 
|  | 262 | auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
|  | 263 | auto rc = encode_set_state_effecter_states_req( | 
|  | 264 | instanceId, effecterId, compEffCnt, stateField.data(), request); | 
|  | 265 |  | 
|  | 266 | if (rc != PLDM_SUCCESS) | 
|  | 267 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 268 | error("Message encode failure. PLDM error code = {RC}", "RC", lg2::hex, | 
|  | 269 | rc); | 
| Andrew Jeffery | a330b2f | 2023-05-04 14:55:37 +0930 | [diff] [blame] | 270 | instanceIdDb->free(mctpEid, instanceId); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 271 | return rc; | 
|  | 272 | } | 
|  | 273 |  | 
| Patrick Williams | 6da4f91 | 2023-05-10 07:50:53 -0500 | [diff] [blame] | 274 | auto setStateEffecterStatesRespHandler = | 
|  | 275 | [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 276 | if (response == nullptr || !respMsgLen) | 
|  | 277 | { | 
|  | 278 | error( | 
|  | 279 | "Failed to receive response for setStateEffecterStates command"); | 
|  | 280 | return; | 
|  | 281 | } | 
|  | 282 | uint8_t completionCode{}; | 
|  | 283 | auto rc = decode_set_state_effecter_states_resp(response, respMsgLen, | 
|  | 284 | &completionCode); | 
|  | 285 | if (rc) | 
|  | 286 | { | 
|  | 287 | error("Failed to decode setStateEffecterStates response, rc {RC}", | 
|  | 288 | "RC", rc); | 
|  | 289 | pldm::utils::reportError( | 
|  | 290 | "xyz.openbmc_project.bmc.pldm.SetHostEffecterFailed"); | 
|  | 291 | } | 
|  | 292 | if (completionCode) | 
|  | 293 | { | 
|  | 294 | error("Failed to set a Host effecter, cc = {CC}", "CC", | 
|  | 295 | static_cast<unsigned>(completionCode)); | 
|  | 296 | pldm::utils::reportError( | 
|  | 297 | "xyz.openbmc_project.bmc.pldm.SetHostEffecterFailed"); | 
|  | 298 | } | 
|  | 299 | }; | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 300 |  | 
| Sampa Misra | c0c7948 | 2021-06-02 08:01:54 -0500 | [diff] [blame] | 301 | rc = handler->registerRequest( | 
|  | 302 | mctpEid, instanceId, PLDM_PLATFORM, PLDM_SET_STATE_EFFECTER_STATES, | 
|  | 303 | std::move(requestMsg), std::move(setStateEffecterStatesRespHandler)); | 
|  | 304 | if (rc) | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 305 | { | 
| Riya Dixit | 49cfb13 | 2023-03-02 04:26:53 -0600 | [diff] [blame] | 306 | error("Failed to send request to set an effecter on Host"); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 307 | } | 
|  | 308 | return rc; | 
|  | 309 | } | 
|  | 310 |  | 
|  | 311 | void HostEffecterParser::createHostEffecterMatch(const std::string& objectPath, | 
|  | 312 | const std::string& interface, | 
|  | 313 | size_t effecterInfoIndex, | 
|  | 314 | size_t dbusInfoIndex, | 
|  | 315 | uint16_t effecterId) | 
|  | 316 | { | 
|  | 317 | using namespace sdbusplus::bus::match::rules; | 
| Patrick Williams | 84b790c | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 318 | effecterInfoMatch.emplace_back(std::make_unique<sdbusplus::bus::match_t>( | 
|  | 319 | pldm::utils::DBusHandler::getBus(), | 
|  | 320 | propertiesChanged(objectPath, interface), | 
|  | 321 | [this, effecterInfoIndex, dbusInfoIndex, | 
|  | 322 | effecterId](sdbusplus::message_t& msg) { | 
| Patrick Williams | 6da4f91 | 2023-05-10 07:50:53 -0500 | [diff] [blame] | 323 | DbusChgHostEffecterProps props; | 
|  | 324 | std::string iface; | 
|  | 325 | msg.read(iface, props); | 
|  | 326 | processHostEffecterChangeNotification(props, effecterInfoIndex, | 
|  | 327 | dbusInfoIndex, effecterId); | 
| Patrick Williams | 84b790c | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 328 | })); | 
| Tom Joseph | 250c475 | 2020-04-15 10:32:45 +0530 | [diff] [blame] | 329 | } | 
|  | 330 |  | 
|  | 331 | } // namespace host_effecters | 
|  | 332 | } // namespace pldm |