1e37f8451SRapkiewicz, Pawel /* 2e37f8451SRapkiewicz, Pawel // Copyright (c) 2018 Intel Corporation 3e37f8451SRapkiewicz, Pawel // 4e37f8451SRapkiewicz, Pawel // Licensed under the Apache License, Version 2.0 (the "License"); 5e37f8451SRapkiewicz, Pawel // you may not use this file except in compliance with the License. 6e37f8451SRapkiewicz, Pawel // You may obtain a copy of the License at 7e37f8451SRapkiewicz, Pawel // 8e37f8451SRapkiewicz, Pawel // http://www.apache.org/licenses/LICENSE-2.0 9e37f8451SRapkiewicz, Pawel // 10e37f8451SRapkiewicz, Pawel // Unless required by applicable law or agreed to in writing, software 11e37f8451SRapkiewicz, Pawel // distributed under the License is distributed on an "AS IS" BASIS, 12e37f8451SRapkiewicz, Pawel // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e37f8451SRapkiewicz, Pawel // See the License for the specific language governing permissions and 14e37f8451SRapkiewicz, Pawel // limitations under the License. 15e37f8451SRapkiewicz, Pawel */ 16e37f8451SRapkiewicz, Pawel #pragma once 17e37f8451SRapkiewicz, Pawel 18b49ac873SJames Feist #include "health.hpp" 191c8fba97SJames Feist #include "led.hpp" 201abe55efSEd Tanous 217e860f15SJohn Edward Broadbent #include <app.hpp> 22168e20c1SEd Tanous #include <dbus_utility.hpp> 23ed398213SEd Tanous #include <registries/privilege_registry.hpp> 241e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 2502f6ff19SGunnar Mills #include <utils/collection.hpp> 261214b7e7SGunnar Mills 271abe55efSEd Tanous namespace redfish 281abe55efSEd Tanous { 29e37f8451SRapkiewicz, Pawel 30e37f8451SRapkiewicz, Pawel /** 31beeca0aeSGunnar Mills * @brief Retrieves chassis state properties over dbus 32beeca0aeSGunnar Mills * 33beeca0aeSGunnar Mills * @param[in] aResp - Shared pointer for completing asynchronous calls. 34beeca0aeSGunnar Mills * 35beeca0aeSGunnar Mills * @return None. 36beeca0aeSGunnar Mills */ 378d1b46d7Szhanghch05 inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> aResp) 38beeca0aeSGunnar Mills { 391e1e598dSJonathan Doman // crow::connections::systemBus->async_method_call( 401e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 411e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 421e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 431e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "CurrentPowerState", 441e1e598dSJonathan Doman [aResp{std::move(aResp)}](const boost::system::error_code ec, 451e1e598dSJonathan Doman const std::string& chassisState) { 46beeca0aeSGunnar Mills if (ec) 47beeca0aeSGunnar Mills { 48a6e5e0abSCarson Labrado if (ec == boost::system::errc::host_unreachable) 49a6e5e0abSCarson Labrado { 50a6e5e0abSCarson Labrado // Service not available, no error, just don't return 51a6e5e0abSCarson Labrado // chassis state info 52a6e5e0abSCarson Labrado BMCWEB_LOG_DEBUG << "Service not available " << ec; 53a6e5e0abSCarson Labrado return; 54a6e5e0abSCarson Labrado } 55beeca0aeSGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 56beeca0aeSGunnar Mills messages::internalError(aResp->res); 57beeca0aeSGunnar Mills return; 58beeca0aeSGunnar Mills } 59beeca0aeSGunnar Mills 601e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Chassis state: " << chassisState; 61beeca0aeSGunnar Mills // Verify Chassis State 621e1e598dSJonathan Doman if (chassisState == 631e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis.PowerState.On") 64beeca0aeSGunnar Mills { 65beeca0aeSGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 66beeca0aeSGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 67beeca0aeSGunnar Mills } 681e1e598dSJonathan Doman else if (chassisState == 69beeca0aeSGunnar Mills "xyz.openbmc_project.State.Chassis.PowerState.Off") 70beeca0aeSGunnar Mills { 71beeca0aeSGunnar Mills aResp->res.jsonValue["PowerState"] = "Off"; 72beeca0aeSGunnar Mills aResp->res.jsonValue["Status"]["State"] = "StandbyOffline"; 73beeca0aeSGunnar Mills } 741e1e598dSJonathan Doman }); 75beeca0aeSGunnar Mills } 76beeca0aeSGunnar Mills 778d1b46d7Szhanghch05 inline void getIntrusionByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 78c181942fSQiang XU const std::string& service, 79c181942fSQiang XU const std::string& objPath) 80c181942fSQiang XU { 81c181942fSQiang XU BMCWEB_LOG_DEBUG << "Get intrusion status by service \n"; 82c181942fSQiang XU 831e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 841e1e598dSJonathan Doman *crow::connections::systemBus, service, objPath, 851e1e598dSJonathan Doman "xyz.openbmc_project.Chassis.Intrusion", "Status", 86c181942fSQiang XU [aResp{std::move(aResp)}](const boost::system::error_code ec, 871e1e598dSJonathan Doman const std::string& value) { 88c181942fSQiang XU if (ec) 89c181942fSQiang XU { 904e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 91c181942fSQiang XU // mandatory property 92c181942fSQiang XU BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n"; 93c181942fSQiang XU return; 94c181942fSQiang XU } 95c181942fSQiang XU 96c181942fSQiang XU aResp->res.jsonValue["PhysicalSecurity"] = { 971e1e598dSJonathan Doman {"IntrusionSensorNumber", 1}, {"IntrusionSensor", value}}; 981e1e598dSJonathan Doman }); 99c181942fSQiang XU } 100c181942fSQiang XU 101c181942fSQiang XU /** 102c181942fSQiang XU * Retrieves physical security properties over dbus 103c181942fSQiang XU */ 1048d1b46d7Szhanghch05 inline void getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> aResp) 105c181942fSQiang XU { 106c181942fSQiang XU crow::connections::systemBus->async_method_call( 107c181942fSQiang XU [aResp{std::move(aResp)}]( 108c181942fSQiang XU const boost::system::error_code ec, 109*b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 110c181942fSQiang XU if (ec) 111c181942fSQiang XU { 1124e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 113c181942fSQiang XU // mandatory property 11454fbf177SAndrew Geissler BMCWEB_LOG_INFO << "DBUS error: no matched iface " << ec 115c181942fSQiang XU << "\n"; 116c181942fSQiang XU return; 117c181942fSQiang XU } 118c181942fSQiang XU // Iterate over all retrieved ObjectPaths. 119c181942fSQiang XU for (const auto& object : subtree) 120c181942fSQiang XU { 121c181942fSQiang XU for (const auto& service : object.second) 122c181942fSQiang XU { 123c181942fSQiang XU getIntrusionByService(aResp, service.first, object.first); 124c181942fSQiang XU return; 125c181942fSQiang XU } 126c181942fSQiang XU } 127c181942fSQiang XU }, 128c181942fSQiang XU "xyz.openbmc_project.ObjectMapper", 129c181942fSQiang XU "/xyz/openbmc_project/object_mapper", 130c181942fSQiang XU "xyz.openbmc_project.ObjectMapper", "GetSubTree", 131271584abSEd Tanous "/xyz/openbmc_project/Intrusion", 1, 132c181942fSQiang XU std::array<const char*, 1>{"xyz.openbmc_project.Chassis.Intrusion"}); 133c181942fSQiang XU } 134c181942fSQiang XU 135e37f8451SRapkiewicz, Pawel /** 136e37f8451SRapkiewicz, Pawel * ChassisCollection derived class for delivering Chassis Collection Schema 137e37f8451SRapkiewicz, Pawel * Functions triggers appropriate requests on DBus 138e37f8451SRapkiewicz, Pawel */ 1397e860f15SJohn Edward Broadbent inline void requestRoutesChassisCollection(App& app) 1401abe55efSEd Tanous { 1417e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/") 142ed398213SEd Tanous .privileges(redfish::privileges::getChassisCollection) 1437e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 1447e860f15SJohn Edward Broadbent [](const crow::Request&, 1457e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1468d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 1478d1b46d7Szhanghch05 "#ChassisCollection.ChassisCollection"; 1488d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis"; 1498d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 150e37f8451SRapkiewicz, Pawel 15102f6ff19SGunnar Mills collection_util::getCollectionMembers( 15202f6ff19SGunnar Mills asyncResp, "/redfish/v1/Chassis", 15302f6ff19SGunnar Mills {"xyz.openbmc_project.Inventory.Item.Board", 15402f6ff19SGunnar Mills "xyz.openbmc_project.Inventory.Item.Chassis"}); 1557e860f15SJohn Edward Broadbent }); 15662d5e2e4SEd Tanous } 157e37f8451SRapkiewicz, Pawel 158308f70c7SWilly Tu inline void 159308f70c7SWilly Tu getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 160308f70c7SWilly Tu const std::string& connectionName, 161308f70c7SWilly Tu const std::string& path) 162308f70c7SWilly Tu { 1631e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 1641e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 1651e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode", 166308f70c7SWilly Tu [asyncResp](const boost::system::error_code ec, 1671e1e598dSJonathan Doman const std::string& property) { 168308f70c7SWilly Tu if (ec) 169308f70c7SWilly Tu { 1700fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error for Location"; 171308f70c7SWilly Tu messages::internalError(asyncResp->res); 172308f70c7SWilly Tu return; 173308f70c7SWilly Tu } 174308f70c7SWilly Tu 175308f70c7SWilly Tu asyncResp->res 1761e1e598dSJonathan Doman .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 1771e1e598dSJonathan Doman property; 1781e1e598dSJonathan Doman }); 179308f70c7SWilly Tu } 180308f70c7SWilly Tu 181308f70c7SWilly Tu inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 182308f70c7SWilly Tu const std::string& connectionName, 183308f70c7SWilly Tu const std::string& path) 184308f70c7SWilly Tu { 1851e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 1861e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 1871e1e598dSJonathan Doman "xyz.openbmc_project.Common.UUID", "UUID", 188308f70c7SWilly Tu [asyncResp](const boost::system::error_code ec, 1891e1e598dSJonathan Doman const std::string& chassisUUID) { 190308f70c7SWilly Tu if (ec) 191308f70c7SWilly Tu { 1920fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error for UUID"; 193308f70c7SWilly Tu messages::internalError(asyncResp->res); 194308f70c7SWilly Tu return; 195308f70c7SWilly Tu } 1961e1e598dSJonathan Doman asyncResp->res.jsonValue["UUID"] = chassisUUID; 1971e1e598dSJonathan Doman }); 198308f70c7SWilly Tu } 199308f70c7SWilly Tu 200e37f8451SRapkiewicz, Pawel /** 201e37f8451SRapkiewicz, Pawel * Chassis override class for delivering Chassis Schema 202e37f8451SRapkiewicz, Pawel * Functions triggers appropriate requests on DBus 203e37f8451SRapkiewicz, Pawel */ 2047e860f15SJohn Edward Broadbent inline void requestRoutesChassis(App& app) 2051abe55efSEd Tanous { 2067e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 207ed398213SEd Tanous .privileges(redfish::privileges::getChassis) 2087e860f15SJohn Edward Broadbent .methods( 2097e860f15SJohn Edward Broadbent boost::beast::http::verb::get)([](const crow::Request&, 2107e860f15SJohn Edward Broadbent const std::shared_ptr< 2117e860f15SJohn Edward Broadbent bmcweb::AsyncResp>& asyncResp, 2127e860f15SJohn Edward Broadbent const std::string& chassisId) { 213adc4f0dbSShawn McCarney const std::array<const char*, 2> interfaces = { 214734bfe90SGunnar Mills "xyz.openbmc_project.Inventory.Item.Board", 215adc4f0dbSShawn McCarney "xyz.openbmc_project.Inventory.Item.Chassis"}; 216734bfe90SGunnar Mills 21755c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 21862d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 21962d5e2e4SEd Tanous const boost::system::error_code ec, 220*b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 22162d5e2e4SEd Tanous if (ec) 2221abe55efSEd Tanous { 223f12894f8SJason M. Bills messages::internalError(asyncResp->res); 224daf36e2eSEd Tanous return; 225daf36e2eSEd Tanous } 226daf36e2eSEd Tanous // Iterate over all retrieved ObjectPaths. 2271abe55efSEd Tanous for (const std::pair< 2281abe55efSEd Tanous std::string, 2297e860f15SJohn Edward Broadbent std::vector<std::pair<std::string, 2307e860f15SJohn Edward Broadbent std::vector<std::string>>>>& 2311214b7e7SGunnar Mills object : subtree) 2321abe55efSEd Tanous { 233daf36e2eSEd Tanous const std::string& path = object.first; 2341abe55efSEd Tanous const std::vector< 2351214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 2361214b7e7SGunnar Mills connectionNames = object.second; 2377e860f15SJohn Edward Broadbent 238997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 239997093ebSGeorge Liu if (objPath.filename() != chassisId) 2401abe55efSEd Tanous { 241daf36e2eSEd Tanous continue; 242daf36e2eSEd Tanous } 24326f03899SShawn McCarney 2447e860f15SJohn Edward Broadbent auto health = 2457e860f15SJohn Edward Broadbent std::make_shared<HealthPopulate>(asyncResp); 246b49ac873SJames Feist 2471e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::vector<std::string>>( 2481e1e598dSJonathan Doman *crow::connections::systemBus, 2491e1e598dSJonathan Doman "xyz.openbmc_project.ObjectMapper", 2501e1e598dSJonathan Doman path + "/all_sensors", 2511e1e598dSJonathan Doman "xyz.openbmc_project.Association", "endpoints", 252168e20c1SEd Tanous [health](const boost::system::error_code ec2, 2531e1e598dSJonathan Doman const std::vector<std::string>& resp) { 25423a21a1cSEd Tanous if (ec2) 255b49ac873SJames Feist { 256b49ac873SJames Feist return; // no sensors = no failures 257b49ac873SJames Feist } 2581e1e598dSJonathan Doman health->inventory = resp; 2591e1e598dSJonathan Doman }); 260b49ac873SJames Feist 261b49ac873SJames Feist health->populate(); 262b49ac873SJames Feist 26326f6976fSEd Tanous if (connectionNames.empty()) 2641abe55efSEd Tanous { 2651c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 266e0d918bcSEd Tanous continue; 267daf36e2eSEd Tanous } 268e0d918bcSEd Tanous 26949c53ac9SJohnathan Mantey asyncResp->res.jsonValue["@odata.type"] = 2705ac5a2f4SGunnar Mills "#Chassis.v1_16_0.Chassis"; 27149c53ac9SJohnathan Mantey asyncResp->res.jsonValue["@odata.id"] = 27249c53ac9SJohnathan Mantey "/redfish/v1/Chassis/" + chassisId; 27349c53ac9SJohnathan Mantey asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 27449c53ac9SJohnathan Mantey asyncResp->res.jsonValue["ChassisType"] = "RackMount"; 2757e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"] = 2767e860f15SJohn Edward Broadbent {{"target", "/redfish/v1/Chassis/" + chassisId + 277dd99e04bSP.K. Lee "/Actions/Chassis.Reset"}, 2781cb1a9e6SAppaRao Puli {"@Redfish.ActionInfo", "/redfish/v1/Chassis/" + 2791cb1a9e6SAppaRao Puli chassisId + 2801cb1a9e6SAppaRao Puli "/ResetActionInfo"}}; 281adbe192aSJason M. Bills asyncResp->res.jsonValue["PCIeDevices"] = { 282adbe192aSJason M. Bills {"@odata.id", 283adbe192aSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices"}}; 28449c53ac9SJohnathan Mantey 28549c53ac9SJohnathan Mantey const std::string& connectionName = 28649c53ac9SJohnathan Mantey connectionNames[0].first; 2871c8fba97SJames Feist 28823a21a1cSEd Tanous const std::vector<std::string>& interfaces2 = 2891c8fba97SJames Feist connectionNames[0].second; 2901c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 2911c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 2920fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 2931c8fba97SJames Feist 294476b9cc5STejas Patil const std::string assetTagInterface = 2950fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag"; 296476b9cc5STejas Patil if (std::find(interfaces2.begin(), interfaces2.end(), 297476b9cc5STejas Patil assetTagInterface) != interfaces2.end()) 298476b9cc5STejas Patil { 2991e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 3001e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, 3011e1e598dSJonathan Doman path, assetTagInterface, "AssetTag", 302476b9cc5STejas Patil [asyncResp, chassisId(std::string(chassisId))]( 303476b9cc5STejas Patil const boost::system::error_code ec, 3041e1e598dSJonathan Doman const std::string& property) { 305476b9cc5STejas Patil if (ec) 306476b9cc5STejas Patil { 307476b9cc5STejas Patil BMCWEB_LOG_DEBUG 3080fda0f12SGeorge Liu << "DBus response error for AssetTag"; 309476b9cc5STejas Patil messages::internalError(asyncResp->res); 310476b9cc5STejas Patil return; 311476b9cc5STejas Patil } 312476b9cc5STejas Patil asyncResp->res.jsonValue["AssetTag"] = 3131e1e598dSJonathan Doman property; 3141e1e598dSJonathan Doman }); 315476b9cc5STejas Patil } 316476b9cc5STejas Patil 3171c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 3181c8fba97SJames Feist { 3197e860f15SJohn Edward Broadbent if (std::find(interfaces2.begin(), 3207e860f15SJohn Edward Broadbent interfaces2.end(), 32123a21a1cSEd Tanous interface) != interfaces2.end()) 3221c8fba97SJames Feist { 3231c8fba97SJames Feist getIndicatorLedState(asyncResp); 3249f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 3251c8fba97SJames Feist break; 3261c8fba97SJames Feist } 3271c8fba97SJames Feist } 3281c8fba97SJames Feist 32955c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 33062d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 33190728b54SEd Tanous const boost::system::error_code /*ec2*/, 332*b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 3337e860f15SJohn Edward Broadbent propertiesList) { 334168e20c1SEd Tanous for (const std::pair< 335168e20c1SEd Tanous std::string, 336168e20c1SEd Tanous dbus::utility::DbusVariantType>& 3371214b7e7SGunnar Mills property : propertiesList) 3381abe55efSEd Tanous { 3397e860f15SJohn Edward Broadbent // Store DBus properties that are also 3407e860f15SJohn Edward Broadbent // Redfish properties with same name and a 3417e860f15SJohn Edward Broadbent // string value 34299cffd7fSShawn McCarney const std::string& propertyName = 34399cffd7fSShawn McCarney property.first; 34499cffd7fSShawn McCarney if ((propertyName == "PartNumber") || 34599cffd7fSShawn McCarney (propertyName == "SerialNumber") || 34699cffd7fSShawn McCarney (propertyName == "Manufacturer") || 347caa11f7aSAlpana Kumari (propertyName == "Model") || 348caa11f7aSAlpana Kumari (propertyName == "SparePartNumber")) 34999cffd7fSShawn McCarney { 350daf36e2eSEd Tanous const std::string* value = 35199cffd7fSShawn McCarney std::get_if<std::string>( 35299cffd7fSShawn McCarney &property.second); 353caa11f7aSAlpana Kumari if (value == nullptr) 3541abe55efSEd Tanous { 355caa11f7aSAlpana Kumari BMCWEB_LOG_ERROR 356caa11f7aSAlpana Kumari << "Null value returned for " 357caa11f7aSAlpana Kumari << propertyName; 358caa11f7aSAlpana Kumari messages::internalError( 359caa11f7aSAlpana Kumari asyncResp->res); 360caa11f7aSAlpana Kumari return; 361daf36e2eSEd Tanous } 362caa11f7aSAlpana Kumari // SparePartNumber is optional on D-Bus 363caa11f7aSAlpana Kumari // so skip if it is empty 364caa11f7aSAlpana Kumari if (propertyName == "SparePartNumber") 365caa11f7aSAlpana Kumari { 36626f6976fSEd Tanous if (value->empty()) 367caa11f7aSAlpana Kumari { 368caa11f7aSAlpana Kumari continue; 369caa11f7aSAlpana Kumari } 370caa11f7aSAlpana Kumari } 371caa11f7aSAlpana Kumari asyncResp->res.jsonValue[propertyName] = 372caa11f7aSAlpana Kumari *value; 373daf36e2eSEd Tanous } 37499cffd7fSShawn McCarney } 37562d5e2e4SEd Tanous asyncResp->res.jsonValue["Name"] = chassisId; 37662d5e2e4SEd Tanous asyncResp->res.jsonValue["Id"] = chassisId; 3770256b694Szhanghch05 #ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL 37862d5e2e4SEd Tanous asyncResp->res.jsonValue["Thermal"] = { 3791abe55efSEd Tanous {"@odata.id", "/redfish/v1/Chassis/" + 3801abe55efSEd Tanous chassisId + "/Thermal"}}; 3812474adfaSEd Tanous // Power object 3822474adfaSEd Tanous asyncResp->res.jsonValue["Power"] = { 3832474adfaSEd Tanous {"@odata.id", "/redfish/v1/Chassis/" + 3842474adfaSEd Tanous chassisId + "/Power"}}; 3850256b694Szhanghch05 #endif 38695a3ecadSAnthony Wilson // SensorCollection 38795a3ecadSAnthony Wilson asyncResp->res.jsonValue["Sensors"] = { 38895a3ecadSAnthony Wilson {"@odata.id", "/redfish/v1/Chassis/" + 38995a3ecadSAnthony Wilson chassisId + "/Sensors"}}; 390029573d4SEd Tanous asyncResp->res.jsonValue["Status"] = { 391029573d4SEd Tanous {"State", "Enabled"}, 392029573d4SEd Tanous }; 3932474adfaSEd Tanous 394029573d4SEd Tanous asyncResp->res 395029573d4SEd Tanous .jsonValue["Links"]["ComputerSystems"] = { 3967e860f15SJohn Edward Broadbent {{"@odata.id", 3977e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system"}}}; 3987e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Links"]["ManagedBy"] = 3997e860f15SJohn Edward Broadbent {{{"@odata.id", 4007e860f15SJohn Edward Broadbent "/redfish/v1/Managers/bmc"}}}; 401beeca0aeSGunnar Mills getChassisState(asyncResp); 402daf36e2eSEd Tanous }, 4037e860f15SJohn Edward Broadbent connectionName, path, 4047e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "GetAll", 4051abe55efSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset"); 4062c37b4b0SSharad Yadav 407308f70c7SWilly Tu for (const auto& interface : interfaces2) 4082c37b4b0SSharad Yadav { 409308f70c7SWilly Tu if (interface == "xyz.openbmc_project.Common.UUID") 4102c37b4b0SSharad Yadav { 411308f70c7SWilly Tu getChassisUUID(asyncResp, connectionName, path); 4122c37b4b0SSharad Yadav } 4130fda0f12SGeorge Liu else if ( 4140fda0f12SGeorge Liu interface == 4150fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.LocationCode") 4162c37b4b0SSharad Yadav { 417308f70c7SWilly Tu getChassisLocationCode(asyncResp, 418308f70c7SWilly Tu connectionName, path); 4192c37b4b0SSharad Yadav } 4202c37b4b0SSharad Yadav } 4212c37b4b0SSharad Yadav 422daf36e2eSEd Tanous return; 423daf36e2eSEd Tanous } 424e0d918bcSEd Tanous 425daf36e2eSEd Tanous // Couldn't find an object with that name. return an error 426f12894f8SJason M. Bills messages::resourceNotFound( 4275ac5a2f4SGunnar Mills asyncResp->res, "#Chassis.v1_16_0.Chassis", chassisId); 428daf36e2eSEd Tanous }, 429daf36e2eSEd Tanous "xyz.openbmc_project.ObjectMapper", 430daf36e2eSEd Tanous "/xyz/openbmc_project/object_mapper", 431daf36e2eSEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 432271584abSEd Tanous "/xyz/openbmc_project/inventory", 0, interfaces); 433c181942fSQiang XU 434c181942fSQiang XU getPhysicalSecurityData(asyncResp); 4357e860f15SJohn Edward Broadbent }); 4361c8fba97SJames Feist 4377e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 438ed398213SEd Tanous .privileges(redfish::privileges::patchChassis) 4397e860f15SJohn Edward Broadbent .methods( 4407e860f15SJohn Edward Broadbent boost::beast::http::verb:: 4417e860f15SJohn Edward Broadbent patch)([](const crow::Request& req, 4427e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4437e860f15SJohn Edward Broadbent const std::string& param) { 4449f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 4451c8fba97SJames Feist std::optional<std::string> indicatorLed; 4461c8fba97SJames Feist 4477e860f15SJohn Edward Broadbent if (param.empty()) 4481c8fba97SJames Feist { 4491c8fba97SJames Feist return; 4501c8fba97SJames Feist } 4511c8fba97SJames Feist 45215ed6780SWilly Tu if (!json_util::readJsonPatch( 4537e860f15SJohn Edward Broadbent req, asyncResp->res, "LocationIndicatorActive", 4547e860f15SJohn Edward Broadbent locationIndicatorActive, "IndicatorLED", indicatorLed)) 4551c8fba97SJames Feist { 4561c8fba97SJames Feist return; 4571c8fba97SJames Feist } 4581c8fba97SJames Feist 4599f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 4609f8bfa7cSGunnar Mills if (!locationIndicatorActive && !indicatorLed) 4611c8fba97SJames Feist { 4621c8fba97SJames Feist return; // delete this when we support more patch properties 4631c8fba97SJames Feist } 464d6aa0093SGunnar Mills if (indicatorLed) 465d6aa0093SGunnar Mills { 4667e860f15SJohn Edward Broadbent asyncResp->res.addHeader( 4677e860f15SJohn Edward Broadbent boost::beast::http::field::warning, 4680fda0f12SGeorge Liu "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\""); 469d6aa0093SGunnar Mills } 4701c8fba97SJames Feist 4711c8fba97SJames Feist const std::array<const char*, 2> interfaces = { 4721c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Board", 4731c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Chassis"}; 4741c8fba97SJames Feist 4757e860f15SJohn Edward Broadbent const std::string& chassisId = param; 4761c8fba97SJames Feist 4771c8fba97SJames Feist crow::connections::systemBus->async_method_call( 4789f8bfa7cSGunnar Mills [asyncResp, chassisId, locationIndicatorActive, indicatorLed]( 4791c8fba97SJames Feist const boost::system::error_code ec, 480*b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 4811c8fba97SJames Feist if (ec) 4821c8fba97SJames Feist { 4831c8fba97SJames Feist messages::internalError(asyncResp->res); 4841c8fba97SJames Feist return; 4851c8fba97SJames Feist } 4861c8fba97SJames Feist 4871c8fba97SJames Feist // Iterate over all retrieved ObjectPaths. 4881c8fba97SJames Feist for (const std::pair< 4891c8fba97SJames Feist std::string, 4907e860f15SJohn Edward Broadbent std::vector<std::pair<std::string, 4917e860f15SJohn Edward Broadbent std::vector<std::string>>>>& 4921214b7e7SGunnar Mills object : subtree) 4931c8fba97SJames Feist { 4941c8fba97SJames Feist const std::string& path = object.first; 4951c8fba97SJames Feist const std::vector< 4961214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 4971214b7e7SGunnar Mills connectionNames = object.second; 4981c8fba97SJames Feist 499997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 500997093ebSGeorge Liu if (objPath.filename() != chassisId) 5011c8fba97SJames Feist { 5021c8fba97SJames Feist continue; 5031c8fba97SJames Feist } 5041c8fba97SJames Feist 50526f6976fSEd Tanous if (connectionNames.empty()) 5061c8fba97SJames Feist { 5071c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 5081c8fba97SJames Feist continue; 5091c8fba97SJames Feist } 5101c8fba97SJames Feist 51123a21a1cSEd Tanous const std::vector<std::string>& interfaces3 = 5121c8fba97SJames Feist connectionNames[0].second; 5131c8fba97SJames Feist 5141c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 5151c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 5160fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 5171c8fba97SJames Feist bool indicatorChassis = false; 5181c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 5191c8fba97SJames Feist { 5207e860f15SJohn Edward Broadbent if (std::find(interfaces3.begin(), 5217e860f15SJohn Edward Broadbent interfaces3.end(), 52223a21a1cSEd Tanous interface) != interfaces3.end()) 5231c8fba97SJames Feist { 5241c8fba97SJames Feist indicatorChassis = true; 5251c8fba97SJames Feist break; 5261c8fba97SJames Feist } 5271c8fba97SJames Feist } 5289f8bfa7cSGunnar Mills if (locationIndicatorActive) 5299f8bfa7cSGunnar Mills { 5309f8bfa7cSGunnar Mills if (indicatorChassis) 5319f8bfa7cSGunnar Mills { 5329f8bfa7cSGunnar Mills setLocationIndicatorActive( 5339f8bfa7cSGunnar Mills asyncResp, *locationIndicatorActive); 5349f8bfa7cSGunnar Mills } 5359f8bfa7cSGunnar Mills else 5369f8bfa7cSGunnar Mills { 5379f8bfa7cSGunnar Mills messages::propertyUnknown( 5389f8bfa7cSGunnar Mills asyncResp->res, "LocationIndicatorActive"); 5399f8bfa7cSGunnar Mills } 5409f8bfa7cSGunnar Mills } 5419f8bfa7cSGunnar Mills if (indicatorLed) 5429f8bfa7cSGunnar Mills { 5431c8fba97SJames Feist if (indicatorChassis) 5441c8fba97SJames Feist { 545f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 5461c8fba97SJames Feist } 5471c8fba97SJames Feist else 5481c8fba97SJames Feist { 5491c8fba97SJames Feist messages::propertyUnknown(asyncResp->res, 5501c8fba97SJames Feist "IndicatorLED"); 5511c8fba97SJames Feist } 5521c8fba97SJames Feist } 5531c8fba97SJames Feist return; 5541c8fba97SJames Feist } 5551c8fba97SJames Feist 5561c8fba97SJames Feist messages::resourceNotFound( 5579f8bfa7cSGunnar Mills asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId); 5581c8fba97SJames Feist }, 5591c8fba97SJames Feist "xyz.openbmc_project.ObjectMapper", 5601c8fba97SJames Feist "/xyz/openbmc_project/object_mapper", 5611c8fba97SJames Feist "xyz.openbmc_project.ObjectMapper", "GetSubTree", 5621c8fba97SJames Feist "/xyz/openbmc_project/inventory", 0, interfaces); 5637e860f15SJohn Edward Broadbent }); 5641c8fba97SJames Feist } 565dd99e04bSP.K. Lee 5668d1b46d7Szhanghch05 inline void 5678d1b46d7Szhanghch05 doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 568dd99e04bSP.K. Lee { 569c3b3c92aSVijay Khemka const char* busName = "xyz.openbmc_project.ObjectMapper"; 570c3b3c92aSVijay Khemka const char* path = "/xyz/openbmc_project/object_mapper"; 571c3b3c92aSVijay Khemka const char* interface = "xyz.openbmc_project.ObjectMapper"; 572c3b3c92aSVijay Khemka const char* method = "GetSubTreePaths"; 573c3b3c92aSVijay Khemka 574c3b3c92aSVijay Khemka const std::array<const char*, 1> interfaces = { 575c3b3c92aSVijay Khemka "xyz.openbmc_project.State.Chassis"}; 576c3b3c92aSVijay Khemka 577c3b3c92aSVijay Khemka // Use mapper to get subtree paths. 578c3b3c92aSVijay Khemka crow::connections::systemBus->async_method_call( 579*b9d36b47SEd Tanous [asyncResp]( 580*b9d36b47SEd Tanous const boost::system::error_code ec, 581*b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreePathsResponse& chassisList) { 582c3b3c92aSVijay Khemka if (ec) 583c3b3c92aSVijay Khemka { 584c3b3c92aSVijay Khemka BMCWEB_LOG_DEBUG << "[mapper] Bad D-Bus request error: " << ec; 585c3b3c92aSVijay Khemka messages::internalError(asyncResp->res); 586c3b3c92aSVijay Khemka return; 587c3b3c92aSVijay Khemka } 588c3b3c92aSVijay Khemka 589dd99e04bSP.K. Lee const char* processName = "xyz.openbmc_project.State.Chassis"; 590dd99e04bSP.K. Lee const char* interfaceName = "xyz.openbmc_project.State.Chassis"; 591dd99e04bSP.K. Lee const char* destProperty = "RequestedPowerTransition"; 592dd99e04bSP.K. Lee const std::string propertyValue = 593dd99e04bSP.K. Lee "xyz.openbmc_project.State.Chassis.Transition.PowerCycle"; 594c3b3c92aSVijay Khemka std::string objectPath = 595c3b3c92aSVijay Khemka "/xyz/openbmc_project/state/chassis_system0"; 596c3b3c92aSVijay Khemka 597c3b3c92aSVijay Khemka /* Look for system reset chassis path */ 598c3b3c92aSVijay Khemka if ((std::find(chassisList.begin(), chassisList.end(), 599c3b3c92aSVijay Khemka objectPath)) == chassisList.end()) 600c3b3c92aSVijay Khemka { 601c3b3c92aSVijay Khemka /* We prefer to reset the full chassis_system, but if it doesn't 602c3b3c92aSVijay Khemka * exist on some platforms, fall back to a host-only power reset 603c3b3c92aSVijay Khemka */ 604c3b3c92aSVijay Khemka objectPath = "/xyz/openbmc_project/state/chassis0"; 605c3b3c92aSVijay Khemka } 606dd99e04bSP.K. Lee 607dd99e04bSP.K. Lee crow::connections::systemBus->async_method_call( 608dd99e04bSP.K. Lee [asyncResp](const boost::system::error_code ec) { 609dd99e04bSP.K. Lee // Use "Set" method to set the property value. 610dd99e04bSP.K. Lee if (ec) 611dd99e04bSP.K. Lee { 612c3b3c92aSVijay Khemka BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " 613c3b3c92aSVijay Khemka << ec; 614dd99e04bSP.K. Lee messages::internalError(asyncResp->res); 615dd99e04bSP.K. Lee return; 616dd99e04bSP.K. Lee } 617dd99e04bSP.K. Lee 618dd99e04bSP.K. Lee messages::success(asyncResp->res); 619dd99e04bSP.K. Lee }, 620c3b3c92aSVijay Khemka processName, objectPath, "org.freedesktop.DBus.Properties", 621c3b3c92aSVijay Khemka "Set", interfaceName, destProperty, 622168e20c1SEd Tanous dbus::utility::DbusVariantType{propertyValue}); 623c3b3c92aSVijay Khemka }, 624c3b3c92aSVijay Khemka busName, path, interface, method, "/", 0, interfaces); 625dd99e04bSP.K. Lee } 626dd99e04bSP.K. Lee 627dd99e04bSP.K. Lee /** 628dd99e04bSP.K. Lee * ChassisResetAction class supports the POST method for the Reset 629dd99e04bSP.K. Lee * action. 630dd99e04bSP.K. Lee * Function handles POST method request. 631dd99e04bSP.K. Lee * Analyzes POST body before sending Reset request data to D-Bus. 632dd99e04bSP.K. Lee */ 6337e860f15SJohn Edward Broadbent 6347e860f15SJohn Edward Broadbent inline void requestRoutesChassisResetAction(App& app) 635dd99e04bSP.K. Lee { 6367e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/") 637ed398213SEd Tanous .privileges(redfish::privileges::postChassis) 6387e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)( 6397e860f15SJohn Edward Broadbent [](const crow::Request& req, 6407e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6417e860f15SJohn Edward Broadbent const std::string&) { 642dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Post Chassis Reset."; 643dd99e04bSP.K. Lee 644dd99e04bSP.K. Lee std::string resetType; 645dd99e04bSP.K. Lee 64615ed6780SWilly Tu if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", 6477e860f15SJohn Edward Broadbent resetType)) 648dd99e04bSP.K. Lee { 649dd99e04bSP.K. Lee return; 650dd99e04bSP.K. Lee } 651dd99e04bSP.K. Lee 652dd99e04bSP.K. Lee if (resetType != "PowerCycle") 653dd99e04bSP.K. Lee { 654dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: " 655dd99e04bSP.K. Lee << resetType; 6567e860f15SJohn Edward Broadbent messages::actionParameterNotSupported( 6577e860f15SJohn Edward Broadbent asyncResp->res, resetType, "ResetType"); 658dd99e04bSP.K. Lee 659dd99e04bSP.K. Lee return; 660dd99e04bSP.K. Lee } 661dd99e04bSP.K. Lee doChassisPowerCycle(asyncResp); 6627e860f15SJohn Edward Broadbent }); 663dd99e04bSP.K. Lee } 6641cb1a9e6SAppaRao Puli 6651cb1a9e6SAppaRao Puli /** 6661cb1a9e6SAppaRao Puli * ChassisResetActionInfo derived class for delivering Chassis 6671cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 6681cb1a9e6SAppaRao Puli */ 6697e860f15SJohn Edward Broadbent inline void requestRoutesChassisResetActionInfo(App& app) 6701cb1a9e6SAppaRao Puli { 6717e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/") 672ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 6737e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 6747e860f15SJohn Edward Broadbent [](const crow::Request&, 6757e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6767e860f15SJohn Edward Broadbent const std::string& chassisId) 6771cb1a9e6SAppaRao Puli 6781cb1a9e6SAppaRao Puli { 6798d1b46d7Szhanghch05 asyncResp->res.jsonValue = { 6808d1b46d7Szhanghch05 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"}, 6818d1b46d7Szhanghch05 {"@odata.id", 6828d1b46d7Szhanghch05 "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo"}, 6831cb1a9e6SAppaRao Puli {"Name", "Reset Action Info"}, 6841cb1a9e6SAppaRao Puli {"Id", "ResetActionInfo"}, 6851cb1a9e6SAppaRao Puli {"Parameters", 6861cb1a9e6SAppaRao Puli {{{"Name", "ResetType"}, 6871cb1a9e6SAppaRao Puli {"Required", true}, 6881cb1a9e6SAppaRao Puli {"DataType", "String"}, 6891cb1a9e6SAppaRao Puli {"AllowableValues", {"PowerCycle"}}}}}}; 6907e860f15SJohn Edward Broadbent }); 6911cb1a9e6SAppaRao Puli } 6921cb1a9e6SAppaRao Puli 693e37f8451SRapkiewicz, Pawel } // namespace redfish 694