1 /* 2 // Copyright (c) 2018 Intel Corporation 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 */ 16 #pragma once 17 18 #include "node.hpp" 19 20 namespace redfish 21 { 22 23 /** 24 * DBus types primitives for several generic DBus interfaces 25 * TODO consider move this to separate file into boost::dbus 26 */ 27 using GetManagedObjectsType = boost::container::flat_map< 28 sdbusplus::message::object_path, 29 boost::container::flat_map< 30 std::string, 31 boost::container::flat_map< 32 std::string, sdbusplus::message::variant< 33 std::string, bool, uint8_t, int16_t, uint16_t, 34 int32_t, uint32_t, int64_t, uint64_t, double>>>>; 35 36 class Manager : public Node 37 { 38 public: 39 Manager(CrowApp &app) : Node(app, "/redfish/v1/Managers/openbmc/") 40 { 41 Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc"; 42 Node::json["@odata.type"] = "#Manager.v1_3_0.Manager"; 43 Node::json["@odata.context"] = "/redfish/v1/$metadata#Manager.Manager"; 44 Node::json["Id"] = "openbmc"; 45 Node::json["Name"] = "OpenBmc Manager"; 46 Node::json["Description"] = "Baseboard Management Controller"; 47 Node::json["PowerState"] = "On"; 48 Node::json["ManagerType"] = "BMC"; 49 Node::json["UUID"] = 50 app.template getMiddleware<crow::persistent_data::Middleware>() 51 .systemUuid; 52 Node::json["Model"] = "OpenBmc"; // TODO(ed), get model 53 Node::json["EthernetInterfaces"] = { 54 {"@odata.id", "/redfish/v1/Managers/openbmc/EthernetInterfaces"}}; 55 56 entityPrivileges = { 57 {boost::beast::http::verb::get, {{"Login"}}}, 58 {boost::beast::http::verb::head, {{"Login"}}}, 59 {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 60 {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 61 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 62 {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 63 } 64 65 private: 66 void doGet(crow::Response &res, const crow::Request &req, 67 const std::vector<std::string> ¶ms) override 68 { 69 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 70 asyncResp->res.jsonValue = Node::json; 71 72 Node::json["DateTime"] = getDateTime(); 73 res.jsonValue = Node::json; 74 crow::connections::systemBus->async_method_call( 75 [asyncResp](const boost::system::error_code ec, 76 const GetManagedObjectsType &resp) { 77 if (ec) 78 { 79 BMCWEB_LOG_ERROR << "Error while getting Software Version"; 80 asyncResp->res.result( 81 boost::beast::http::status::internal_server_error); 82 return; 83 } 84 85 for (auto &objpath : resp) 86 { 87 for (auto &interface : objpath.second) 88 { 89 // If interface is xyz.openbmc_project.Software.Version, 90 // this is what we're looking for. 91 if (interface.first == 92 "xyz.openbmc_project.Software.Version") 93 { 94 // Cut out everyting until last "/", ... 95 const std::string &iface_id = objpath.first; 96 for (auto &property : interface.second) 97 { 98 if (property.first == "Version") 99 { 100 const std::string *value = 101 mapbox::getPtr<const std::string>( 102 property.second); 103 if (value == nullptr) 104 { 105 continue; 106 } 107 asyncResp->res 108 .jsonValue["FirmwareVersion"] = *value; 109 } 110 } 111 } 112 } 113 } 114 }, 115 "xyz.openbmc_project.Software.BMC.Updater", 116 "/xyz/openbmc_project/software", 117 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 118 } 119 120 std::string getDateTime() const 121 { 122 std::array<char, 128> dateTime; 123 std::string redfishDateTime("0000-00-00T00:00:00Z00:00"); 124 std::time_t time = std::time(nullptr); 125 126 if (std::strftime(dateTime.begin(), dateTime.size(), "%FT%T%z", 127 std::localtime(&time))) 128 { 129 // insert the colon required by the ISO 8601 standard 130 redfishDateTime = std::string(dateTime.data()); 131 redfishDateTime.insert(redfishDateTime.end() - 2, ':'); 132 } 133 134 return redfishDateTime; 135 } 136 }; 137 138 class ManagerCollection : public Node 139 { 140 public: 141 ManagerCollection(CrowApp &app) : Node(app, "/redfish/v1/Managers/") 142 { 143 Node::json["@odata.id"] = "/redfish/v1/Managers"; 144 Node::json["@odata.type"] = "#ManagerCollection.ManagerCollection"; 145 Node::json["@odata.context"] = 146 "/redfish/v1/$metadata#ManagerCollection.ManagerCollection"; 147 Node::json["Name"] = "Manager Collection"; 148 Node::json["Members@odata.count"] = 1; 149 Node::json["Members"] = { 150 {{"@odata.id", "/redfish/v1/Managers/openbmc"}}}; 151 152 entityPrivileges = { 153 {boost::beast::http::verb::get, {{"Login"}}}, 154 {boost::beast::http::verb::head, {{"Login"}}}, 155 {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 156 {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 157 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 158 {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 159 } 160 161 private: 162 void doGet(crow::Response &res, const crow::Request &req, 163 const std::vector<std::string> ¶ms) override 164 { 165 // Collections don't include the static data added by SubRoute because 166 // it has a duplicate entry for members 167 res.jsonValue["@odata.id"] = "/redfish/v1/Managers"; 168 res.jsonValue["@odata.type"] = "#ManagerCollection.ManagerCollection"; 169 res.jsonValue["@odata.context"] = 170 "/redfish/v1/$metadata#ManagerCollection.ManagerCollection"; 171 res.jsonValue["Name"] = "Manager Collection"; 172 res.jsonValue["Members@odata.count"] = 1; 173 res.jsonValue["Members"] = { 174 {{"@odata.id", "/redfish/v1/Managers/openbmc"}}}; 175 res.end(); 176 } 177 }; 178 179 } // namespace redfish 180