19c310685SBorawski.Lukasz /* 29c310685SBorawski.Lukasz // Copyright (c) 2018 Intel Corporation 39c310685SBorawski.Lukasz // 49c310685SBorawski.Lukasz // Licensed under the Apache License, Version 2.0 (the "License"); 59c310685SBorawski.Lukasz // you may not use this file except in compliance with the License. 69c310685SBorawski.Lukasz // You may obtain a copy of the License at 79c310685SBorawski.Lukasz // 89c310685SBorawski.Lukasz // http://www.apache.org/licenses/LICENSE-2.0 99c310685SBorawski.Lukasz // 109c310685SBorawski.Lukasz // Unless required by applicable law or agreed to in writing, software 119c310685SBorawski.Lukasz // distributed under the License is distributed on an "AS IS" BASIS, 129c310685SBorawski.Lukasz // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139c310685SBorawski.Lukasz // See the License for the specific language governing permissions and 149c310685SBorawski.Lukasz // limitations under the License. 159c310685SBorawski.Lukasz */ 169c310685SBorawski.Lukasz #pragma once 179c310685SBorawski.Lukasz 189c310685SBorawski.Lukasz #include "node.hpp" 199c310685SBorawski.Lukasz 201abe55efSEd Tanous namespace redfish 211abe55efSEd Tanous { 229c310685SBorawski.Lukasz 23*ca537928SJennifer Lee /** 24*ca537928SJennifer Lee * DBus types primitives for several generic DBus interfaces 25*ca537928SJennifer Lee * TODO consider move this to separate file into boost::dbus 26*ca537928SJennifer Lee */ 27*ca537928SJennifer Lee using GetManagedObjectsType = boost::container::flat_map< 28*ca537928SJennifer Lee sdbusplus::message::object_path, 29*ca537928SJennifer Lee boost::container::flat_map< 30*ca537928SJennifer Lee std::string, 31*ca537928SJennifer Lee boost::container::flat_map< 32*ca537928SJennifer Lee std::string, sdbusplus::message::variant< 33*ca537928SJennifer Lee std::string, bool, uint8_t, int16_t, uint16_t, 34*ca537928SJennifer Lee int32_t, uint32_t, int64_t, uint64_t, double>>>>; 35*ca537928SJennifer Lee 361abe55efSEd Tanous class Manager : public Node 371abe55efSEd Tanous { 389c310685SBorawski.Lukasz public: 391abe55efSEd Tanous Manager(CrowApp &app) : Node(app, "/redfish/v1/Managers/openbmc/") 401abe55efSEd Tanous { 419c310685SBorawski.Lukasz Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc"; 429c310685SBorawski.Lukasz Node::json["@odata.type"] = "#Manager.v1_3_0.Manager"; 439c310685SBorawski.Lukasz Node::json["@odata.context"] = "/redfish/v1/$metadata#Manager.Manager"; 449c310685SBorawski.Lukasz Node::json["Id"] = "openbmc"; 459c310685SBorawski.Lukasz Node::json["Name"] = "OpenBmc Manager"; 469c310685SBorawski.Lukasz Node::json["Description"] = "Baseboard Management Controller"; 479c310685SBorawski.Lukasz Node::json["PowerState"] = "On"; 48*ca537928SJennifer Lee Node::json["ManagerType"] = "BMC"; 499c310685SBorawski.Lukasz Node::json["UUID"] = 5055c7b7a2SEd Tanous app.template getMiddleware<crow::persistent_data::Middleware>() 5155c7b7a2SEd Tanous .systemUuid; 529c310685SBorawski.Lukasz Node::json["Model"] = "OpenBmc"; // TODO(ed), get model 53*ca537928SJennifer Lee Node::json["EthernetInterfaces"] = { 54*ca537928SJennifer Lee {"@odata.id", "/redfish/v1/Managers/openbmc/EthernetInterfaces"}}; 553ebd75f7SEd Tanous 56a434f2bdSEd Tanous entityPrivileges = { 57a434f2bdSEd Tanous {boost::beast::http::verb::get, {{"Login"}}}, 58e0d918bcSEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 59e0d918bcSEd Tanous {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 60e0d918bcSEd Tanous {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 61e0d918bcSEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 62e0d918bcSEd Tanous {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 639c310685SBorawski.Lukasz } 649c310685SBorawski.Lukasz 659c310685SBorawski.Lukasz private: 6655c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 671abe55efSEd Tanous const std::vector<std::string> ¶ms) override 681abe55efSEd Tanous { 69*ca537928SJennifer Lee std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 70*ca537928SJennifer Lee asyncResp->res.jsonValue = Node::json; 71*ca537928SJennifer Lee 729c310685SBorawski.Lukasz Node::json["DateTime"] = getDateTime(); 7355c7b7a2SEd Tanous res.jsonValue = Node::json; 74*ca537928SJennifer Lee crow::connections::systemBus->async_method_call( 75*ca537928SJennifer Lee [asyncResp](const boost::system::error_code ec, 76*ca537928SJennifer Lee const GetManagedObjectsType &resp) { 77*ca537928SJennifer Lee if (ec) 78*ca537928SJennifer Lee { 79*ca537928SJennifer Lee BMCWEB_LOG_ERROR << "Error while getting Software Version"; 80*ca537928SJennifer Lee asyncResp->res.result( 81*ca537928SJennifer Lee boost::beast::http::status::internal_server_error); 82*ca537928SJennifer Lee return; 83*ca537928SJennifer Lee } 84*ca537928SJennifer Lee 85*ca537928SJennifer Lee for (auto &objpath : resp) 86*ca537928SJennifer Lee { 87*ca537928SJennifer Lee for (auto &interface : objpath.second) 88*ca537928SJennifer Lee { 89*ca537928SJennifer Lee // If interface is xyz.openbmc_project.Software.Version, 90*ca537928SJennifer Lee // this is what we're looking for. 91*ca537928SJennifer Lee if (interface.first == 92*ca537928SJennifer Lee "xyz.openbmc_project.Software.Version") 93*ca537928SJennifer Lee { 94*ca537928SJennifer Lee // Cut out everyting until last "/", ... 95*ca537928SJennifer Lee const std::string &iface_id = objpath.first; 96*ca537928SJennifer Lee for (auto &property : interface.second) 97*ca537928SJennifer Lee { 98*ca537928SJennifer Lee if (property.first == "Version") 99*ca537928SJennifer Lee { 100*ca537928SJennifer Lee const std::string *value = 101*ca537928SJennifer Lee mapbox::getPtr<const std::string>( 102*ca537928SJennifer Lee property.second); 103*ca537928SJennifer Lee if (value == nullptr) 104*ca537928SJennifer Lee { 105*ca537928SJennifer Lee continue; 106*ca537928SJennifer Lee } 107*ca537928SJennifer Lee asyncResp->res 108*ca537928SJennifer Lee .jsonValue["FirmwareVersion"] = *value; 109*ca537928SJennifer Lee } 110*ca537928SJennifer Lee } 111*ca537928SJennifer Lee } 112*ca537928SJennifer Lee } 113*ca537928SJennifer Lee } 114*ca537928SJennifer Lee }, 115*ca537928SJennifer Lee "xyz.openbmc_project.Software.BMC.Updater", 116*ca537928SJennifer Lee "/xyz/openbmc_project/software", 117*ca537928SJennifer Lee "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 1189c310685SBorawski.Lukasz } 1199c310685SBorawski.Lukasz 1201abe55efSEd Tanous std::string getDateTime() const 1211abe55efSEd Tanous { 1229c310685SBorawski.Lukasz std::array<char, 128> dateTime; 1239c310685SBorawski.Lukasz std::string redfishDateTime("0000-00-00T00:00:00Z00:00"); 1249c310685SBorawski.Lukasz std::time_t time = std::time(nullptr); 1259c310685SBorawski.Lukasz 1269c310685SBorawski.Lukasz if (std::strftime(dateTime.begin(), dateTime.size(), "%FT%T%z", 1271abe55efSEd Tanous std::localtime(&time))) 1281abe55efSEd Tanous { 1299c310685SBorawski.Lukasz // insert the colon required by the ISO 8601 standard 1309c310685SBorawski.Lukasz redfishDateTime = std::string(dateTime.data()); 1319c310685SBorawski.Lukasz redfishDateTime.insert(redfishDateTime.end() - 2, ':'); 1329c310685SBorawski.Lukasz } 1339c310685SBorawski.Lukasz 1349c310685SBorawski.Lukasz return redfishDateTime; 1359c310685SBorawski.Lukasz } 1369c310685SBorawski.Lukasz }; 1379c310685SBorawski.Lukasz 1381abe55efSEd Tanous class ManagerCollection : public Node 1391abe55efSEd Tanous { 1409c310685SBorawski.Lukasz public: 1411abe55efSEd Tanous ManagerCollection(CrowApp &app) : Node(app, "/redfish/v1/Managers/") 1421abe55efSEd Tanous { 1439c310685SBorawski.Lukasz Node::json["@odata.id"] = "/redfish/v1/Managers"; 1449c310685SBorawski.Lukasz Node::json["@odata.type"] = "#ManagerCollection.ManagerCollection"; 1459c310685SBorawski.Lukasz Node::json["@odata.context"] = 1469c310685SBorawski.Lukasz "/redfish/v1/$metadata#ManagerCollection.ManagerCollection"; 1479c310685SBorawski.Lukasz Node::json["Name"] = "Manager Collection"; 1489c310685SBorawski.Lukasz Node::json["Members@odata.count"] = 1; 1491abe55efSEd Tanous Node::json["Members"] = { 1501abe55efSEd Tanous {{"@odata.id", "/redfish/v1/Managers/openbmc"}}}; 1513ebd75f7SEd Tanous 152a434f2bdSEd Tanous entityPrivileges = { 153a434f2bdSEd Tanous {boost::beast::http::verb::get, {{"Login"}}}, 154e0d918bcSEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 155e0d918bcSEd Tanous {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 156e0d918bcSEd Tanous {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 157e0d918bcSEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 158e0d918bcSEd Tanous {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 1599c310685SBorawski.Lukasz } 1609c310685SBorawski.Lukasz 1619c310685SBorawski.Lukasz private: 16255c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 1631abe55efSEd Tanous const std::vector<std::string> ¶ms) override 1641abe55efSEd Tanous { 1651abe55efSEd Tanous // Collections don't include the static data added by SubRoute because 1661abe55efSEd Tanous // it has a duplicate entry for members 16755c7b7a2SEd Tanous res.jsonValue["@odata.id"] = "/redfish/v1/Managers"; 16855c7b7a2SEd Tanous res.jsonValue["@odata.type"] = "#ManagerCollection.ManagerCollection"; 16955c7b7a2SEd Tanous res.jsonValue["@odata.context"] = 17055c7b7a2SEd Tanous "/redfish/v1/$metadata#ManagerCollection.ManagerCollection"; 17155c7b7a2SEd Tanous res.jsonValue["Name"] = "Manager Collection"; 17255c7b7a2SEd Tanous res.jsonValue["Members@odata.count"] = 1; 17355c7b7a2SEd Tanous res.jsonValue["Members"] = { 17455c7b7a2SEd Tanous {{"@odata.id", "/redfish/v1/Managers/openbmc"}}}; 1759c310685SBorawski.Lukasz res.end(); 1769c310685SBorawski.Lukasz } 1779c310685SBorawski.Lukasz }; 1789c310685SBorawski.Lukasz 1799c310685SBorawski.Lukasz } // namespace redfish 180