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> 2345ca1b86SEd Tanous #include <query.hpp> 24ed398213SEd Tanous #include <registries/privilege_registry.hpp> 251e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 2602f6ff19SGunnar Mills #include <utils/collection.hpp> 271214b7e7SGunnar Mills 281abe55efSEd Tanous namespace redfish 291abe55efSEd Tanous { 30e37f8451SRapkiewicz, Pawel 31e37f8451SRapkiewicz, Pawel /** 32beeca0aeSGunnar Mills * @brief Retrieves chassis state properties over dbus 33beeca0aeSGunnar Mills * 34beeca0aeSGunnar Mills * @param[in] aResp - Shared pointer for completing asynchronous calls. 35beeca0aeSGunnar Mills * 36beeca0aeSGunnar Mills * @return None. 37beeca0aeSGunnar Mills */ 388d1b46d7Szhanghch05 inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> aResp) 39beeca0aeSGunnar Mills { 401e1e598dSJonathan Doman // crow::connections::systemBus->async_method_call( 411e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 421e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 431e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 441e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "CurrentPowerState", 451e1e598dSJonathan Doman [aResp{std::move(aResp)}](const boost::system::error_code ec, 461e1e598dSJonathan Doman const std::string& chassisState) { 47beeca0aeSGunnar Mills if (ec) 48beeca0aeSGunnar Mills { 49a6e5e0abSCarson Labrado if (ec == boost::system::errc::host_unreachable) 50a6e5e0abSCarson Labrado { 51a6e5e0abSCarson Labrado // Service not available, no error, just don't return 52a6e5e0abSCarson Labrado // chassis state info 53a6e5e0abSCarson Labrado BMCWEB_LOG_DEBUG << "Service not available " << ec; 54a6e5e0abSCarson Labrado return; 55a6e5e0abSCarson Labrado } 56beeca0aeSGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 57beeca0aeSGunnar Mills messages::internalError(aResp->res); 58beeca0aeSGunnar Mills return; 59beeca0aeSGunnar Mills } 60beeca0aeSGunnar Mills 611e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Chassis state: " << chassisState; 62beeca0aeSGunnar Mills // Verify Chassis State 631e1e598dSJonathan Doman if (chassisState == 641e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis.PowerState.On") 65beeca0aeSGunnar Mills { 66beeca0aeSGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 67beeca0aeSGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 68beeca0aeSGunnar Mills } 691e1e598dSJonathan Doman else if (chassisState == 70beeca0aeSGunnar Mills "xyz.openbmc_project.State.Chassis.PowerState.Off") 71beeca0aeSGunnar Mills { 72beeca0aeSGunnar Mills aResp->res.jsonValue["PowerState"] = "Off"; 73beeca0aeSGunnar Mills aResp->res.jsonValue["Status"]["State"] = "StandbyOffline"; 74beeca0aeSGunnar Mills } 751e1e598dSJonathan Doman }); 76beeca0aeSGunnar Mills } 77beeca0aeSGunnar Mills 788d1b46d7Szhanghch05 inline void getIntrusionByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 79c181942fSQiang XU const std::string& service, 80c181942fSQiang XU const std::string& objPath) 81c181942fSQiang XU { 82c181942fSQiang XU BMCWEB_LOG_DEBUG << "Get intrusion status by service \n"; 83c181942fSQiang XU 841e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 851e1e598dSJonathan Doman *crow::connections::systemBus, service, objPath, 861e1e598dSJonathan Doman "xyz.openbmc_project.Chassis.Intrusion", "Status", 87c181942fSQiang XU [aResp{std::move(aResp)}](const boost::system::error_code ec, 881e1e598dSJonathan Doman const std::string& value) { 89c181942fSQiang XU if (ec) 90c181942fSQiang XU { 914e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 92c181942fSQiang XU // mandatory property 93c181942fSQiang XU BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n"; 94c181942fSQiang XU return; 95c181942fSQiang XU } 96c181942fSQiang XU 97*1476687dSEd Tanous aResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensorNumber"] = 98*1476687dSEd Tanous 1; 99*1476687dSEd Tanous aResp->res.jsonValue["PhysicalSecurity"]["IntrusionSensor"] = value; 1001e1e598dSJonathan Doman }); 101c181942fSQiang XU } 102c181942fSQiang XU 103c181942fSQiang XU /** 104c181942fSQiang XU * Retrieves physical security properties over dbus 105c181942fSQiang XU */ 1068d1b46d7Szhanghch05 inline void getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> aResp) 107c181942fSQiang XU { 108c181942fSQiang XU crow::connections::systemBus->async_method_call( 109c181942fSQiang XU [aResp{std::move(aResp)}]( 110c181942fSQiang XU const boost::system::error_code ec, 111b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 112c181942fSQiang XU if (ec) 113c181942fSQiang XU { 1144e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 115c181942fSQiang XU // mandatory property 11654fbf177SAndrew Geissler BMCWEB_LOG_INFO << "DBUS error: no matched iface " << ec 117c181942fSQiang XU << "\n"; 118c181942fSQiang XU return; 119c181942fSQiang XU } 120c181942fSQiang XU // Iterate over all retrieved ObjectPaths. 121c181942fSQiang XU for (const auto& object : subtree) 122c181942fSQiang XU { 123c181942fSQiang XU for (const auto& service : object.second) 124c181942fSQiang XU { 125c181942fSQiang XU getIntrusionByService(aResp, service.first, object.first); 126c181942fSQiang XU return; 127c181942fSQiang XU } 128c181942fSQiang XU } 129c181942fSQiang XU }, 130c181942fSQiang XU "xyz.openbmc_project.ObjectMapper", 131c181942fSQiang XU "/xyz/openbmc_project/object_mapper", 132c181942fSQiang XU "xyz.openbmc_project.ObjectMapper", "GetSubTree", 133271584abSEd Tanous "/xyz/openbmc_project/Intrusion", 1, 134c181942fSQiang XU std::array<const char*, 1>{"xyz.openbmc_project.Chassis.Intrusion"}); 135c181942fSQiang XU } 136c181942fSQiang XU 137e37f8451SRapkiewicz, Pawel /** 138e37f8451SRapkiewicz, Pawel * ChassisCollection derived class for delivering Chassis Collection Schema 139e37f8451SRapkiewicz, Pawel * Functions triggers appropriate requests on DBus 140e37f8451SRapkiewicz, Pawel */ 1417e860f15SJohn Edward Broadbent inline void requestRoutesChassisCollection(App& app) 1421abe55efSEd Tanous { 1437e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/") 144ed398213SEd Tanous .privileges(redfish::privileges::getChassisCollection) 1457e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 14645ca1b86SEd Tanous [&app](const crow::Request& req, 1477e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 14845ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 14945ca1b86SEd Tanous { 15045ca1b86SEd Tanous return; 15145ca1b86SEd Tanous } 1528d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 1538d1b46d7Szhanghch05 "#ChassisCollection.ChassisCollection"; 1548d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis"; 1558d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 156e37f8451SRapkiewicz, Pawel 15702f6ff19SGunnar Mills collection_util::getCollectionMembers( 15802f6ff19SGunnar Mills asyncResp, "/redfish/v1/Chassis", 15902f6ff19SGunnar Mills {"xyz.openbmc_project.Inventory.Item.Board", 16002f6ff19SGunnar Mills "xyz.openbmc_project.Inventory.Item.Chassis"}); 1617e860f15SJohn Edward Broadbent }); 16262d5e2e4SEd Tanous } 163e37f8451SRapkiewicz, Pawel 164308f70c7SWilly Tu inline void 165308f70c7SWilly Tu getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 166308f70c7SWilly Tu const std::string& connectionName, 167308f70c7SWilly Tu const std::string& path) 168308f70c7SWilly Tu { 1691e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 1701e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 1711e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode", 172308f70c7SWilly Tu [asyncResp](const boost::system::error_code ec, 1731e1e598dSJonathan Doman const std::string& property) { 174308f70c7SWilly Tu if (ec) 175308f70c7SWilly Tu { 1760fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error for Location"; 177308f70c7SWilly Tu messages::internalError(asyncResp->res); 178308f70c7SWilly Tu return; 179308f70c7SWilly Tu } 180308f70c7SWilly Tu 181308f70c7SWilly Tu asyncResp->res 1821e1e598dSJonathan Doman .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 1831e1e598dSJonathan Doman property; 1841e1e598dSJonathan Doman }); 185308f70c7SWilly Tu } 186308f70c7SWilly Tu 187308f70c7SWilly Tu inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 188308f70c7SWilly Tu const std::string& connectionName, 189308f70c7SWilly Tu const std::string& path) 190308f70c7SWilly Tu { 1911e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 1921e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 1931e1e598dSJonathan Doman "xyz.openbmc_project.Common.UUID", "UUID", 194308f70c7SWilly Tu [asyncResp](const boost::system::error_code ec, 1951e1e598dSJonathan Doman const std::string& chassisUUID) { 196308f70c7SWilly Tu if (ec) 197308f70c7SWilly Tu { 1980fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error for UUID"; 199308f70c7SWilly Tu messages::internalError(asyncResp->res); 200308f70c7SWilly Tu return; 201308f70c7SWilly Tu } 2021e1e598dSJonathan Doman asyncResp->res.jsonValue["UUID"] = chassisUUID; 2031e1e598dSJonathan Doman }); 204308f70c7SWilly Tu } 205308f70c7SWilly Tu 206e37f8451SRapkiewicz, Pawel /** 207e37f8451SRapkiewicz, Pawel * Chassis override class for delivering Chassis Schema 208e37f8451SRapkiewicz, Pawel * Functions triggers appropriate requests on DBus 209e37f8451SRapkiewicz, Pawel */ 2107e860f15SJohn Edward Broadbent inline void requestRoutesChassis(App& app) 2111abe55efSEd Tanous { 2127e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 213ed398213SEd Tanous .privileges(redfish::privileges::getChassis) 2147e860f15SJohn Edward Broadbent .methods( 21545ca1b86SEd Tanous boost::beast::http::verb:: 21645ca1b86SEd Tanous get)([&app](const crow::Request& req, 21745ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2187e860f15SJohn Edward Broadbent const std::string& chassisId) { 21945ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 22045ca1b86SEd Tanous { 22145ca1b86SEd Tanous return; 22245ca1b86SEd Tanous } 223adc4f0dbSShawn McCarney const std::array<const char*, 2> interfaces = { 224734bfe90SGunnar Mills "xyz.openbmc_project.Inventory.Item.Board", 225adc4f0dbSShawn McCarney "xyz.openbmc_project.Inventory.Item.Chassis"}; 226734bfe90SGunnar Mills 22755c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 22862d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 22962d5e2e4SEd Tanous const boost::system::error_code ec, 230b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 23162d5e2e4SEd Tanous if (ec) 2321abe55efSEd Tanous { 233f12894f8SJason M. Bills messages::internalError(asyncResp->res); 234daf36e2eSEd Tanous return; 235daf36e2eSEd Tanous } 236daf36e2eSEd Tanous // Iterate over all retrieved ObjectPaths. 2371abe55efSEd Tanous for (const std::pair< 2381abe55efSEd Tanous std::string, 2397e860f15SJohn Edward Broadbent std::vector<std::pair<std::string, 2407e860f15SJohn Edward Broadbent std::vector<std::string>>>>& 2411214b7e7SGunnar Mills object : subtree) 2421abe55efSEd Tanous { 243daf36e2eSEd Tanous const std::string& path = object.first; 2441abe55efSEd Tanous const std::vector< 2451214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 2461214b7e7SGunnar Mills connectionNames = object.second; 2477e860f15SJohn Edward Broadbent 248997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 249997093ebSGeorge Liu if (objPath.filename() != chassisId) 2501abe55efSEd Tanous { 251daf36e2eSEd Tanous continue; 252daf36e2eSEd Tanous } 25326f03899SShawn McCarney 2547e860f15SJohn Edward Broadbent auto health = 2557e860f15SJohn Edward Broadbent std::make_shared<HealthPopulate>(asyncResp); 256b49ac873SJames Feist 2571e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::vector<std::string>>( 2581e1e598dSJonathan Doman *crow::connections::systemBus, 2591e1e598dSJonathan Doman "xyz.openbmc_project.ObjectMapper", 2601e1e598dSJonathan Doman path + "/all_sensors", 2611e1e598dSJonathan Doman "xyz.openbmc_project.Association", "endpoints", 262168e20c1SEd Tanous [health](const boost::system::error_code ec2, 2631e1e598dSJonathan Doman const std::vector<std::string>& resp) { 26423a21a1cSEd Tanous if (ec2) 265b49ac873SJames Feist { 266b49ac873SJames Feist return; // no sensors = no failures 267b49ac873SJames Feist } 2681e1e598dSJonathan Doman health->inventory = resp; 2691e1e598dSJonathan Doman }); 270b49ac873SJames Feist 271b49ac873SJames Feist health->populate(); 272b49ac873SJames Feist 27326f6976fSEd Tanous if (connectionNames.empty()) 2741abe55efSEd Tanous { 2751c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 276e0d918bcSEd Tanous continue; 277daf36e2eSEd Tanous } 278e0d918bcSEd Tanous 27949c53ac9SJohnathan Mantey asyncResp->res.jsonValue["@odata.type"] = 2805ac5a2f4SGunnar Mills "#Chassis.v1_16_0.Chassis"; 28149c53ac9SJohnathan Mantey asyncResp->res.jsonValue["@odata.id"] = 28249c53ac9SJohnathan Mantey "/redfish/v1/Chassis/" + chassisId; 28349c53ac9SJohnathan Mantey asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 28449c53ac9SJohnathan Mantey asyncResp->res.jsonValue["ChassisType"] = "RackMount"; 285*1476687dSEd Tanous asyncResp->res 286*1476687dSEd Tanous .jsonValue["Actions"]["#Chassis.Reset"]["target"] = 287*1476687dSEd Tanous "/redfish/v1/Chassis/" + chassisId + 288*1476687dSEd Tanous "/Actions/Chassis.Reset"; 289*1476687dSEd Tanous asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"] 290*1476687dSEd Tanous ["@Redfish.ActionInfo"] = 291*1476687dSEd Tanous "/redfish/v1/Chassis/" + chassisId + 292*1476687dSEd Tanous "/ResetActionInfo"; 293*1476687dSEd Tanous asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] = 294*1476687dSEd Tanous "/redfish/v1/Systems/system/PCIeDevices"; 29549c53ac9SJohnathan Mantey 29649c53ac9SJohnathan Mantey const std::string& connectionName = 29749c53ac9SJohnathan Mantey connectionNames[0].first; 2981c8fba97SJames Feist 29923a21a1cSEd Tanous const std::vector<std::string>& interfaces2 = 3001c8fba97SJames Feist connectionNames[0].second; 3011c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 3021c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 3030fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 3041c8fba97SJames Feist 305476b9cc5STejas Patil const std::string assetTagInterface = 3060fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag"; 307476b9cc5STejas Patil if (std::find(interfaces2.begin(), interfaces2.end(), 308476b9cc5STejas Patil assetTagInterface) != interfaces2.end()) 309476b9cc5STejas Patil { 3101e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 3111e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, 3121e1e598dSJonathan Doman path, assetTagInterface, "AssetTag", 313476b9cc5STejas Patil [asyncResp, chassisId(std::string(chassisId))]( 314476b9cc5STejas Patil const boost::system::error_code ec, 3151e1e598dSJonathan Doman const std::string& property) { 316476b9cc5STejas Patil if (ec) 317476b9cc5STejas Patil { 318476b9cc5STejas Patil BMCWEB_LOG_DEBUG 3190fda0f12SGeorge Liu << "DBus response error for AssetTag"; 320476b9cc5STejas Patil messages::internalError(asyncResp->res); 321476b9cc5STejas Patil return; 322476b9cc5STejas Patil } 323476b9cc5STejas Patil asyncResp->res.jsonValue["AssetTag"] = 3241e1e598dSJonathan Doman property; 3251e1e598dSJonathan Doman }); 326476b9cc5STejas Patil } 327476b9cc5STejas Patil 3281c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 3291c8fba97SJames Feist { 3307e860f15SJohn Edward Broadbent if (std::find(interfaces2.begin(), 3317e860f15SJohn Edward Broadbent interfaces2.end(), 33223a21a1cSEd Tanous interface) != interfaces2.end()) 3331c8fba97SJames Feist { 3341c8fba97SJames Feist getIndicatorLedState(asyncResp); 3359f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 3361c8fba97SJames Feist break; 3371c8fba97SJames Feist } 3381c8fba97SJames Feist } 3391c8fba97SJames Feist 34055c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 34162d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 34290728b54SEd Tanous const boost::system::error_code /*ec2*/, 343b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& 3447e860f15SJohn Edward Broadbent propertiesList) { 345168e20c1SEd Tanous for (const std::pair< 346168e20c1SEd Tanous std::string, 347168e20c1SEd Tanous dbus::utility::DbusVariantType>& 3481214b7e7SGunnar Mills property : propertiesList) 3491abe55efSEd Tanous { 3507e860f15SJohn Edward Broadbent // Store DBus properties that are also 3517e860f15SJohn Edward Broadbent // Redfish properties with same name and a 3527e860f15SJohn Edward Broadbent // string value 35399cffd7fSShawn McCarney const std::string& propertyName = 35499cffd7fSShawn McCarney property.first; 35599cffd7fSShawn McCarney if ((propertyName == "PartNumber") || 35699cffd7fSShawn McCarney (propertyName == "SerialNumber") || 35799cffd7fSShawn McCarney (propertyName == "Manufacturer") || 358caa11f7aSAlpana Kumari (propertyName == "Model") || 359caa11f7aSAlpana Kumari (propertyName == "SparePartNumber")) 36099cffd7fSShawn McCarney { 361daf36e2eSEd Tanous const std::string* value = 36299cffd7fSShawn McCarney std::get_if<std::string>( 36399cffd7fSShawn McCarney &property.second); 364caa11f7aSAlpana Kumari if (value == nullptr) 3651abe55efSEd Tanous { 366caa11f7aSAlpana Kumari BMCWEB_LOG_ERROR 367caa11f7aSAlpana Kumari << "Null value returned for " 368caa11f7aSAlpana Kumari << propertyName; 369caa11f7aSAlpana Kumari messages::internalError( 370caa11f7aSAlpana Kumari asyncResp->res); 371caa11f7aSAlpana Kumari return; 372daf36e2eSEd Tanous } 373caa11f7aSAlpana Kumari // SparePartNumber is optional on D-Bus 374caa11f7aSAlpana Kumari // so skip if it is empty 375caa11f7aSAlpana Kumari if (propertyName == "SparePartNumber") 376caa11f7aSAlpana Kumari { 37726f6976fSEd Tanous if (value->empty()) 378caa11f7aSAlpana Kumari { 379caa11f7aSAlpana Kumari continue; 380caa11f7aSAlpana Kumari } 381caa11f7aSAlpana Kumari } 382caa11f7aSAlpana Kumari asyncResp->res.jsonValue[propertyName] = 383caa11f7aSAlpana Kumari *value; 384daf36e2eSEd Tanous } 38599cffd7fSShawn McCarney } 38662d5e2e4SEd Tanous asyncResp->res.jsonValue["Name"] = chassisId; 38762d5e2e4SEd Tanous asyncResp->res.jsonValue["Id"] = chassisId; 3880256b694Szhanghch05 #ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL 389*1476687dSEd Tanous asyncResp->res 390*1476687dSEd Tanous .jsonValue["Thermal"]["@odata.id"] = 391*1476687dSEd Tanous "/redfish/v1/Chassis/" + chassisId + 392*1476687dSEd Tanous "/Thermal"; 3932474adfaSEd Tanous // Power object 394*1476687dSEd Tanous asyncResp->res.jsonValue["Power"]["@odata.id"] = 395*1476687dSEd Tanous "/redfish/v1/Chassis/" + chassisId + 396*1476687dSEd Tanous "/Power"; 3970256b694Szhanghch05 #endif 39895a3ecadSAnthony Wilson // SensorCollection 399029573d4SEd Tanous asyncResp->res 400*1476687dSEd Tanous .jsonValue["Sensors"]["@odata.id"] = 401*1476687dSEd Tanous "/redfish/v1/Chassis/" + chassisId + 402*1476687dSEd Tanous "/Sensors"; 403*1476687dSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 404*1476687dSEd Tanous "Enabled"; 405*1476687dSEd Tanous 406*1476687dSEd Tanous nlohmann::json::array_t computerSystems; 407*1476687dSEd Tanous nlohmann::json::object_t system; 408*1476687dSEd Tanous system["@odata.id"] = 409*1476687dSEd Tanous "/redfish/v1/Systems/system"; 410*1476687dSEd Tanous computerSystems.push_back(std::move(system)); 411*1476687dSEd Tanous asyncResp->res 412*1476687dSEd Tanous .jsonValue["Links"]["ComputerSystems"] = 413*1476687dSEd Tanous std::move(computerSystems); 414*1476687dSEd Tanous 415*1476687dSEd Tanous nlohmann::json::array_t managedBy; 416*1476687dSEd Tanous nlohmann::json::object_t manager; 417*1476687dSEd Tanous manager["@odata.id"] = 418*1476687dSEd Tanous "/redfish/v1/Managers/bmc"; 419*1476687dSEd Tanous managedBy.push_back(std::move(manager)); 4207e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Links"]["ManagedBy"] = 421*1476687dSEd Tanous std::move(managedBy); 422beeca0aeSGunnar Mills getChassisState(asyncResp); 423daf36e2eSEd Tanous }, 4247e860f15SJohn Edward Broadbent connectionName, path, 4257e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "GetAll", 4261abe55efSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset"); 4272c37b4b0SSharad Yadav 428308f70c7SWilly Tu for (const auto& interface : interfaces2) 4292c37b4b0SSharad Yadav { 430308f70c7SWilly Tu if (interface == "xyz.openbmc_project.Common.UUID") 4312c37b4b0SSharad Yadav { 432308f70c7SWilly Tu getChassisUUID(asyncResp, connectionName, path); 4332c37b4b0SSharad Yadav } 4340fda0f12SGeorge Liu else if ( 4350fda0f12SGeorge Liu interface == 4360fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.LocationCode") 4372c37b4b0SSharad Yadav { 438308f70c7SWilly Tu getChassisLocationCode(asyncResp, 439308f70c7SWilly Tu connectionName, path); 4402c37b4b0SSharad Yadav } 4412c37b4b0SSharad Yadav } 4422c37b4b0SSharad Yadav 443daf36e2eSEd Tanous return; 444daf36e2eSEd Tanous } 445e0d918bcSEd Tanous 446daf36e2eSEd Tanous // Couldn't find an object with that name. return an error 447f12894f8SJason M. Bills messages::resourceNotFound( 4485ac5a2f4SGunnar Mills asyncResp->res, "#Chassis.v1_16_0.Chassis", chassisId); 449daf36e2eSEd Tanous }, 450daf36e2eSEd Tanous "xyz.openbmc_project.ObjectMapper", 451daf36e2eSEd Tanous "/xyz/openbmc_project/object_mapper", 452daf36e2eSEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 453271584abSEd Tanous "/xyz/openbmc_project/inventory", 0, interfaces); 454c181942fSQiang XU 455c181942fSQiang XU getPhysicalSecurityData(asyncResp); 4567e860f15SJohn Edward Broadbent }); 4571c8fba97SJames Feist 4587e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 459ed398213SEd Tanous .privileges(redfish::privileges::patchChassis) 4607e860f15SJohn Edward Broadbent .methods( 4617e860f15SJohn Edward Broadbent boost::beast::http::verb:: 46245ca1b86SEd Tanous patch)([&app]( 46345ca1b86SEd Tanous const crow::Request& req, 4647e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4657e860f15SJohn Edward Broadbent const std::string& param) { 46645ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 46745ca1b86SEd Tanous { 46845ca1b86SEd Tanous return; 46945ca1b86SEd Tanous } 4709f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 4711c8fba97SJames Feist std::optional<std::string> indicatorLed; 4721c8fba97SJames Feist 4737e860f15SJohn Edward Broadbent if (param.empty()) 4741c8fba97SJames Feist { 4751c8fba97SJames Feist return; 4761c8fba97SJames Feist } 4771c8fba97SJames Feist 47815ed6780SWilly Tu if (!json_util::readJsonPatch( 4797e860f15SJohn Edward Broadbent req, asyncResp->res, "LocationIndicatorActive", 4807e860f15SJohn Edward Broadbent locationIndicatorActive, "IndicatorLED", indicatorLed)) 4811c8fba97SJames Feist { 4821c8fba97SJames Feist return; 4831c8fba97SJames Feist } 4841c8fba97SJames Feist 4859f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 4869f8bfa7cSGunnar Mills if (!locationIndicatorActive && !indicatorLed) 4871c8fba97SJames Feist { 4881c8fba97SJames Feist return; // delete this when we support more patch properties 4891c8fba97SJames Feist } 490d6aa0093SGunnar Mills if (indicatorLed) 491d6aa0093SGunnar Mills { 4927e860f15SJohn Edward Broadbent asyncResp->res.addHeader( 4937e860f15SJohn Edward Broadbent boost::beast::http::field::warning, 4940fda0f12SGeorge Liu "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\""); 495d6aa0093SGunnar Mills } 4961c8fba97SJames Feist 4971c8fba97SJames Feist const std::array<const char*, 2> interfaces = { 4981c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Board", 4991c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Chassis"}; 5001c8fba97SJames Feist 5017e860f15SJohn Edward Broadbent const std::string& chassisId = param; 5021c8fba97SJames Feist 5031c8fba97SJames Feist crow::connections::systemBus->async_method_call( 5049f8bfa7cSGunnar Mills [asyncResp, chassisId, locationIndicatorActive, indicatorLed]( 5051c8fba97SJames Feist const boost::system::error_code ec, 506b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 5071c8fba97SJames Feist if (ec) 5081c8fba97SJames Feist { 5091c8fba97SJames Feist messages::internalError(asyncResp->res); 5101c8fba97SJames Feist return; 5111c8fba97SJames Feist } 5121c8fba97SJames Feist 5131c8fba97SJames Feist // Iterate over all retrieved ObjectPaths. 5141c8fba97SJames Feist for (const std::pair< 5151c8fba97SJames Feist std::string, 5167e860f15SJohn Edward Broadbent std::vector<std::pair<std::string, 5177e860f15SJohn Edward Broadbent std::vector<std::string>>>>& 5181214b7e7SGunnar Mills object : subtree) 5191c8fba97SJames Feist { 5201c8fba97SJames Feist const std::string& path = object.first; 5211c8fba97SJames Feist const std::vector< 5221214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 5231214b7e7SGunnar Mills connectionNames = object.second; 5241c8fba97SJames Feist 525997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 526997093ebSGeorge Liu if (objPath.filename() != chassisId) 5271c8fba97SJames Feist { 5281c8fba97SJames Feist continue; 5291c8fba97SJames Feist } 5301c8fba97SJames Feist 53126f6976fSEd Tanous if (connectionNames.empty()) 5321c8fba97SJames Feist { 5331c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 5341c8fba97SJames Feist continue; 5351c8fba97SJames Feist } 5361c8fba97SJames Feist 53723a21a1cSEd Tanous const std::vector<std::string>& interfaces3 = 5381c8fba97SJames Feist connectionNames[0].second; 5391c8fba97SJames Feist 5401c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 5411c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 5420fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 5431c8fba97SJames Feist bool indicatorChassis = false; 5441c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 5451c8fba97SJames Feist { 5467e860f15SJohn Edward Broadbent if (std::find(interfaces3.begin(), 5477e860f15SJohn Edward Broadbent interfaces3.end(), 54823a21a1cSEd Tanous interface) != interfaces3.end()) 5491c8fba97SJames Feist { 5501c8fba97SJames Feist indicatorChassis = true; 5511c8fba97SJames Feist break; 5521c8fba97SJames Feist } 5531c8fba97SJames Feist } 5549f8bfa7cSGunnar Mills if (locationIndicatorActive) 5559f8bfa7cSGunnar Mills { 5569f8bfa7cSGunnar Mills if (indicatorChassis) 5579f8bfa7cSGunnar Mills { 5589f8bfa7cSGunnar Mills setLocationIndicatorActive( 5599f8bfa7cSGunnar Mills asyncResp, *locationIndicatorActive); 5609f8bfa7cSGunnar Mills } 5619f8bfa7cSGunnar Mills else 5629f8bfa7cSGunnar Mills { 5639f8bfa7cSGunnar Mills messages::propertyUnknown( 5649f8bfa7cSGunnar Mills asyncResp->res, "LocationIndicatorActive"); 5659f8bfa7cSGunnar Mills } 5669f8bfa7cSGunnar Mills } 5679f8bfa7cSGunnar Mills if (indicatorLed) 5689f8bfa7cSGunnar Mills { 5691c8fba97SJames Feist if (indicatorChassis) 5701c8fba97SJames Feist { 571f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 5721c8fba97SJames Feist } 5731c8fba97SJames Feist else 5741c8fba97SJames Feist { 5751c8fba97SJames Feist messages::propertyUnknown(asyncResp->res, 5761c8fba97SJames Feist "IndicatorLED"); 5771c8fba97SJames Feist } 5781c8fba97SJames Feist } 5791c8fba97SJames Feist return; 5801c8fba97SJames Feist } 5811c8fba97SJames Feist 5821c8fba97SJames Feist messages::resourceNotFound( 5839f8bfa7cSGunnar Mills asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId); 5841c8fba97SJames Feist }, 5851c8fba97SJames Feist "xyz.openbmc_project.ObjectMapper", 5861c8fba97SJames Feist "/xyz/openbmc_project/object_mapper", 5871c8fba97SJames Feist "xyz.openbmc_project.ObjectMapper", "GetSubTree", 5881c8fba97SJames Feist "/xyz/openbmc_project/inventory", 0, interfaces); 5897e860f15SJohn Edward Broadbent }); 5901c8fba97SJames Feist } 591dd99e04bSP.K. Lee 5928d1b46d7Szhanghch05 inline void 5938d1b46d7Szhanghch05 doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 594dd99e04bSP.K. Lee { 595c3b3c92aSVijay Khemka const char* busName = "xyz.openbmc_project.ObjectMapper"; 596c3b3c92aSVijay Khemka const char* path = "/xyz/openbmc_project/object_mapper"; 597c3b3c92aSVijay Khemka const char* interface = "xyz.openbmc_project.ObjectMapper"; 598c3b3c92aSVijay Khemka const char* method = "GetSubTreePaths"; 599c3b3c92aSVijay Khemka 600c3b3c92aSVijay Khemka const std::array<const char*, 1> interfaces = { 601c3b3c92aSVijay Khemka "xyz.openbmc_project.State.Chassis"}; 602c3b3c92aSVijay Khemka 603c3b3c92aSVijay Khemka // Use mapper to get subtree paths. 604c3b3c92aSVijay Khemka crow::connections::systemBus->async_method_call( 605b9d36b47SEd Tanous [asyncResp]( 606b9d36b47SEd Tanous const boost::system::error_code ec, 607b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreePathsResponse& chassisList) { 608c3b3c92aSVijay Khemka if (ec) 609c3b3c92aSVijay Khemka { 610c3b3c92aSVijay Khemka BMCWEB_LOG_DEBUG << "[mapper] Bad D-Bus request error: " << ec; 611c3b3c92aSVijay Khemka messages::internalError(asyncResp->res); 612c3b3c92aSVijay Khemka return; 613c3b3c92aSVijay Khemka } 614c3b3c92aSVijay Khemka 615dd99e04bSP.K. Lee const char* processName = "xyz.openbmc_project.State.Chassis"; 616dd99e04bSP.K. Lee const char* interfaceName = "xyz.openbmc_project.State.Chassis"; 617dd99e04bSP.K. Lee const char* destProperty = "RequestedPowerTransition"; 618dd99e04bSP.K. Lee const std::string propertyValue = 619dd99e04bSP.K. Lee "xyz.openbmc_project.State.Chassis.Transition.PowerCycle"; 620c3b3c92aSVijay Khemka std::string objectPath = 621c3b3c92aSVijay Khemka "/xyz/openbmc_project/state/chassis_system0"; 622c3b3c92aSVijay Khemka 623c3b3c92aSVijay Khemka /* Look for system reset chassis path */ 624c3b3c92aSVijay Khemka if ((std::find(chassisList.begin(), chassisList.end(), 625c3b3c92aSVijay Khemka objectPath)) == chassisList.end()) 626c3b3c92aSVijay Khemka { 627c3b3c92aSVijay Khemka /* We prefer to reset the full chassis_system, but if it doesn't 628c3b3c92aSVijay Khemka * exist on some platforms, fall back to a host-only power reset 629c3b3c92aSVijay Khemka */ 630c3b3c92aSVijay Khemka objectPath = "/xyz/openbmc_project/state/chassis0"; 631c3b3c92aSVijay Khemka } 632dd99e04bSP.K. Lee 633dd99e04bSP.K. Lee crow::connections::systemBus->async_method_call( 634dd99e04bSP.K. Lee [asyncResp](const boost::system::error_code ec) { 635dd99e04bSP.K. Lee // Use "Set" method to set the property value. 636dd99e04bSP.K. Lee if (ec) 637dd99e04bSP.K. Lee { 638c3b3c92aSVijay Khemka BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " 639c3b3c92aSVijay Khemka << ec; 640dd99e04bSP.K. Lee messages::internalError(asyncResp->res); 641dd99e04bSP.K. Lee return; 642dd99e04bSP.K. Lee } 643dd99e04bSP.K. Lee 644dd99e04bSP.K. Lee messages::success(asyncResp->res); 645dd99e04bSP.K. Lee }, 646c3b3c92aSVijay Khemka processName, objectPath, "org.freedesktop.DBus.Properties", 647c3b3c92aSVijay Khemka "Set", interfaceName, destProperty, 648168e20c1SEd Tanous dbus::utility::DbusVariantType{propertyValue}); 649c3b3c92aSVijay Khemka }, 650c3b3c92aSVijay Khemka busName, path, interface, method, "/", 0, interfaces); 651dd99e04bSP.K. Lee } 652dd99e04bSP.K. Lee 653dd99e04bSP.K. Lee /** 654dd99e04bSP.K. Lee * ChassisResetAction class supports the POST method for the Reset 655dd99e04bSP.K. Lee * action. 656dd99e04bSP.K. Lee * Function handles POST method request. 657dd99e04bSP.K. Lee * Analyzes POST body before sending Reset request data to D-Bus. 658dd99e04bSP.K. Lee */ 6597e860f15SJohn Edward Broadbent 6607e860f15SJohn Edward Broadbent inline void requestRoutesChassisResetAction(App& app) 661dd99e04bSP.K. Lee { 6627e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/") 663ed398213SEd Tanous .privileges(redfish::privileges::postChassis) 6647e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)( 66545ca1b86SEd Tanous [&app](const crow::Request& req, 6667e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6677e860f15SJohn Edward Broadbent const std::string&) { 66845ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 66945ca1b86SEd Tanous { 67045ca1b86SEd Tanous return; 67145ca1b86SEd Tanous } 672dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Post Chassis Reset."; 673dd99e04bSP.K. Lee 674dd99e04bSP.K. Lee std::string resetType; 675dd99e04bSP.K. Lee 67615ed6780SWilly Tu if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", 6777e860f15SJohn Edward Broadbent resetType)) 678dd99e04bSP.K. Lee { 679dd99e04bSP.K. Lee return; 680dd99e04bSP.K. Lee } 681dd99e04bSP.K. Lee 682dd99e04bSP.K. Lee if (resetType != "PowerCycle") 683dd99e04bSP.K. Lee { 684dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: " 685dd99e04bSP.K. Lee << resetType; 6867e860f15SJohn Edward Broadbent messages::actionParameterNotSupported( 6877e860f15SJohn Edward Broadbent asyncResp->res, resetType, "ResetType"); 688dd99e04bSP.K. Lee 689dd99e04bSP.K. Lee return; 690dd99e04bSP.K. Lee } 691dd99e04bSP.K. Lee doChassisPowerCycle(asyncResp); 6927e860f15SJohn Edward Broadbent }); 693dd99e04bSP.K. Lee } 6941cb1a9e6SAppaRao Puli 6951cb1a9e6SAppaRao Puli /** 6961cb1a9e6SAppaRao Puli * ChassisResetActionInfo derived class for delivering Chassis 6971cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 6981cb1a9e6SAppaRao Puli */ 6997e860f15SJohn Edward Broadbent inline void requestRoutesChassisResetActionInfo(App& app) 7001cb1a9e6SAppaRao Puli { 7017e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/") 702ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 7037e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 70445ca1b86SEd Tanous [&app](const crow::Request& req, 7057e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 70645ca1b86SEd Tanous const std::string& chassisId) { 70745ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 7081cb1a9e6SAppaRao Puli { 70945ca1b86SEd Tanous return; 71045ca1b86SEd Tanous } 711*1476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 712*1476687dSEd Tanous "#ActionInfo.v1_1_2.ActionInfo"; 713*1476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 714*1476687dSEd Tanous "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo"; 715*1476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 716*1476687dSEd Tanous 717*1476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 718*1476687dSEd Tanous nlohmann::json::object_t parameters; 719*1476687dSEd Tanous parameters["Name"] = "ResetType"; 720*1476687dSEd Tanous parameters["Required"] = true; 721*1476687dSEd Tanous parameters["DataType"] = "String"; 722*1476687dSEd Tanous nlohmann::json::array_t allowed; 723*1476687dSEd Tanous allowed.push_back("PowerCycle"); 724*1476687dSEd Tanous parameters["AllowableValues"] = std::move(allowed); 725*1476687dSEd Tanous asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 7267e860f15SJohn Edward Broadbent }); 7271cb1a9e6SAppaRao Puli } 7281cb1a9e6SAppaRao Puli 729e37f8451SRapkiewicz, Pawel } // namespace redfish 730