xref: /openbmc/bmcweb/features/redfish/lib/storage.hpp (revision ed3982131dcef2b499da36e674d2d21b2289ef29)
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 
217e860f15SJohn Edward Broadbent #include <app.hpp>
22*ed398213SEd Tanous #include <registries/privilege_registry.hpp>
23a25aeccfSNikhil Potade 
24a25aeccfSNikhil Potade namespace redfish
25a25aeccfSNikhil Potade {
267e860f15SJohn Edward Broadbent inline void requestRoutesStorageCollection(App& app)
27a25aeccfSNikhil Potade {
287e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/")
29*ed398213SEd Tanous         .privileges(redfish::privileges::getStorageCollection)
307e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
317e860f15SJohn Edward Broadbent             [](const crow::Request&,
327e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
338d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
348d1b46d7Szhanghch05                     "#StorageCollection.StorageCollection";
358d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] =
368d1b46d7Szhanghch05                     "/redfish/v1/Systems/system/Storage";
378d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Storage Collection";
388d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Members"] = {
39a25aeccfSNikhil Potade                     {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}};
408d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Members@odata.count"] = 1;
417e860f15SJohn Edward Broadbent             });
42a25aeccfSNikhil Potade }
43a25aeccfSNikhil Potade 
447e860f15SJohn Edward Broadbent inline void requestRoutesStorage(App& app)
45a25aeccfSNikhil Potade {
467e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/")
47*ed398213SEd Tanous         .privileges(redfish::privileges::getStorage)
487e860f15SJohn Edward Broadbent         .methods(
497e860f15SJohn Edward Broadbent             boost::beast::http::verb::
507e860f15SJohn Edward Broadbent                 get)([](const crow::Request&,
517e860f15SJohn Edward Broadbent                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
528d1b46d7Szhanghch05             asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage";
538d1b46d7Szhanghch05             asyncResp->res.jsonValue["@odata.id"] =
548d1b46d7Szhanghch05                 "/redfish/v1/Systems/system/Storage/1";
558d1b46d7Szhanghch05             asyncResp->res.jsonValue["Name"] = "Storage";
568d1b46d7Szhanghch05             asyncResp->res.jsonValue["Id"] = "1";
578d1b46d7Szhanghch05             asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
58a25aeccfSNikhil Potade 
59e284a7c1SJames Feist             auto health = std::make_shared<HealthPopulate>(asyncResp);
60e284a7c1SJames Feist             health->populate();
61e284a7c1SJames Feist 
62a25aeccfSNikhil Potade             crow::connections::systemBus->async_method_call(
637e860f15SJohn Edward Broadbent                 [asyncResp,
647e860f15SJohn Edward Broadbent                  health](const boost::system::error_code ec,
65a25aeccfSNikhil Potade                          const std::vector<std::string>& storageList) {
66a25aeccfSNikhil Potade                     nlohmann::json& storageArray =
67a25aeccfSNikhil Potade                         asyncResp->res.jsonValue["Drives"];
68a25aeccfSNikhil Potade                     storageArray = nlohmann::json::array();
697e860f15SJohn Edward Broadbent                     auto& count =
707e860f15SJohn Edward Broadbent                         asyncResp->res.jsonValue["Drives@odata.count"];
71e284a7c1SJames Feist                     count = 0;
722ad9c2f6SJames Feist 
73a25aeccfSNikhil Potade                     if (ec)
74a25aeccfSNikhil Potade                     {
75a25aeccfSNikhil Potade                         BMCWEB_LOG_ERROR << "Drive mapper call error";
76a25aeccfSNikhil Potade                         messages::internalError(asyncResp->res);
77a25aeccfSNikhil Potade                         return;
78a25aeccfSNikhil Potade                     }
792ad9c2f6SJames Feist 
80e284a7c1SJames Feist                     health->inventory.insert(health->inventory.end(),
81e284a7c1SJames Feist                                              storageList.begin(),
82e284a7c1SJames Feist                                              storageList.end());
832ad9c2f6SJames Feist 
84a25aeccfSNikhil Potade                     for (const std::string& objpath : storageList)
85a25aeccfSNikhil Potade                     {
86f23b7296SEd Tanous                         std::size_t lastPos = objpath.rfind('/');
87a25aeccfSNikhil Potade                         if (lastPos == std::string::npos ||
88a25aeccfSNikhil Potade                             (objpath.size() <= lastPos + 1))
89a25aeccfSNikhil Potade                         {
907e860f15SJohn Edward Broadbent                             BMCWEB_LOG_ERROR << "Failed to find '/' in "
917e860f15SJohn Edward Broadbent                                              << objpath;
92a25aeccfSNikhil Potade                             continue;
93a25aeccfSNikhil Potade                         }
94a25aeccfSNikhil Potade 
95a25aeccfSNikhil Potade                         storageArray.push_back(
96a25aeccfSNikhil Potade                             {{"@odata.id",
97be13ceceSJames Feist                               "/redfish/v1/Systems/system/Storage/1/Drives/" +
98a25aeccfSNikhil Potade                                   objpath.substr(lastPos + 1)}});
99a25aeccfSNikhil Potade                     }
100a25aeccfSNikhil Potade 
101e284a7c1SJames Feist                     count = storageArray.size();
102a25aeccfSNikhil Potade                 },
103a25aeccfSNikhil Potade                 "xyz.openbmc_project.ObjectMapper",
104a25aeccfSNikhil Potade                 "/xyz/openbmc_project/object_mapper",
105a25aeccfSNikhil Potade                 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
106a25aeccfSNikhil Potade                 "/xyz/openbmc_project/inventory", int32_t(0),
107a25aeccfSNikhil Potade                 std::array<const char*, 1>{
108a25aeccfSNikhil Potade                     "xyz.openbmc_project.Inventory.Item.Drive"});
109e284a7c1SJames Feist 
110e284a7c1SJames Feist             crow::connections::systemBus->async_method_call(
111e284a7c1SJames Feist                 [asyncResp,
112e284a7c1SJames Feist                  health](const boost::system::error_code ec,
113e284a7c1SJames Feist                          const crow::openbmc_mapper::GetSubTreeType& subtree) {
114e284a7c1SJames Feist                     if (ec || !subtree.size())
115e284a7c1SJames Feist                     {
116d819a420SJames Feist                         // doesn't have to be there
117e284a7c1SJames Feist                         return;
118e284a7c1SJames Feist                     }
119e284a7c1SJames Feist 
120e284a7c1SJames Feist                     nlohmann::json& root =
121e284a7c1SJames Feist                         asyncResp->res.jsonValue["StorageControllers"];
122e284a7c1SJames Feist                     root = nlohmann::json::array();
123e284a7c1SJames Feist                     for (const auto& [path, interfaceDict] : subtree)
124e284a7c1SJames Feist                     {
125f23b7296SEd Tanous                         std::size_t lastPos = path.rfind('/');
126e284a7c1SJames Feist                         if (lastPos == std::string::npos ||
127e284a7c1SJames Feist                             (path.size() <= lastPos + 1))
128e284a7c1SJames Feist                         {
1297e860f15SJohn Edward Broadbent                             BMCWEB_LOG_ERROR << "Failed to find '/' in "
1307e860f15SJohn Edward Broadbent                                              << path;
131e284a7c1SJames Feist                             return;
132e284a7c1SJames Feist                         }
133e284a7c1SJames Feist 
134e284a7c1SJames Feist                         if (interfaceDict.size() != 1)
135e284a7c1SJames Feist                         {
136e284a7c1SJames Feist                             BMCWEB_LOG_ERROR << "Connection size "
137e284a7c1SJames Feist                                              << interfaceDict.size()
138e284a7c1SJames Feist                                              << ", greater than 1";
139e284a7c1SJames Feist                             messages::internalError(asyncResp->res);
140e284a7c1SJames Feist                             return;
141e284a7c1SJames Feist                         }
142e284a7c1SJames Feist 
143e284a7c1SJames Feist                         const std::string& connectionName =
144e284a7c1SJames Feist                             interfaceDict.front().first;
145e284a7c1SJames Feist 
146e284a7c1SJames Feist                         size_t index = root.size();
147e284a7c1SJames Feist                         nlohmann::json& storageController =
148e284a7c1SJames Feist                             root.emplace_back(nlohmann::json::object());
149e284a7c1SJames Feist 
150e284a7c1SJames Feist                         std::string id = path.substr(lastPos + 1);
151e284a7c1SJames Feist 
152e284a7c1SJames Feist                         storageController["@odata.type"] =
153e284a7c1SJames Feist                             "#Storage.v1_7_0.StorageController";
154e284a7c1SJames Feist                         storageController["@odata.id"] =
155e284a7c1SJames Feist                             "/redfish/v1/Systems/system/Storage/1"
156e284a7c1SJames Feist                             "#/StorageControllers/" +
157e284a7c1SJames Feist                             std::to_string(index);
158e284a7c1SJames Feist                         storageController["Name"] = id;
159e284a7c1SJames Feist                         storageController["MemberId"] = id;
160e284a7c1SJames Feist                         storageController["Status"]["State"] = "Enabled";
161e284a7c1SJames Feist 
162e284a7c1SJames Feist                         crow::connections::systemBus->async_method_call(
1637e860f15SJohn Edward Broadbent                             [asyncResp,
1647e860f15SJohn Edward Broadbent                              index](const boost::system::error_code ec2,
165e284a7c1SJames Feist                                     const std::variant<bool> present) {
1667e860f15SJohn Edward Broadbent                                 // this interface isn't necessary, only check it
1677e860f15SJohn Edward Broadbent                                 // if we get a good return
16823a21a1cSEd Tanous                                 if (ec2)
169e284a7c1SJames Feist                                 {
170e284a7c1SJames Feist                                     return;
171e284a7c1SJames Feist                                 }
1727e860f15SJohn Edward Broadbent                                 const bool* enabled =
1737e860f15SJohn Edward Broadbent                                     std::get_if<bool>(&present);
174e284a7c1SJames Feist                                 if (enabled == nullptr)
175e284a7c1SJames Feist                                 {
1767e860f15SJohn Edward Broadbent                                     BMCWEB_LOG_DEBUG
1777e860f15SJohn Edward Broadbent                                         << "Illegal property present";
178e284a7c1SJames Feist                                     messages::internalError(asyncResp->res);
179e284a7c1SJames Feist                                     return;
180e284a7c1SJames Feist                                 }
181e284a7c1SJames Feist                                 if (!(*enabled))
182e284a7c1SJames Feist                                 {
183e284a7c1SJames Feist                                     asyncResp->res
184e284a7c1SJames Feist                                         .jsonValue["StorageControllers"][index]
1857e860f15SJohn Edward Broadbent                                                   ["Status"]["State"] =
1867e860f15SJohn Edward Broadbent                                         "Disabled";
187e284a7c1SJames Feist                                 }
188e284a7c1SJames Feist                             },
1897e860f15SJohn Edward Broadbent                             connectionName, path,
1907e860f15SJohn Edward Broadbent                             "org.freedesktop.DBus.Properties", "Get",
1917e860f15SJohn Edward Broadbent                             "xyz.openbmc_project.Inventory.Item", "Present");
192e284a7c1SJames Feist 
193e284a7c1SJames Feist                         crow::connections::systemBus->async_method_call(
1947e860f15SJohn Edward Broadbent                             [asyncResp, index](
1957e860f15SJohn Edward Broadbent                                 const boost::system::error_code ec2,
1967e860f15SJohn Edward Broadbent                                 const std::vector<std::pair<
1977e860f15SJohn Edward Broadbent                                     std::string,
1987e860f15SJohn Edward Broadbent                                     std::variant<bool, std::string, uint64_t>>>&
1997e860f15SJohn Edward Broadbent                                     propertiesList) {
2007e860f15SJohn Edward Broadbent                                 if (ec2)
2017e860f15SJohn Edward Broadbent                                 {
2027e860f15SJohn Edward Broadbent                                     // this interface isn't necessary
2037e860f15SJohn Edward Broadbent                                     return;
2047e860f15SJohn Edward Broadbent                                 }
2057e860f15SJohn Edward Broadbent                                 for (const std::pair<
2067e860f15SJohn Edward Broadbent                                          std::string,
2077e860f15SJohn Edward Broadbent                                          std::variant<bool, std::string,
2087e860f15SJohn Edward Broadbent                                                       uint64_t>>& property :
2097e860f15SJohn Edward Broadbent                                      propertiesList)
2107e860f15SJohn Edward Broadbent                                 {
2117e860f15SJohn Edward Broadbent                                     // Store DBus properties that are also
2127e860f15SJohn Edward Broadbent                                     // Redfish properties with same name and a
2137e860f15SJohn Edward Broadbent                                     // string value
2147e860f15SJohn Edward Broadbent                                     const std::string& propertyName =
2157e860f15SJohn Edward Broadbent                                         property.first;
2167e860f15SJohn Edward Broadbent                                     nlohmann::json& object =
2177e860f15SJohn Edward Broadbent                                         asyncResp->res
2187e860f15SJohn Edward Broadbent                                             .jsonValue["StorageControllers"]
2197e860f15SJohn Edward Broadbent                                                       [index];
2207e860f15SJohn Edward Broadbent                                     if ((propertyName == "PartNumber") ||
2217e860f15SJohn Edward Broadbent                                         (propertyName == "SerialNumber") ||
2227e860f15SJohn Edward Broadbent                                         (propertyName == "Manufacturer") ||
2237e860f15SJohn Edward Broadbent                                         (propertyName == "Model"))
2247e860f15SJohn Edward Broadbent                                     {
2257e860f15SJohn Edward Broadbent                                         const std::string* value =
2267e860f15SJohn Edward Broadbent                                             std::get_if<std::string>(
2277e860f15SJohn Edward Broadbent                                                 &property.second);
2287e860f15SJohn Edward Broadbent                                         if (value == nullptr)
2297e860f15SJohn Edward Broadbent                                         {
2307e860f15SJohn Edward Broadbent                                             // illegal property
2317e860f15SJohn Edward Broadbent                                             messages::internalError(
2327e860f15SJohn Edward Broadbent                                                 asyncResp->res);
2337e860f15SJohn Edward Broadbent                                             return;
2347e860f15SJohn Edward Broadbent                                         }
2357e860f15SJohn Edward Broadbent                                         object[propertyName] = *value;
2367e860f15SJohn Edward Broadbent                                     }
2377e860f15SJohn Edward Broadbent                                 }
2387e860f15SJohn Edward Broadbent                             },
2397e860f15SJohn Edward Broadbent                             connectionName, path,
2407e860f15SJohn Edward Broadbent                             "org.freedesktop.DBus.Properties", "GetAll",
2417e860f15SJohn Edward Broadbent                             "xyz.openbmc_project.Inventory.Decorator.Asset");
2427e860f15SJohn Edward Broadbent                     }
2437e860f15SJohn Edward Broadbent 
2447e860f15SJohn Edward Broadbent                     // this is done after we know the json array will no longer
2457e860f15SJohn Edward Broadbent                     // be resized, as json::array uses vector underneath and we
2467e860f15SJohn Edward Broadbent                     // need references to its members that won't change
2477e860f15SJohn Edward Broadbent                     size_t count = 0;
2487e860f15SJohn Edward Broadbent                     for (const auto& [path, interfaceDict] : subtree)
2497e860f15SJohn Edward Broadbent                     {
2507e860f15SJohn Edward Broadbent                         auto subHealth = std::make_shared<HealthPopulate>(
2517e860f15SJohn Edward Broadbent                             asyncResp, root[count]["Status"]);
2527e860f15SJohn Edward Broadbent                         subHealth->inventory.emplace_back(path);
2537e860f15SJohn Edward Broadbent                         health->inventory.emplace_back(path);
2547e860f15SJohn Edward Broadbent                         health->children.emplace_back(subHealth);
2557e860f15SJohn Edward Broadbent                         count++;
2567e860f15SJohn Edward Broadbent                     }
2577e860f15SJohn Edward Broadbent                 },
2587e860f15SJohn Edward Broadbent                 "xyz.openbmc_project.ObjectMapper",
2597e860f15SJohn Edward Broadbent                 "/xyz/openbmc_project/object_mapper",
2607e860f15SJohn Edward Broadbent                 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
2617e860f15SJohn Edward Broadbent                 "/xyz/openbmc_project/inventory", int32_t(0),
2627e860f15SJohn Edward Broadbent                 std::array<const char*, 1>{
2637e860f15SJohn Edward Broadbent                     "xyz.openbmc_project.Inventory.Item.StorageController"});
2647e860f15SJohn Edward Broadbent         });
2657e860f15SJohn Edward Broadbent }
2667e860f15SJohn Edward Broadbent 
2677e860f15SJohn Edward Broadbent inline void requestRoutesDrive(App& app)
2687e860f15SJohn Edward Broadbent {
2697e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/")
270*ed398213SEd Tanous         .privileges(redfish::privileges::getDrive)
2717e860f15SJohn Edward Broadbent         .methods(
2727e860f15SJohn Edward Broadbent             boost::beast::http::verb::get)([](const crow::Request&,
2737e860f15SJohn Edward Broadbent                                               const std::shared_ptr<
2747e860f15SJohn Edward Broadbent                                                   bmcweb::AsyncResp>& asyncResp,
2757e860f15SJohn Edward Broadbent                                               const std::string& driveId) {
2767e860f15SJohn Edward Broadbent             crow::connections::systemBus->async_method_call(
277e284a7c1SJames Feist                 [asyncResp,
2787e860f15SJohn Edward Broadbent                  driveId](const boost::system::error_code ec,
2797e860f15SJohn Edward Broadbent                           const crow::openbmc_mapper::GetSubTreeType& subtree) {
2807e860f15SJohn Edward Broadbent                     if (ec)
2817e860f15SJohn Edward Broadbent                     {
2827e860f15SJohn Edward Broadbent                         BMCWEB_LOG_ERROR << "Drive mapper call error";
2837e860f15SJohn Edward Broadbent                         messages::internalError(asyncResp->res);
2847e860f15SJohn Edward Broadbent                         return;
2857e860f15SJohn Edward Broadbent                     }
2867e860f15SJohn Edward Broadbent 
2877e860f15SJohn Edward Broadbent                     auto object2 = std::find_if(
2887e860f15SJohn Edward Broadbent                         subtree.begin(), subtree.end(),
2897e860f15SJohn Edward Broadbent                         [&driveId](auto& object) {
2907e860f15SJohn Edward Broadbent                             const std::string& path = object.first;
2917e860f15SJohn Edward Broadbent                             return boost::ends_with(path, "/" + driveId);
2927e860f15SJohn Edward Broadbent                         });
2937e860f15SJohn Edward Broadbent 
2947e860f15SJohn Edward Broadbent                     if (object2 == subtree.end())
2957e860f15SJohn Edward Broadbent                     {
2967e860f15SJohn Edward Broadbent                         messages::resourceNotFound(asyncResp->res, "Drive",
2977e860f15SJohn Edward Broadbent                                                    driveId);
2987e860f15SJohn Edward Broadbent                         return;
2997e860f15SJohn Edward Broadbent                     }
3007e860f15SJohn Edward Broadbent 
3017e860f15SJohn Edward Broadbent                     const std::string& path = object2->first;
3027e860f15SJohn Edward Broadbent                     const std::vector<
3037e860f15SJohn Edward Broadbent                         std::pair<std::string, std::vector<std::string>>>&
3047e860f15SJohn Edward Broadbent                         connectionNames = object2->second;
3057e860f15SJohn Edward Broadbent 
3067e860f15SJohn Edward Broadbent                     asyncResp->res.jsonValue["@odata.type"] =
3077e860f15SJohn Edward Broadbent                         "#Drive.v1_7_0.Drive";
3087e860f15SJohn Edward Broadbent                     asyncResp->res.jsonValue["@odata.id"] =
3097e860f15SJohn Edward Broadbent                         "/redfish/v1/Systems/system/Storage/1/Drives/" +
3107e860f15SJohn Edward Broadbent                         driveId;
3117e860f15SJohn Edward Broadbent                     asyncResp->res.jsonValue["Name"] = driveId;
3127e860f15SJohn Edward Broadbent                     asyncResp->res.jsonValue["Id"] = driveId;
3137e860f15SJohn Edward Broadbent 
3147e860f15SJohn Edward Broadbent                     if (connectionNames.size() != 1)
3157e860f15SJohn Edward Broadbent                     {
3167e860f15SJohn Edward Broadbent                         BMCWEB_LOG_ERROR << "Connection size "
3177e860f15SJohn Edward Broadbent                                          << connectionNames.size()
3187e860f15SJohn Edward Broadbent                                          << ", greater than 1";
3197e860f15SJohn Edward Broadbent                         messages::internalError(asyncResp->res);
3207e860f15SJohn Edward Broadbent                         return;
3217e860f15SJohn Edward Broadbent                     }
3227e860f15SJohn Edward Broadbent 
3237e860f15SJohn Edward Broadbent                     getMainChassisId(
3247e860f15SJohn Edward Broadbent                         asyncResp,
3257e860f15SJohn Edward Broadbent                         [](const std::string& chassisId,
3267e860f15SJohn Edward Broadbent                            const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3277e860f15SJohn Edward Broadbent                             aRsp->res.jsonValue["Links"]["Chassis"] = {
3287e860f15SJohn Edward Broadbent                                 {"@odata.id",
3297e860f15SJohn Edward Broadbent                                  "/redfish/v1/Chassis/" + chassisId}};
3307e860f15SJohn Edward Broadbent                         });
3317e860f15SJohn Edward Broadbent 
3327e860f15SJohn Edward Broadbent                     const std::string& connectionName =
3337e860f15SJohn Edward Broadbent                         connectionNames[0].first;
3347e860f15SJohn Edward Broadbent                     crow::connections::systemBus->async_method_call(
3357e860f15SJohn Edward Broadbent                         [asyncResp](
3367e860f15SJohn Edward Broadbent                             const boost::system::error_code ec2,
337e284a7c1SJames Feist                             const std::vector<std::pair<
338e284a7c1SJames Feist                                 std::string,
3391214b7e7SGunnar Mills                                 std::variant<bool, std::string, uint64_t>>>&
3401214b7e7SGunnar Mills                                 propertiesList) {
34123a21a1cSEd Tanous                             if (ec2)
342e284a7c1SJames Feist                             {
343e284a7c1SJames Feist                                 // this interface isn't necessary
344e284a7c1SJames Feist                                 return;
345e284a7c1SJames Feist                             }
346e284a7c1SJames Feist                             for (const std::pair<
347e284a7c1SJames Feist                                      std::string,
3481214b7e7SGunnar Mills                                      std::variant<bool, std::string, uint64_t>>&
3491214b7e7SGunnar Mills                                      property : propertiesList)
350e284a7c1SJames Feist                             {
351e284a7c1SJames Feist                                 // Store DBus properties that are also
352e284a7c1SJames Feist                                 // Redfish properties with same name and a
353e284a7c1SJames Feist                                 // string value
354e284a7c1SJames Feist                                 const std::string& propertyName =
355e284a7c1SJames Feist                                     property.first;
356e284a7c1SJames Feist                                 if ((propertyName == "PartNumber") ||
357e284a7c1SJames Feist                                     (propertyName == "SerialNumber") ||
358e284a7c1SJames Feist                                     (propertyName == "Manufacturer") ||
359e284a7c1SJames Feist                                     (propertyName == "Model"))
360e284a7c1SJames Feist                                 {
361e284a7c1SJames Feist                                     const std::string* value =
362e284a7c1SJames Feist                                         std::get_if<std::string>(
363e284a7c1SJames Feist                                             &property.second);
364e284a7c1SJames Feist                                     if (value == nullptr)
365e284a7c1SJames Feist                                     {
366e284a7c1SJames Feist                                         // illegal property
367e284a7c1SJames Feist                                         messages::internalError(asyncResp->res);
368601af5edSChicago Duan                                         return;
369e284a7c1SJames Feist                                     }
3707e860f15SJohn Edward Broadbent                                     asyncResp->res.jsonValue[propertyName] =
3717e860f15SJohn Edward Broadbent                                         *value;
372e284a7c1SJames Feist                                 }
373e284a7c1SJames Feist                             }
374e284a7c1SJames Feist                         },
375e284a7c1SJames Feist                         connectionName, path, "org.freedesktop.DBus.Properties",
376e284a7c1SJames Feist                         "GetAll",
377e284a7c1SJames Feist                         "xyz.openbmc_project.Inventory.Decorator.Asset");
378a25aeccfSNikhil Potade 
379a25aeccfSNikhil Potade                     // default it to Enabled
380a25aeccfSNikhil Potade                     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
381a25aeccfSNikhil Potade 
3822ad9c2f6SJames Feist                     auto health = std::make_shared<HealthPopulate>(asyncResp);
383e284a7c1SJames Feist                     health->inventory.emplace_back(path);
3842ad9c2f6SJames Feist                     health->populate();
3852ad9c2f6SJames Feist 
386a25aeccfSNikhil Potade                     crow::connections::systemBus->async_method_call(
387cb13a392SEd Tanous                         [asyncResp, path](const boost::system::error_code ec2,
388a25aeccfSNikhil Potade                                           const std::variant<bool> present) {
3897e860f15SJohn Edward Broadbent                             // this interface isn't necessary, only check it if
3907e860f15SJohn Edward Broadbent                             // we get a good return
391cb13a392SEd Tanous                             if (ec2)
392a25aeccfSNikhil Potade                             {
3932ad9c2f6SJames Feist                                 return;
3942ad9c2f6SJames Feist                             }
395a25aeccfSNikhil Potade                             const bool* enabled = std::get_if<bool>(&present);
396a25aeccfSNikhil Potade                             if (enabled == nullptr)
397a25aeccfSNikhil Potade                             {
398a25aeccfSNikhil Potade                                 BMCWEB_LOG_DEBUG << "Illegal property present";
399a25aeccfSNikhil Potade                                 messages::internalError(asyncResp->res);
400a25aeccfSNikhil Potade                                 return;
401a25aeccfSNikhil Potade                             }
402a25aeccfSNikhil Potade                             if (!(*enabled))
403a25aeccfSNikhil Potade                             {
404a25aeccfSNikhil Potade                                 asyncResp->res.jsonValue["Status"]["State"] =
405a25aeccfSNikhil Potade                                     "Disabled";
406a25aeccfSNikhil Potade                             }
407a25aeccfSNikhil Potade                         },
408a25aeccfSNikhil Potade                         connectionName, path, "org.freedesktop.DBus.Properties",
409a25aeccfSNikhil Potade                         "Get", "xyz.openbmc_project.Inventory.Item", "Present");
41022984074SJames Feist 
41122984074SJames Feist                     crow::connections::systemBus->async_method_call(
412cb13a392SEd Tanous                         [asyncResp](const boost::system::error_code ec2,
41322984074SJames Feist                                     const std::variant<bool> rebuilding) {
4147e860f15SJohn Edward Broadbent                             // this interface isn't necessary, only check it if
4157e860f15SJohn Edward Broadbent                             // we get a good return
416cb13a392SEd Tanous                             if (ec2)
41722984074SJames Feist                             {
41822984074SJames Feist                                 return;
41922984074SJames Feist                             }
4207e860f15SJohn Edward Broadbent                             const bool* updating =
4217e860f15SJohn Edward Broadbent                                 std::get_if<bool>(&rebuilding);
42222984074SJames Feist                             if (updating == nullptr)
42322984074SJames Feist                             {
42422984074SJames Feist                                 BMCWEB_LOG_DEBUG << "Illegal property present";
42522984074SJames Feist                                 messages::internalError(asyncResp->res);
42622984074SJames Feist                                 return;
42722984074SJames Feist                             }
42822984074SJames Feist 
42922984074SJames Feist                             // updating and disabled in the backend shouldn't be
4307e860f15SJohn Edward Broadbent                             // able to be set at the same time, so we don't need
4317e860f15SJohn Edward Broadbent                             // to check for the race condition of these two
4327e860f15SJohn Edward Broadbent                             // calls
43322984074SJames Feist                             if ((*updating))
43422984074SJames Feist                             {
43522984074SJames Feist                                 asyncResp->res.jsonValue["Status"]["State"] =
43622984074SJames Feist                                     "Updating";
43722984074SJames Feist                             }
43822984074SJames Feist                         },
43922984074SJames Feist                         connectionName, path, "org.freedesktop.DBus.Properties",
44022984074SJames Feist                         "Get", "xyz.openbmc_project.State.Drive", "Rebuilding");
441a25aeccfSNikhil Potade                 },
442a25aeccfSNikhil Potade                 "xyz.openbmc_project.ObjectMapper",
443a25aeccfSNikhil Potade                 "/xyz/openbmc_project/object_mapper",
444a25aeccfSNikhil Potade                 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
445a25aeccfSNikhil Potade                 "/xyz/openbmc_project/inventory", int32_t(0),
446a25aeccfSNikhil Potade                 std::array<const char*, 1>{
447a25aeccfSNikhil Potade                     "xyz.openbmc_project.Inventory.Item.Drive"});
4487e860f15SJohn Edward Broadbent         });
449a25aeccfSNikhil Potade }
450a25aeccfSNikhil Potade } // namespace redfish
451