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*8d1b46d7Szhanghch05 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 42*8d1b46d7Szhanghch05 const crow::Request&, const std::vector<std::string>&) override 43a25aeccfSNikhil Potade { 44*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 45*8d1b46d7Szhanghch05 "#StorageCollection.StorageCollection"; 46*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 47*8d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Storage"; 48*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Storage Collection"; 49*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["Members"] = { 50a25aeccfSNikhil Potade {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}}; 51*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["Members@odata.count"] = 1; 52a25aeccfSNikhil Potade } 53a25aeccfSNikhil Potade }; 54a25aeccfSNikhil Potade 55a25aeccfSNikhil Potade class Storage : public Node 56a25aeccfSNikhil Potade { 57a25aeccfSNikhil Potade public: 5852cc112dSEd Tanous Storage(App& app) : Node(app, "/redfish/v1/Systems/system/Storage/1/") 59a25aeccfSNikhil Potade { 60a25aeccfSNikhil Potade entityPrivileges = { 61a25aeccfSNikhil Potade {boost::beast::http::verb::get, {{"Login"}}}, 62a25aeccfSNikhil Potade {boost::beast::http::verb::head, {{"Login"}}}, 63a25aeccfSNikhil Potade {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 64a25aeccfSNikhil Potade {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 65a25aeccfSNikhil Potade {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 66a25aeccfSNikhil Potade {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 67a25aeccfSNikhil Potade } 68a25aeccfSNikhil Potade 69a25aeccfSNikhil Potade private: 70*8d1b46d7Szhanghch05 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 71*8d1b46d7Szhanghch05 const crow::Request&, const std::vector<std::string>&) override 72a25aeccfSNikhil Potade { 73*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage"; 74*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 75*8d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Storage/1"; 76*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Storage"; 77*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["Id"] = "1"; 78*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 79a25aeccfSNikhil Potade 80e284a7c1SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 81e284a7c1SJames Feist health->populate(); 82e284a7c1SJames Feist 83a25aeccfSNikhil Potade crow::connections::systemBus->async_method_call( 84e284a7c1SJames Feist [asyncResp, health](const boost::system::error_code ec, 85a25aeccfSNikhil Potade const std::vector<std::string>& storageList) { 86a25aeccfSNikhil Potade nlohmann::json& storageArray = 87a25aeccfSNikhil Potade asyncResp->res.jsonValue["Drives"]; 88a25aeccfSNikhil Potade storageArray = nlohmann::json::array(); 89e284a7c1SJames Feist auto& count = asyncResp->res.jsonValue["Drives@odata.count"]; 90e284a7c1SJames Feist count = 0; 912ad9c2f6SJames Feist 92a25aeccfSNikhil Potade if (ec) 93a25aeccfSNikhil Potade { 94a25aeccfSNikhil Potade BMCWEB_LOG_ERROR << "Drive mapper call error"; 95a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 96a25aeccfSNikhil Potade return; 97a25aeccfSNikhil Potade } 982ad9c2f6SJames Feist 99e284a7c1SJames Feist health->inventory.insert(health->inventory.end(), 100e284a7c1SJames Feist storageList.begin(), 101e284a7c1SJames Feist storageList.end()); 1022ad9c2f6SJames Feist 103a25aeccfSNikhil Potade for (const std::string& objpath : storageList) 104a25aeccfSNikhil Potade { 105f23b7296SEd Tanous std::size_t lastPos = objpath.rfind('/'); 106a25aeccfSNikhil Potade if (lastPos == std::string::npos || 107a25aeccfSNikhil Potade (objpath.size() <= lastPos + 1)) 108a25aeccfSNikhil Potade { 109a25aeccfSNikhil Potade BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath; 110a25aeccfSNikhil Potade continue; 111a25aeccfSNikhil Potade } 112a25aeccfSNikhil Potade 113a25aeccfSNikhil Potade storageArray.push_back( 114a25aeccfSNikhil Potade {{"@odata.id", 115be13ceceSJames Feist "/redfish/v1/Systems/system/Storage/1/Drives/" + 116a25aeccfSNikhil Potade objpath.substr(lastPos + 1)}}); 117a25aeccfSNikhil Potade } 118a25aeccfSNikhil Potade 119e284a7c1SJames Feist count = storageArray.size(); 120a25aeccfSNikhil Potade }, 121a25aeccfSNikhil Potade "xyz.openbmc_project.ObjectMapper", 122a25aeccfSNikhil Potade "/xyz/openbmc_project/object_mapper", 123a25aeccfSNikhil Potade "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 124a25aeccfSNikhil Potade "/xyz/openbmc_project/inventory", int32_t(0), 125a25aeccfSNikhil Potade std::array<const char*, 1>{ 126a25aeccfSNikhil Potade "xyz.openbmc_project.Inventory.Item.Drive"}); 127e284a7c1SJames Feist 128e284a7c1SJames Feist crow::connections::systemBus->async_method_call( 129e284a7c1SJames Feist [asyncResp, 130e284a7c1SJames Feist health](const boost::system::error_code ec, 131e284a7c1SJames Feist const crow::openbmc_mapper::GetSubTreeType& subtree) { 132e284a7c1SJames Feist if (ec || !subtree.size()) 133e284a7c1SJames Feist { 134d819a420SJames Feist // doesn't have to be there 135e284a7c1SJames Feist return; 136e284a7c1SJames Feist } 137e284a7c1SJames Feist 138e284a7c1SJames Feist nlohmann::json& root = 139e284a7c1SJames Feist asyncResp->res.jsonValue["StorageControllers"]; 140e284a7c1SJames Feist root = nlohmann::json::array(); 141e284a7c1SJames Feist for (const auto& [path, interfaceDict] : subtree) 142e284a7c1SJames Feist { 143f23b7296SEd Tanous std::size_t lastPos = path.rfind('/'); 144e284a7c1SJames Feist if (lastPos == std::string::npos || 145e284a7c1SJames Feist (path.size() <= lastPos + 1)) 146e284a7c1SJames Feist { 147e284a7c1SJames Feist BMCWEB_LOG_ERROR << "Failed to find '/' in " << path; 148e284a7c1SJames Feist return; 149e284a7c1SJames Feist } 150e284a7c1SJames Feist 151e284a7c1SJames Feist if (interfaceDict.size() != 1) 152e284a7c1SJames Feist { 153e284a7c1SJames Feist BMCWEB_LOG_ERROR << "Connection size " 154e284a7c1SJames Feist << interfaceDict.size() 155e284a7c1SJames Feist << ", greater than 1"; 156e284a7c1SJames Feist messages::internalError(asyncResp->res); 157e284a7c1SJames Feist return; 158e284a7c1SJames Feist } 159e284a7c1SJames Feist 160e284a7c1SJames Feist const std::string& connectionName = 161e284a7c1SJames Feist interfaceDict.front().first; 162e284a7c1SJames Feist 163e284a7c1SJames Feist size_t index = root.size(); 164e284a7c1SJames Feist nlohmann::json& storageController = 165e284a7c1SJames Feist root.emplace_back(nlohmann::json::object()); 166e284a7c1SJames Feist 167e284a7c1SJames Feist std::string id = path.substr(lastPos + 1); 168e284a7c1SJames Feist 169e284a7c1SJames Feist storageController["@odata.type"] = 170e284a7c1SJames Feist "#Storage.v1_7_0.StorageController"; 171e284a7c1SJames Feist storageController["@odata.id"] = 172e284a7c1SJames Feist "/redfish/v1/Systems/system/Storage/1" 173e284a7c1SJames Feist "#/StorageControllers/" + 174e284a7c1SJames Feist std::to_string(index); 175e284a7c1SJames Feist storageController["Name"] = id; 176e284a7c1SJames Feist storageController["MemberId"] = id; 177e284a7c1SJames Feist storageController["Status"]["State"] = "Enabled"; 178e284a7c1SJames Feist 179e284a7c1SJames Feist crow::connections::systemBus->async_method_call( 18023a21a1cSEd Tanous [asyncResp, index](const boost::system::error_code ec2, 181e284a7c1SJames Feist const std::variant<bool> present) { 182e284a7c1SJames Feist // this interface isn't necessary, only check it if 183e284a7c1SJames Feist // we get a good return 18423a21a1cSEd Tanous if (ec2) 185e284a7c1SJames Feist { 186e284a7c1SJames Feist return; 187e284a7c1SJames Feist } 188e284a7c1SJames Feist const bool* enabled = std::get_if<bool>(&present); 189e284a7c1SJames Feist if (enabled == nullptr) 190e284a7c1SJames Feist { 191e284a7c1SJames Feist BMCWEB_LOG_DEBUG << "Illegal property present"; 192e284a7c1SJames Feist messages::internalError(asyncResp->res); 193e284a7c1SJames Feist return; 194e284a7c1SJames Feist } 195e284a7c1SJames Feist if (!(*enabled)) 196e284a7c1SJames Feist { 197e284a7c1SJames Feist asyncResp->res 198e284a7c1SJames Feist .jsonValue["StorageControllers"][index] 199e284a7c1SJames Feist ["Status"]["State"] = "Disabled"; 200e284a7c1SJames Feist } 201e284a7c1SJames Feist }, 202e284a7c1SJames Feist connectionName, path, "org.freedesktop.DBus.Properties", 203e284a7c1SJames Feist "Get", "xyz.openbmc_project.Inventory.Item", "Present"); 204e284a7c1SJames Feist 205e284a7c1SJames Feist crow::connections::systemBus->async_method_call( 206e284a7c1SJames Feist [asyncResp, 20723a21a1cSEd Tanous index](const boost::system::error_code ec2, 208e284a7c1SJames Feist const std::vector<std::pair< 209e284a7c1SJames Feist std::string, 2101214b7e7SGunnar Mills std::variant<bool, std::string, uint64_t>>>& 2111214b7e7SGunnar Mills propertiesList) { 21223a21a1cSEd Tanous if (ec2) 213e284a7c1SJames Feist { 214e284a7c1SJames Feist // this interface isn't necessary 215e284a7c1SJames Feist return; 216e284a7c1SJames Feist } 217e284a7c1SJames Feist for (const std::pair< 218e284a7c1SJames Feist std::string, 2191214b7e7SGunnar Mills std::variant<bool, std::string, uint64_t>>& 2201214b7e7SGunnar Mills property : propertiesList) 221e284a7c1SJames Feist { 222e284a7c1SJames Feist // Store DBus properties that are also 223e284a7c1SJames Feist // Redfish properties with same name and a 224e284a7c1SJames Feist // string value 225e284a7c1SJames Feist const std::string& propertyName = 226e284a7c1SJames Feist property.first; 227e284a7c1SJames Feist nlohmann::json& object = 228e284a7c1SJames Feist asyncResp->res 229e284a7c1SJames Feist .jsonValue["StorageControllers"][index]; 230e284a7c1SJames Feist if ((propertyName == "PartNumber") || 231e284a7c1SJames Feist (propertyName == "SerialNumber") || 232e284a7c1SJames Feist (propertyName == "Manufacturer") || 233e284a7c1SJames Feist (propertyName == "Model")) 234e284a7c1SJames Feist { 235e284a7c1SJames Feist const std::string* value = 236e284a7c1SJames Feist std::get_if<std::string>( 237e284a7c1SJames Feist &property.second); 238e284a7c1SJames Feist if (value == nullptr) 239e284a7c1SJames Feist { 240e284a7c1SJames Feist // illegal property 241e284a7c1SJames Feist messages::internalError(asyncResp->res); 242e284a7c1SJames Feist continue; 243e284a7c1SJames Feist } 244e284a7c1SJames Feist object[propertyName] = *value; 245e284a7c1SJames Feist } 246e284a7c1SJames Feist } 247e284a7c1SJames Feist }, 248e284a7c1SJames Feist connectionName, path, "org.freedesktop.DBus.Properties", 249e284a7c1SJames Feist "GetAll", 250e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Decorator.Asset"); 251e284a7c1SJames Feist } 252e284a7c1SJames Feist 253e284a7c1SJames Feist // this is done after we know the json array will no longer be 254e284a7c1SJames Feist // resized, as json::array uses vector underneath and we need 255e284a7c1SJames Feist // references to its members that won't change 256e284a7c1SJames Feist size_t count = 0; 257e284a7c1SJames Feist for (const auto& [path, interfaceDict] : subtree) 258e284a7c1SJames Feist { 259e284a7c1SJames Feist auto subHealth = std::make_shared<HealthPopulate>( 260e284a7c1SJames Feist asyncResp, root[count]["Status"]); 261e284a7c1SJames Feist subHealth->inventory.emplace_back(path); 262e284a7c1SJames Feist health->inventory.emplace_back(path); 263e284a7c1SJames Feist health->children.emplace_back(subHealth); 264e284a7c1SJames Feist count++; 265e284a7c1SJames Feist } 266e284a7c1SJames Feist }, 267e284a7c1SJames Feist "xyz.openbmc_project.ObjectMapper", 268e284a7c1SJames Feist "/xyz/openbmc_project/object_mapper", 269e284a7c1SJames Feist "xyz.openbmc_project.ObjectMapper", "GetSubTree", 270e284a7c1SJames Feist "/xyz/openbmc_project/inventory", int32_t(0), 271e284a7c1SJames Feist std::array<const char*, 1>{ 272e284a7c1SJames Feist "xyz.openbmc_project.Inventory.Item.StorageController"}); 273a25aeccfSNikhil Potade } 274a25aeccfSNikhil Potade }; 275a25aeccfSNikhil Potade 276a25aeccfSNikhil Potade class Drive : public Node 277a25aeccfSNikhil Potade { 278a25aeccfSNikhil Potade public: 27952cc112dSEd Tanous Drive(App& app) : 280be13ceceSJames Feist Node(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/", 281a25aeccfSNikhil Potade std::string()) 282a25aeccfSNikhil Potade { 283a25aeccfSNikhil Potade entityPrivileges = { 284a25aeccfSNikhil Potade {boost::beast::http::verb::get, {{"Login"}}}, 285a25aeccfSNikhil Potade {boost::beast::http::verb::head, {{"Login"}}}, 286a25aeccfSNikhil Potade {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 287a25aeccfSNikhil Potade {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 288a25aeccfSNikhil Potade {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 289a25aeccfSNikhil Potade {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 290a25aeccfSNikhil Potade } 291a25aeccfSNikhil Potade 292a25aeccfSNikhil Potade private: 293*8d1b46d7Szhanghch05 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 294*8d1b46d7Szhanghch05 const crow::Request&, 295a25aeccfSNikhil Potade const std::vector<std::string>& params) override 296a25aeccfSNikhil Potade { 297e284a7c1SJames Feist if (params.size() != 1) 298e284a7c1SJames Feist { 299e284a7c1SJames Feist messages::internalError(asyncResp->res); 300e284a7c1SJames Feist return; 301e284a7c1SJames Feist } 302a25aeccfSNikhil Potade const std::string& driveId = params[0]; 303a25aeccfSNikhil Potade 304a25aeccfSNikhil Potade crow::connections::systemBus->async_method_call( 305e284a7c1SJames Feist [asyncResp, 306e284a7c1SJames Feist driveId](const boost::system::error_code ec, 307e284a7c1SJames Feist const crow::openbmc_mapper::GetSubTreeType& subtree) { 308a25aeccfSNikhil Potade if (ec) 309a25aeccfSNikhil Potade { 310a25aeccfSNikhil Potade BMCWEB_LOG_ERROR << "Drive mapper call error"; 311a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 312a25aeccfSNikhil Potade return; 313a25aeccfSNikhil Potade } 314a25aeccfSNikhil Potade 31523a21a1cSEd Tanous auto object2 = std::find_if( 316a25aeccfSNikhil Potade subtree.begin(), subtree.end(), [&driveId](auto& object) { 317a25aeccfSNikhil Potade const std::string& path = object.first; 318a25aeccfSNikhil Potade return boost::ends_with(path, "/" + driveId); 319a25aeccfSNikhil Potade }); 320a25aeccfSNikhil Potade 32123a21a1cSEd Tanous if (object2 == subtree.end()) 322a25aeccfSNikhil Potade { 323a25aeccfSNikhil Potade messages::resourceNotFound(asyncResp->res, "Drive", 324a25aeccfSNikhil Potade driveId); 325a25aeccfSNikhil Potade return; 326a25aeccfSNikhil Potade } 327a25aeccfSNikhil Potade 32823a21a1cSEd Tanous const std::string& path = object2->first; 329a25aeccfSNikhil Potade const std::vector< 3301214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 33123a21a1cSEd Tanous connectionNames = object2->second; 332a25aeccfSNikhil Potade 333a25aeccfSNikhil Potade asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive"; 334a25aeccfSNikhil Potade asyncResp->res.jsonValue["@odata.id"] = 335be13ceceSJames Feist "/redfish/v1/Systems/system/Storage/1/Drives/" + driveId; 3362ad9c2f6SJames Feist asyncResp->res.jsonValue["Name"] = driveId; 3372ad9c2f6SJames Feist asyncResp->res.jsonValue["Id"] = driveId; 338a25aeccfSNikhil Potade 339a25aeccfSNikhil Potade if (connectionNames.size() != 1) 340a25aeccfSNikhil Potade { 341a25aeccfSNikhil Potade BMCWEB_LOG_ERROR << "Connection size " 342a25aeccfSNikhil Potade << connectionNames.size() 343a25aeccfSNikhil Potade << ", greater than 1"; 344a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 345a25aeccfSNikhil Potade return; 346a25aeccfSNikhil Potade } 347a25aeccfSNikhil Potade 348a25aeccfSNikhil Potade getMainChassisId( 349*8d1b46d7Szhanghch05 asyncResp, 350*8d1b46d7Szhanghch05 [](const std::string& chassisId, 351*8d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { 352a25aeccfSNikhil Potade aRsp->res.jsonValue["Links"]["Chassis"] = { 353a25aeccfSNikhil Potade {"@odata.id", "/redfish/v1/Chassis/" + chassisId}}; 354a25aeccfSNikhil Potade }); 355a25aeccfSNikhil Potade 356a25aeccfSNikhil Potade const std::string& connectionName = connectionNames[0].first; 357a25aeccfSNikhil Potade crow::connections::systemBus->async_method_call( 358cb13a392SEd Tanous [asyncResp](const boost::system::error_code ec2, 359a25aeccfSNikhil Potade const std::vector<std::pair< 360a25aeccfSNikhil Potade std::string, 3611214b7e7SGunnar Mills std::variant<bool, std::string, uint64_t>>>& 3621214b7e7SGunnar Mills propertiesList) { 363cb13a392SEd Tanous if (ec2) 364a25aeccfSNikhil Potade { 365a25aeccfSNikhil Potade // this interface isn't necessary 366a25aeccfSNikhil Potade return; 367a25aeccfSNikhil Potade } 368a25aeccfSNikhil Potade for (const std::pair<std::string, 369a25aeccfSNikhil Potade std::variant<bool, std::string, 370a25aeccfSNikhil Potade uint64_t>>& property : 371a25aeccfSNikhil Potade propertiesList) 372a25aeccfSNikhil Potade { 373a25aeccfSNikhil Potade // Store DBus properties that are also 374a25aeccfSNikhil Potade // Redfish properties with same name and a 375a25aeccfSNikhil Potade // string value 376a25aeccfSNikhil Potade const std::string& propertyName = property.first; 377a25aeccfSNikhil Potade if ((propertyName == "PartNumber") || 378a25aeccfSNikhil Potade (propertyName == "SerialNumber") || 379a25aeccfSNikhil Potade (propertyName == "Manufacturer") || 380a25aeccfSNikhil Potade (propertyName == "Model")) 381a25aeccfSNikhil Potade { 382a25aeccfSNikhil Potade const std::string* value = 383a25aeccfSNikhil Potade std::get_if<std::string>(&property.second); 384a25aeccfSNikhil Potade if (value == nullptr) 385a25aeccfSNikhil Potade { 386a25aeccfSNikhil Potade // illegal property 387a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 388a25aeccfSNikhil Potade continue; 389a25aeccfSNikhil Potade } 390a25aeccfSNikhil Potade asyncResp->res.jsonValue[propertyName] = *value; 391a25aeccfSNikhil Potade } 392a25aeccfSNikhil Potade } 393a25aeccfSNikhil Potade }, 394a25aeccfSNikhil Potade connectionName, path, "org.freedesktop.DBus.Properties", 395a25aeccfSNikhil Potade "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset"); 396a25aeccfSNikhil Potade 397a25aeccfSNikhil Potade // default it to Enabled 398a25aeccfSNikhil Potade asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 399a25aeccfSNikhil Potade 4002ad9c2f6SJames Feist auto health = std::make_shared<HealthPopulate>(asyncResp); 401e284a7c1SJames Feist health->inventory.emplace_back(path); 4022ad9c2f6SJames Feist health->populate(); 4032ad9c2f6SJames Feist 404a25aeccfSNikhil Potade crow::connections::systemBus->async_method_call( 405cb13a392SEd Tanous [asyncResp, path](const boost::system::error_code ec2, 406a25aeccfSNikhil Potade const std::variant<bool> present) { 407a25aeccfSNikhil Potade // this interface isn't necessary, only check it if we 408a25aeccfSNikhil Potade // get a good return 409cb13a392SEd Tanous if (ec2) 410a25aeccfSNikhil Potade { 4112ad9c2f6SJames Feist return; 4122ad9c2f6SJames Feist } 413a25aeccfSNikhil Potade const bool* enabled = std::get_if<bool>(&present); 414a25aeccfSNikhil Potade if (enabled == nullptr) 415a25aeccfSNikhil Potade { 416a25aeccfSNikhil Potade BMCWEB_LOG_DEBUG << "Illegal property present"; 417a25aeccfSNikhil Potade messages::internalError(asyncResp->res); 418a25aeccfSNikhil Potade return; 419a25aeccfSNikhil Potade } 420a25aeccfSNikhil Potade if (!(*enabled)) 421a25aeccfSNikhil Potade { 422a25aeccfSNikhil Potade asyncResp->res.jsonValue["Status"]["State"] = 423a25aeccfSNikhil Potade "Disabled"; 424a25aeccfSNikhil Potade } 425a25aeccfSNikhil Potade }, 426a25aeccfSNikhil Potade connectionName, path, "org.freedesktop.DBus.Properties", 427a25aeccfSNikhil Potade "Get", "xyz.openbmc_project.Inventory.Item", "Present"); 42822984074SJames Feist 42922984074SJames Feist crow::connections::systemBus->async_method_call( 430cb13a392SEd Tanous [asyncResp](const boost::system::error_code ec2, 43122984074SJames Feist const std::variant<bool> rebuilding) { 43222984074SJames Feist // this interface isn't necessary, only check it if we 43322984074SJames Feist // get a good return 434cb13a392SEd Tanous if (ec2) 43522984074SJames Feist { 43622984074SJames Feist return; 43722984074SJames Feist } 43822984074SJames Feist const bool* updating = std::get_if<bool>(&rebuilding); 43922984074SJames Feist if (updating == nullptr) 44022984074SJames Feist { 44122984074SJames Feist BMCWEB_LOG_DEBUG << "Illegal property present"; 44222984074SJames Feist messages::internalError(asyncResp->res); 44322984074SJames Feist return; 44422984074SJames Feist } 44522984074SJames Feist 44622984074SJames Feist // updating and disabled in the backend shouldn't be 44722984074SJames Feist // able to be set at the same time, so we don't need to 44822984074SJames Feist // check for the race condition of these two calls 44922984074SJames Feist if ((*updating)) 45022984074SJames Feist { 45122984074SJames Feist asyncResp->res.jsonValue["Status"]["State"] = 45222984074SJames Feist "Updating"; 45322984074SJames Feist } 45422984074SJames Feist }, 45522984074SJames Feist connectionName, path, "org.freedesktop.DBus.Properties", 45622984074SJames Feist "Get", "xyz.openbmc_project.State.Drive", "Rebuilding"); 457a25aeccfSNikhil Potade }, 458a25aeccfSNikhil Potade "xyz.openbmc_project.ObjectMapper", 459a25aeccfSNikhil Potade "/xyz/openbmc_project/object_mapper", 460a25aeccfSNikhil Potade "xyz.openbmc_project.ObjectMapper", "GetSubTree", 461a25aeccfSNikhil Potade "/xyz/openbmc_project/inventory", int32_t(0), 462a25aeccfSNikhil Potade std::array<const char*, 1>{ 463a25aeccfSNikhil Potade "xyz.openbmc_project.Inventory.Item.Drive"}); 464a25aeccfSNikhil Potade } 465a25aeccfSNikhil Potade }; 466a25aeccfSNikhil Potade } // namespace redfish 467