1a25aeccfSNikhil Potade /* 2a25aeccfSNikhil Potade // Copyright (c) 2019 Intel Corporation 3a25aeccfSNikhil Potade // 4a25aeccfSNikhil Potade // Licensed under the Apache License, Version 2.0 (the "License"); 5a25aeccfSNikhil Potade // you may not use this file except in compliance with the License. 6a25aeccfSNikhil Potade // You may obtain a copy of the License at 7a25aeccfSNikhil Potade // 8a25aeccfSNikhil Potade // http://www.apache.org/licenses/LICENSE-2.0 9a25aeccfSNikhil Potade // 10a25aeccfSNikhil Potade // Unless required by applicable law or agreed to in writing, software 11a25aeccfSNikhil Potade // distributed under the License is distributed on an "AS IS" BASIS, 12a25aeccfSNikhil Potade // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a25aeccfSNikhil Potade // See the License for the specific language governing permissions and 14a25aeccfSNikhil Potade // limitations under the License. 15a25aeccfSNikhil Potade */ 16a25aeccfSNikhil Potade #pragma once 17a25aeccfSNikhil Potade 182ad9c2f6SJames Feist #include "health.hpp" 19e284a7c1SJames Feist #include "openbmc_dbus_rest.hpp" 202ad9c2f6SJames Feist 21a25aeccfSNikhil Potade #include <node.hpp> 22a25aeccfSNikhil Potade 23a25aeccfSNikhil Potade namespace redfish 24a25aeccfSNikhil Potade { 25a25aeccfSNikhil Potade class StorageCollection : public Node 26a25aeccfSNikhil Potade { 27a25aeccfSNikhil Potade public: 2852cc112dSEd Tanous StorageCollection(App& app) : 29a25aeccfSNikhil Potade Node(app, "/redfish/v1/Systems/system/Storage/") 30a25aeccfSNikhil Potade { 31a25aeccfSNikhil Potade entityPrivileges = { 32a25aeccfSNikhil Potade {boost::beast::http::verb::get, {{"Login"}}}, 33a25aeccfSNikhil Potade {boost::beast::http::verb::head, {{"Login"}}}, 34a25aeccfSNikhil Potade {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 35a25aeccfSNikhil Potade {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 36a25aeccfSNikhil Potade {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 37a25aeccfSNikhil Potade {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 38a25aeccfSNikhil Potade } 39a25aeccfSNikhil Potade 40a25aeccfSNikhil Potade private: 41*cb13a392SEd Tanous void doGet(crow::Response& res, const crow::Request&, 42*cb13a392SEd Tanous const std::vector<std::string>&) override 43a25aeccfSNikhil Potade { 44a25aeccfSNikhil Potade res.jsonValue["@odata.type"] = "#StorageCollection.StorageCollection"; 45a25aeccfSNikhil Potade res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Storage"; 46a25aeccfSNikhil Potade res.jsonValue["Name"] = "Storage Collection"; 47a25aeccfSNikhil Potade res.jsonValue["Members"] = { 48a25aeccfSNikhil Potade {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}}; 49a25aeccfSNikhil Potade res.jsonValue["Members@odata.count"] = 1; 50a25aeccfSNikhil Potade res.end(); 51a25aeccfSNikhil Potade } 52a25aeccfSNikhil Potade }; 53a25aeccfSNikhil Potade 54a25aeccfSNikhil Potade class Storage : public Node 55a25aeccfSNikhil Potade { 56a25aeccfSNikhil Potade public: 5752cc112dSEd Tanous Storage(App& app) : Node(app, "/redfish/v1/Systems/system/Storage/1/") 58a25aeccfSNikhil Potade { 59a25aeccfSNikhil Potade entityPrivileges = { 60a25aeccfSNikhil Potade {boost::beast::http::verb::get, {{"Login"}}}, 61a25aeccfSNikhil Potade {boost::beast::http::verb::head, {{"Login"}}}, 62a25aeccfSNikhil Potade {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 63a25aeccfSNikhil Potade {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 64a25aeccfSNikhil Potade {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 65a25aeccfSNikhil Potade {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 66a25aeccfSNikhil Potade } 67a25aeccfSNikhil Potade 68a25aeccfSNikhil Potade private: 69*cb13a392SEd Tanous void doGet(crow::Response& res, const crow::Request&, 70*cb13a392SEd Tanous const std::vector<std::string>&) override 71a25aeccfSNikhil Potade { 72a25aeccfSNikhil Potade res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage"; 73a25aeccfSNikhil Potade res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Storage/1"; 74e284a7c1SJames Feist res.jsonValue["Name"] = "Storage"; 75a25aeccfSNikhil Potade res.jsonValue["Id"] = "1"; 762ad9c2f6SJames Feist res.jsonValue["Status"]["State"] = "Enabled"; 77a25aeccfSNikhil Potade 78a25aeccfSNikhil Potade auto asyncResp = std::make_shared<AsyncResp>(res); 79e284a7c1SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 80e284a7c1SJames Feist health->populate(); 81e284a7c1SJames Feist 82a25aeccfSNikhil Potade crow::connections::systemBus->async_method_call( 83e284a7c1SJames Feist [asyncResp, health](const boost::system::error_code ec, 84a25aeccfSNikhil Potade const std::vector<std::string>& storageList) { 85a25aeccfSNikhil Potade nlohmann::json& storageArray = 86a25aeccfSNikhil Potade asyncResp->res.jsonValue["Drives"]; 87a25aeccfSNikhil Potade storageArray = nlohmann::json::array(); 88e284a7c1SJames Feist auto& count = asyncResp->res.jsonValue["Drives@odata.count"]; 89e284a7c1SJames Feist count = 0; 902ad9c2f6SJames Feist 91a25aeccfSNikhil Potade if (ec) 92a25aeccfSNikhil Potade { 93a25aeccfSNikhil Potade BMCWEB_LOG_ERROR << "Drive mapper call error"; 94a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 95a25aeccfSNikhil Potade return; 96a25aeccfSNikhil Potade } 972ad9c2f6SJames Feist 98e284a7c1SJames Feist health->inventory.insert(health->inventory.end(), 99e284a7c1SJames Feist storageList.begin(), 100e284a7c1SJames Feist storageList.end()); 1012ad9c2f6SJames Feist 102a25aeccfSNikhil Potade for (const std::string& objpath : storageList) 103a25aeccfSNikhil Potade { 104a25aeccfSNikhil Potade std::size_t lastPos = objpath.rfind("/"); 105a25aeccfSNikhil Potade if (lastPos == std::string::npos || 106a25aeccfSNikhil Potade (objpath.size() <= lastPos + 1)) 107a25aeccfSNikhil Potade { 108a25aeccfSNikhil Potade BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath; 109a25aeccfSNikhil Potade continue; 110a25aeccfSNikhil Potade } 111a25aeccfSNikhil Potade 112a25aeccfSNikhil Potade storageArray.push_back( 113a25aeccfSNikhil Potade {{"@odata.id", 114be13ceceSJames Feist "/redfish/v1/Systems/system/Storage/1/Drives/" + 115a25aeccfSNikhil Potade objpath.substr(lastPos + 1)}}); 116a25aeccfSNikhil Potade } 117a25aeccfSNikhil Potade 118e284a7c1SJames Feist count = storageArray.size(); 119a25aeccfSNikhil Potade }, 120a25aeccfSNikhil Potade "xyz.openbmc_project.ObjectMapper", 121a25aeccfSNikhil Potade "/xyz/openbmc_project/object_mapper", 122a25aeccfSNikhil Potade "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 123a25aeccfSNikhil Potade "/xyz/openbmc_project/inventory", int32_t(0), 124a25aeccfSNikhil Potade std::array<const char*, 1>{ 125a25aeccfSNikhil Potade "xyz.openbmc_project.Inventory.Item.Drive"}); 126e284a7c1SJames Feist 127e284a7c1SJames Feist crow::connections::systemBus->async_method_call( 128e284a7c1SJames Feist [asyncResp, 129e284a7c1SJames Feist health](const boost::system::error_code ec, 130e284a7c1SJames Feist const crow::openbmc_mapper::GetSubTreeType& subtree) { 131e284a7c1SJames Feist if (ec || !subtree.size()) 132e284a7c1SJames Feist { 133d819a420SJames Feist // doesn't have to be there 134e284a7c1SJames Feist return; 135e284a7c1SJames Feist } 136e284a7c1SJames Feist 137e284a7c1SJames Feist nlohmann::json& root = 138e284a7c1SJames Feist asyncResp->res.jsonValue["StorageControllers"]; 139e284a7c1SJames Feist root = nlohmann::json::array(); 140e284a7c1SJames Feist for (const auto& [path, interfaceDict] : subtree) 141e284a7c1SJames Feist { 142e284a7c1SJames Feist std::size_t lastPos = path.rfind("/"); 143e284a7c1SJames Feist if (lastPos == std::string::npos || 144e284a7c1SJames Feist (path.size() <= lastPos + 1)) 145e284a7c1SJames Feist { 146e284a7c1SJames Feist BMCWEB_LOG_ERROR << "Failed to find '/' in " << path; 147e284a7c1SJames Feist return; 148e284a7c1SJames Feist } 149e284a7c1SJames Feist 150e284a7c1SJames Feist if (interfaceDict.size() != 1) 151e284a7c1SJames Feist { 152e284a7c1SJames Feist BMCWEB_LOG_ERROR << "Connection size " 153e284a7c1SJames Feist << interfaceDict.size() 154e284a7c1SJames Feist << ", greater than 1"; 155e284a7c1SJames Feist messages::internalError(asyncResp->res); 156e284a7c1SJames Feist return; 157e284a7c1SJames Feist } 158e284a7c1SJames Feist 159e284a7c1SJames Feist const std::string& connectionName = 160e284a7c1SJames Feist interfaceDict.front().first; 161e284a7c1SJames Feist 162e284a7c1SJames Feist size_t index = root.size(); 163e284a7c1SJames Feist nlohmann::json& storageController = 164e284a7c1SJames Feist root.emplace_back(nlohmann::json::object()); 165e284a7c1SJames Feist 166e284a7c1SJames Feist std::string id = path.substr(lastPos + 1); 167e284a7c1SJames Feist 168e284a7c1SJames Feist storageController["@odata.type"] = 169e284a7c1SJames Feist "#Storage.v1_7_0.StorageController"; 170e284a7c1SJames Feist storageController["@odata.id"] = 171e284a7c1SJames Feist "/redfish/v1/Systems/system/Storage/1" 172e284a7c1SJames Feist "#/StorageControllers/" + 173e284a7c1SJames Feist std::to_string(index); 174e284a7c1SJames Feist storageController["Name"] = id; 175e284a7c1SJames Feist storageController["MemberId"] = id; 176e284a7c1SJames Feist storageController["Status"]["State"] = "Enabled"; 177e284a7c1SJames Feist 178e284a7c1SJames Feist crow::connections::systemBus->async_method_call( 17923a21a1cSEd Tanous [asyncResp, index](const boost::system::error_code ec2, 180e284a7c1SJames Feist const std::variant<bool> present) { 181e284a7c1SJames Feist // this interface isn't necessary, only check it if 182e284a7c1SJames Feist // we get a good return 18323a21a1cSEd Tanous if (ec2) 184e284a7c1SJames Feist { 185e284a7c1SJames Feist return; 186e284a7c1SJames Feist } 187e284a7c1SJames Feist const bool* enabled = std::get_if<bool>(&present); 188e284a7c1SJames Feist if (enabled == nullptr) 189e284a7c1SJames Feist { 190e284a7c1SJames Feist BMCWEB_LOG_DEBUG << "Illegal property present"; 191e284a7c1SJames Feist messages::internalError(asyncResp->res); 192e284a7c1SJames Feist return; 193e284a7c1SJames Feist } 194e284a7c1SJames Feist if (!(*enabled)) 195e284a7c1SJames Feist { 196e284a7c1SJames Feist asyncResp->res 197e284a7c1SJames Feist .jsonValue["StorageControllers"][index] 198e284a7c1SJames Feist ["Status"]["State"] = "Disabled"; 199e284a7c1SJames Feist } 200e284a7c1SJames Feist }, 201e284a7c1SJames Feist connectionName, path, "org.freedesktop.DBus.Properties", 202e284a7c1SJames Feist "Get", "xyz.openbmc_project.Inventory.Item", "Present"); 203e284a7c1SJames Feist 204e284a7c1SJames Feist crow::connections::systemBus->async_method_call( 205e284a7c1SJames Feist [asyncResp, 20623a21a1cSEd Tanous index](const boost::system::error_code ec2, 207e284a7c1SJames Feist const std::vector<std::pair< 208e284a7c1SJames Feist std::string, 2091214b7e7SGunnar Mills std::variant<bool, std::string, uint64_t>>>& 2101214b7e7SGunnar Mills propertiesList) { 21123a21a1cSEd Tanous if (ec2) 212e284a7c1SJames Feist { 213e284a7c1SJames Feist // this interface isn't necessary 214e284a7c1SJames Feist return; 215e284a7c1SJames Feist } 216e284a7c1SJames Feist for (const std::pair< 217e284a7c1SJames Feist std::string, 2181214b7e7SGunnar Mills std::variant<bool, std::string, uint64_t>>& 2191214b7e7SGunnar Mills property : propertiesList) 220e284a7c1SJames Feist { 221e284a7c1SJames Feist // Store DBus properties that are also 222e284a7c1SJames Feist // Redfish properties with same name and a 223e284a7c1SJames Feist // string value 224e284a7c1SJames Feist const std::string& propertyName = 225e284a7c1SJames Feist property.first; 226e284a7c1SJames Feist nlohmann::json& object = 227e284a7c1SJames Feist asyncResp->res 228e284a7c1SJames Feist .jsonValue["StorageControllers"][index]; 229e284a7c1SJames Feist if ((propertyName == "PartNumber") || 230e284a7c1SJames Feist (propertyName == "SerialNumber") || 231e284a7c1SJames Feist (propertyName == "Manufacturer") || 232e284a7c1SJames Feist (propertyName == "Model")) 233e284a7c1SJames Feist { 234e284a7c1SJames Feist const std::string* value = 235e284a7c1SJames Feist std::get_if<std::string>( 236e284a7c1SJames Feist &property.second); 237e284a7c1SJames Feist if (value == nullptr) 238e284a7c1SJames Feist { 239e284a7c1SJames Feist // illegal property 240e284a7c1SJames Feist messages::internalError(asyncResp->res); 241e284a7c1SJames Feist continue; 242e284a7c1SJames Feist } 243e284a7c1SJames Feist object[propertyName] = *value; 244e284a7c1SJames Feist } 245e284a7c1SJames Feist } 246e284a7c1SJames Feist }, 247e284a7c1SJames Feist connectionName, path, "org.freedesktop.DBus.Properties", 248e284a7c1SJames Feist "GetAll", 249e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Decorator.Asset"); 250e284a7c1SJames Feist } 251e284a7c1SJames Feist 252e284a7c1SJames Feist // this is done after we know the json array will no longer be 253e284a7c1SJames Feist // resized, as json::array uses vector underneath and we need 254e284a7c1SJames Feist // references to its members that won't change 255e284a7c1SJames Feist size_t count = 0; 256e284a7c1SJames Feist for (const auto& [path, interfaceDict] : subtree) 257e284a7c1SJames Feist { 258e284a7c1SJames Feist auto subHealth = std::make_shared<HealthPopulate>( 259e284a7c1SJames Feist asyncResp, root[count]["Status"]); 260e284a7c1SJames Feist subHealth->inventory.emplace_back(path); 261e284a7c1SJames Feist health->inventory.emplace_back(path); 262e284a7c1SJames Feist health->children.emplace_back(subHealth); 263e284a7c1SJames Feist count++; 264e284a7c1SJames Feist } 265e284a7c1SJames Feist }, 266e284a7c1SJames Feist "xyz.openbmc_project.ObjectMapper", 267e284a7c1SJames Feist "/xyz/openbmc_project/object_mapper", 268e284a7c1SJames Feist "xyz.openbmc_project.ObjectMapper", "GetSubTree", 269e284a7c1SJames Feist "/xyz/openbmc_project/inventory", int32_t(0), 270e284a7c1SJames Feist std::array<const char*, 1>{ 271e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}); 272a25aeccfSNikhil Potade } 273a25aeccfSNikhil Potade }; 274a25aeccfSNikhil Potade 275a25aeccfSNikhil Potade class Drive : public Node 276a25aeccfSNikhil Potade { 277a25aeccfSNikhil Potade public: 27852cc112dSEd Tanous Drive(App& app) : 279be13ceceSJames Feist Node(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/", 280a25aeccfSNikhil Potade std::string()) 281a25aeccfSNikhil Potade { 282a25aeccfSNikhil Potade entityPrivileges = { 283a25aeccfSNikhil Potade {boost::beast::http::verb::get, {{"Login"}}}, 284a25aeccfSNikhil Potade {boost::beast::http::verb::head, {{"Login"}}}, 285a25aeccfSNikhil Potade {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 286a25aeccfSNikhil Potade {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 287a25aeccfSNikhil Potade {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 288a25aeccfSNikhil Potade {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 289a25aeccfSNikhil Potade } 290a25aeccfSNikhil Potade 291a25aeccfSNikhil Potade private: 292*cb13a392SEd Tanous void doGet(crow::Response& res, const crow::Request&, 293a25aeccfSNikhil Potade const std::vector<std::string>& params) override 294a25aeccfSNikhil Potade { 295e284a7c1SJames Feist auto asyncResp = std::make_shared<AsyncResp>(res); 296e284a7c1SJames Feist if (params.size() != 1) 297e284a7c1SJames Feist { 298e284a7c1SJames Feist messages::internalError(asyncResp->res); 299e284a7c1SJames Feist return; 300e284a7c1SJames Feist } 301a25aeccfSNikhil Potade const std::string& driveId = params[0]; 302a25aeccfSNikhil Potade 303a25aeccfSNikhil Potade crow::connections::systemBus->async_method_call( 304e284a7c1SJames Feist [asyncResp, 305e284a7c1SJames Feist driveId](const boost::system::error_code ec, 306e284a7c1SJames Feist const crow::openbmc_mapper::GetSubTreeType& subtree) { 307a25aeccfSNikhil Potade if (ec) 308a25aeccfSNikhil Potade { 309a25aeccfSNikhil Potade BMCWEB_LOG_ERROR << "Drive mapper call error"; 310a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 311a25aeccfSNikhil Potade return; 312a25aeccfSNikhil Potade } 313a25aeccfSNikhil Potade 31423a21a1cSEd Tanous auto object2 = std::find_if( 315a25aeccfSNikhil Potade subtree.begin(), subtree.end(), [&driveId](auto& object) { 316a25aeccfSNikhil Potade const std::string& path = object.first; 317a25aeccfSNikhil Potade return boost::ends_with(path, "/" + driveId); 318a25aeccfSNikhil Potade }); 319a25aeccfSNikhil Potade 32023a21a1cSEd Tanous if (object2 == subtree.end()) 321a25aeccfSNikhil Potade { 322a25aeccfSNikhil Potade messages::resourceNotFound(asyncResp->res, "Drive", 323a25aeccfSNikhil Potade driveId); 324a25aeccfSNikhil Potade return; 325a25aeccfSNikhil Potade } 326a25aeccfSNikhil Potade 32723a21a1cSEd Tanous const std::string& path = object2->first; 328a25aeccfSNikhil Potade const std::vector< 3291214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 33023a21a1cSEd Tanous connectionNames = object2->second; 331a25aeccfSNikhil Potade 332a25aeccfSNikhil Potade asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive"; 333a25aeccfSNikhil Potade asyncResp->res.jsonValue["@odata.id"] = 334be13ceceSJames Feist "/redfish/v1/Systems/system/Storage/1/Drives/" + driveId; 3352ad9c2f6SJames Feist asyncResp->res.jsonValue["Name"] = driveId; 3362ad9c2f6SJames Feist asyncResp->res.jsonValue["Id"] = driveId; 337a25aeccfSNikhil Potade 338a25aeccfSNikhil Potade if (connectionNames.size() != 1) 339a25aeccfSNikhil Potade { 340a25aeccfSNikhil Potade BMCWEB_LOG_ERROR << "Connection size " 341a25aeccfSNikhil Potade << connectionNames.size() 342a25aeccfSNikhil Potade << ", greater than 1"; 343a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 344a25aeccfSNikhil Potade return; 345a25aeccfSNikhil Potade } 346a25aeccfSNikhil Potade 347a25aeccfSNikhil Potade getMainChassisId( 348a25aeccfSNikhil Potade asyncResp, [](const std::string& chassisId, 349a25aeccfSNikhil Potade std::shared_ptr<AsyncResp> aRsp) { 350a25aeccfSNikhil Potade aRsp->res.jsonValue["Links"]["Chassis"] = { 351a25aeccfSNikhil Potade {"@odata.id", "/redfish/v1/Chassis/" + chassisId}}; 352a25aeccfSNikhil Potade }); 353a25aeccfSNikhil Potade 354a25aeccfSNikhil Potade const std::string& connectionName = connectionNames[0].first; 355a25aeccfSNikhil Potade crow::connections::systemBus->async_method_call( 356*cb13a392SEd Tanous [asyncResp](const boost::system::error_code ec2, 357a25aeccfSNikhil Potade const std::vector<std::pair< 358a25aeccfSNikhil Potade std::string, 3591214b7e7SGunnar Mills std::variant<bool, std::string, uint64_t>>>& 3601214b7e7SGunnar Mills propertiesList) { 361*cb13a392SEd Tanous if (ec2) 362a25aeccfSNikhil Potade { 363a25aeccfSNikhil Potade // this interface isn't necessary 364a25aeccfSNikhil Potade return; 365a25aeccfSNikhil Potade } 366a25aeccfSNikhil Potade for (const std::pair<std::string, 367a25aeccfSNikhil Potade std::variant<bool, std::string, 368a25aeccfSNikhil Potade uint64_t>>& property : 369a25aeccfSNikhil Potade propertiesList) 370a25aeccfSNikhil Potade { 371a25aeccfSNikhil Potade // Store DBus properties that are also 372a25aeccfSNikhil Potade // Redfish properties with same name and a 373a25aeccfSNikhil Potade // string value 374a25aeccfSNikhil Potade const std::string& propertyName = property.first; 375a25aeccfSNikhil Potade if ((propertyName == "PartNumber") || 376a25aeccfSNikhil Potade (propertyName == "SerialNumber") || 377a25aeccfSNikhil Potade (propertyName == "Manufacturer") || 378a25aeccfSNikhil Potade (propertyName == "Model")) 379a25aeccfSNikhil Potade { 380a25aeccfSNikhil Potade const std::string* value = 381a25aeccfSNikhil Potade std::get_if<std::string>(&property.second); 382a25aeccfSNikhil Potade if (value == nullptr) 383a25aeccfSNikhil Potade { 384a25aeccfSNikhil Potade // illegal property 385a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 386a25aeccfSNikhil Potade continue; 387a25aeccfSNikhil Potade } 388a25aeccfSNikhil Potade asyncResp->res.jsonValue[propertyName] = *value; 389a25aeccfSNikhil Potade } 390a25aeccfSNikhil Potade } 391a25aeccfSNikhil Potade }, 392a25aeccfSNikhil Potade connectionName, path, "org.freedesktop.DBus.Properties", 393a25aeccfSNikhil Potade "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset"); 394a25aeccfSNikhil Potade 395a25aeccfSNikhil Potade // default it to Enabled 396a25aeccfSNikhil Potade asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 397a25aeccfSNikhil Potade 3982ad9c2f6SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 399e284a7c1SJames Feist health->inventory.emplace_back(path); 4002ad9c2f6SJames Feist health->populate(); 4012ad9c2f6SJames Feist 402a25aeccfSNikhil Potade crow::connections::systemBus->async_method_call( 403*cb13a392SEd Tanous [asyncResp, path](const boost::system::error_code ec2, 404a25aeccfSNikhil Potade const std::variant<bool> present) { 405a25aeccfSNikhil Potade // this interface isn't necessary, only check it if we 406a25aeccfSNikhil Potade // get a good return 407*cb13a392SEd Tanous if (ec2) 408a25aeccfSNikhil Potade { 4092ad9c2f6SJames Feist return; 4102ad9c2f6SJames Feist } 411a25aeccfSNikhil Potade const bool* enabled = std::get_if<bool>(&present); 412a25aeccfSNikhil Potade if (enabled == nullptr) 413a25aeccfSNikhil Potade { 414a25aeccfSNikhil Potade BMCWEB_LOG_DEBUG << "Illegal property present"; 415a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 416a25aeccfSNikhil Potade return; 417a25aeccfSNikhil Potade } 418a25aeccfSNikhil Potade if (!(*enabled)) 419a25aeccfSNikhil Potade { 420a25aeccfSNikhil Potade asyncResp->res.jsonValue["Status"]["State"] = 421a25aeccfSNikhil Potade "Disabled"; 422a25aeccfSNikhil Potade } 423a25aeccfSNikhil Potade }, 424a25aeccfSNikhil Potade connectionName, path, "org.freedesktop.DBus.Properties", 425a25aeccfSNikhil Potade "Get", "xyz.openbmc_project.Inventory.Item", "Present"); 42622984074SJames Feist 42722984074SJames Feist crow::connections::systemBus->async_method_call( 428*cb13a392SEd Tanous [asyncResp](const boost::system::error_code ec2, 42922984074SJames Feist const std::variant<bool> rebuilding) { 43022984074SJames Feist // this interface isn't necessary, only check it if we 43122984074SJames Feist // get a good return 432*cb13a392SEd Tanous if (ec2) 43322984074SJames Feist { 43422984074SJames Feist return; 43522984074SJames Feist } 43622984074SJames Feist const bool* updating = std::get_if<bool>(&rebuilding); 43722984074SJames Feist if (updating == nullptr) 43822984074SJames Feist { 43922984074SJames Feist BMCWEB_LOG_DEBUG << "Illegal property present"; 44022984074SJames Feist messages::internalError(asyncResp->res); 44122984074SJames Feist return; 44222984074SJames Feist } 44322984074SJames Feist 44422984074SJames Feist // updating and disabled in the backend shouldn't be 44522984074SJames Feist // able to be set at the same time, so we don't need to 44622984074SJames Feist // check for the race condition of these two calls 44722984074SJames Feist if ((*updating)) 44822984074SJames Feist { 44922984074SJames Feist asyncResp->res.jsonValue["Status"]["State"] = 45022984074SJames Feist "Updating"; 45122984074SJames Feist } 45222984074SJames Feist }, 45322984074SJames Feist connectionName, path, "org.freedesktop.DBus.Properties", 45422984074SJames Feist "Get", "xyz.openbmc_project.State.Drive", "Rebuilding"); 455a25aeccfSNikhil Potade }, 456a25aeccfSNikhil Potade "xyz.openbmc_project.ObjectMapper", 457a25aeccfSNikhil Potade "/xyz/openbmc_project/object_mapper", 458a25aeccfSNikhil Potade "xyz.openbmc_project.ObjectMapper", "GetSubTree", 459a25aeccfSNikhil Potade "/xyz/openbmc_project/inventory", int32_t(0), 460a25aeccfSNikhil Potade std::array<const char*, 1>{ 461a25aeccfSNikhil Potade "xyz.openbmc_project.Inventory.Item.Drive"}); 462a25aeccfSNikhil Potade } 463a25aeccfSNikhil Potade }; 464a25aeccfSNikhil Potade } // namespace redfish 465