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> 22e37f8451SRapkiewicz, Pawel #include <boost/container/flat_map.hpp> 23168e20c1SEd Tanous #include <dbus_utility.hpp> 24ed398213SEd Tanous #include <registries/privilege_registry.hpp> 25*1e1e598dSJonathan 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 { 40*1e1e598dSJonathan Doman // crow::connections::systemBus->async_method_call( 41*1e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 42*1e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis", 43*1e1e598dSJonathan Doman "/xyz/openbmc_project/state/chassis0", 44*1e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis", "CurrentPowerState", 45*1e1e598dSJonathan Doman [aResp{std::move(aResp)}](const boost::system::error_code ec, 46*1e1e598dSJonathan Doman const std::string& chassisState) { 47beeca0aeSGunnar Mills if (ec) 48beeca0aeSGunnar Mills { 49beeca0aeSGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 50beeca0aeSGunnar Mills messages::internalError(aResp->res); 51beeca0aeSGunnar Mills return; 52beeca0aeSGunnar Mills } 53beeca0aeSGunnar Mills 54*1e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Chassis state: " << chassisState; 55beeca0aeSGunnar Mills // Verify Chassis State 56*1e1e598dSJonathan Doman if (chassisState == 57*1e1e598dSJonathan Doman "xyz.openbmc_project.State.Chassis.PowerState.On") 58beeca0aeSGunnar Mills { 59beeca0aeSGunnar Mills aResp->res.jsonValue["PowerState"] = "On"; 60beeca0aeSGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 61beeca0aeSGunnar Mills } 62*1e1e598dSJonathan Doman else if (chassisState == 63beeca0aeSGunnar Mills "xyz.openbmc_project.State.Chassis.PowerState.Off") 64beeca0aeSGunnar Mills { 65beeca0aeSGunnar Mills aResp->res.jsonValue["PowerState"] = "Off"; 66beeca0aeSGunnar Mills aResp->res.jsonValue["Status"]["State"] = "StandbyOffline"; 67beeca0aeSGunnar Mills } 68*1e1e598dSJonathan Doman }); 69beeca0aeSGunnar Mills } 70beeca0aeSGunnar Mills 71beeca0aeSGunnar Mills /** 72e37f8451SRapkiewicz, Pawel * DBus types primitives for several generic DBus interfaces 73e37f8451SRapkiewicz, Pawel * TODO(Pawel) consider move this to separate file into boost::dbus 74e37f8451SRapkiewicz, Pawel */ 75aa2e59c1SEd Tanous using ManagedObjectsType = std::vector<std::pair< 76aa2e59c1SEd Tanous sdbusplus::message::object_path, 77168e20c1SEd Tanous std::vector<std::pair< 78168e20c1SEd Tanous std::string, 79168e20c1SEd Tanous std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>>>>>; 80e37f8451SRapkiewicz, Pawel 81168e20c1SEd Tanous using PropertiesType = 82168e20c1SEd Tanous boost::container::flat_map<std::string, dbus::utility::DbusVariantType>; 83e37f8451SRapkiewicz, Pawel 848d1b46d7Szhanghch05 inline void getIntrusionByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 85c181942fSQiang XU const std::string& service, 86c181942fSQiang XU const std::string& objPath) 87c181942fSQiang XU { 88c181942fSQiang XU BMCWEB_LOG_DEBUG << "Get intrusion status by service \n"; 89c181942fSQiang XU 90*1e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 91*1e1e598dSJonathan Doman *crow::connections::systemBus, service, objPath, 92*1e1e598dSJonathan Doman "xyz.openbmc_project.Chassis.Intrusion", "Status", 93c181942fSQiang XU [aResp{std::move(aResp)}](const boost::system::error_code ec, 94*1e1e598dSJonathan Doman const std::string& value) { 95c181942fSQiang XU if (ec) 96c181942fSQiang XU { 974e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 98c181942fSQiang XU // mandatory property 99c181942fSQiang XU BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n"; 100c181942fSQiang XU return; 101c181942fSQiang XU } 102c181942fSQiang XU 103c181942fSQiang XU aResp->res.jsonValue["PhysicalSecurity"] = { 104*1e1e598dSJonathan Doman {"IntrusionSensorNumber", 1}, {"IntrusionSensor", value}}; 105*1e1e598dSJonathan Doman }); 106c181942fSQiang XU } 107c181942fSQiang XU 108c181942fSQiang XU /** 109c181942fSQiang XU * Retrieves physical security properties over dbus 110c181942fSQiang XU */ 1118d1b46d7Szhanghch05 inline void getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> aResp) 112c181942fSQiang XU { 113c181942fSQiang XU crow::connections::systemBus->async_method_call( 114c181942fSQiang XU [aResp{std::move(aResp)}]( 115c181942fSQiang XU const boost::system::error_code ec, 116c181942fSQiang XU const std::vector<std::pair< 117c181942fSQiang XU std::string, 1181214b7e7SGunnar Mills std::vector<std::pair<std::string, std::vector<std::string>>>>>& 1191214b7e7SGunnar Mills subtree) { 120c181942fSQiang XU if (ec) 121c181942fSQiang XU { 1224e0453b1SGunnar Mills // do not add err msg in redfish response, because this is not 123c181942fSQiang XU // mandatory property 12454fbf177SAndrew Geissler BMCWEB_LOG_INFO << "DBUS error: no matched iface " << ec 125c181942fSQiang XU << "\n"; 126c181942fSQiang XU return; 127c181942fSQiang XU } 128c181942fSQiang XU // Iterate over all retrieved ObjectPaths. 129c181942fSQiang XU for (const auto& object : subtree) 130c181942fSQiang XU { 131c181942fSQiang XU for (const auto& service : object.second) 132c181942fSQiang XU { 133c181942fSQiang XU getIntrusionByService(aResp, service.first, object.first); 134c181942fSQiang XU return; 135c181942fSQiang XU } 136c181942fSQiang XU } 137c181942fSQiang XU }, 138c181942fSQiang XU "xyz.openbmc_project.ObjectMapper", 139c181942fSQiang XU "/xyz/openbmc_project/object_mapper", 140c181942fSQiang XU "xyz.openbmc_project.ObjectMapper", "GetSubTree", 141271584abSEd Tanous "/xyz/openbmc_project/Intrusion", 1, 142c181942fSQiang XU std::array<const char*, 1>{"xyz.openbmc_project.Chassis.Intrusion"}); 143c181942fSQiang XU } 144c181942fSQiang XU 145e37f8451SRapkiewicz, Pawel /** 146e37f8451SRapkiewicz, Pawel * ChassisCollection derived class for delivering Chassis Collection Schema 147e37f8451SRapkiewicz, Pawel * Functions triggers appropriate requests on DBus 148e37f8451SRapkiewicz, Pawel */ 1497e860f15SJohn Edward Broadbent inline void requestRoutesChassisCollection(App& app) 1501abe55efSEd Tanous { 1517e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/") 152ed398213SEd Tanous .privileges(redfish::privileges::getChassisCollection) 1537e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 1547e860f15SJohn Edward Broadbent [](const crow::Request&, 1557e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1568d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 1578d1b46d7Szhanghch05 "#ChassisCollection.ChassisCollection"; 1588d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis"; 1598d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Chassis Collection"; 160e37f8451SRapkiewicz, Pawel 16102f6ff19SGunnar Mills collection_util::getCollectionMembers( 16202f6ff19SGunnar Mills asyncResp, "/redfish/v1/Chassis", 16302f6ff19SGunnar Mills {"xyz.openbmc_project.Inventory.Item.Board", 16402f6ff19SGunnar Mills "xyz.openbmc_project.Inventory.Item.Chassis"}); 1657e860f15SJohn Edward Broadbent }); 16662d5e2e4SEd Tanous } 167e37f8451SRapkiewicz, Pawel 168308f70c7SWilly Tu inline void 169308f70c7SWilly Tu getChassisLocationCode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 170308f70c7SWilly Tu const std::string& connectionName, 171308f70c7SWilly Tu const std::string& path) 172308f70c7SWilly Tu { 173*1e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 174*1e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 175*1e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode", 176308f70c7SWilly Tu [asyncResp](const boost::system::error_code ec, 177*1e1e598dSJonathan Doman const std::string& property) { 178308f70c7SWilly Tu if (ec) 179308f70c7SWilly Tu { 1800fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error for Location"; 181308f70c7SWilly Tu messages::internalError(asyncResp->res); 182308f70c7SWilly Tu return; 183308f70c7SWilly Tu } 184308f70c7SWilly Tu 185308f70c7SWilly Tu asyncResp->res 186*1e1e598dSJonathan Doman .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 187*1e1e598dSJonathan Doman property; 188*1e1e598dSJonathan Doman }); 189308f70c7SWilly Tu } 190308f70c7SWilly Tu 191308f70c7SWilly Tu inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 192308f70c7SWilly Tu const std::string& connectionName, 193308f70c7SWilly Tu const std::string& path) 194308f70c7SWilly Tu { 195*1e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 196*1e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, path, 197*1e1e598dSJonathan Doman "xyz.openbmc_project.Common.UUID", "UUID", 198308f70c7SWilly Tu [asyncResp](const boost::system::error_code ec, 199*1e1e598dSJonathan Doman const std::string& chassisUUID) { 200308f70c7SWilly Tu if (ec) 201308f70c7SWilly Tu { 2020fda0f12SGeorge Liu BMCWEB_LOG_DEBUG << "DBUS response error for UUID"; 203308f70c7SWilly Tu messages::internalError(asyncResp->res); 204308f70c7SWilly Tu return; 205308f70c7SWilly Tu } 206*1e1e598dSJonathan Doman asyncResp->res.jsonValue["UUID"] = chassisUUID; 207*1e1e598dSJonathan Doman }); 208308f70c7SWilly Tu } 209308f70c7SWilly Tu 210e37f8451SRapkiewicz, Pawel /** 211e37f8451SRapkiewicz, Pawel * Chassis override class for delivering Chassis Schema 212e37f8451SRapkiewicz, Pawel * Functions triggers appropriate requests on DBus 213e37f8451SRapkiewicz, Pawel */ 2147e860f15SJohn Edward Broadbent inline void requestRoutesChassis(App& app) 2151abe55efSEd Tanous { 2167e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 217ed398213SEd Tanous .privileges(redfish::privileges::getChassis) 2187e860f15SJohn Edward Broadbent .methods( 2197e860f15SJohn Edward Broadbent boost::beast::http::verb::get)([](const crow::Request&, 2207e860f15SJohn Edward Broadbent const std::shared_ptr< 2217e860f15SJohn Edward Broadbent bmcweb::AsyncResp>& asyncResp, 2227e860f15SJohn Edward Broadbent const std::string& chassisId) { 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, 2301c8fba97SJames Feist const crow::openbmc_mapper::GetSubTreeType& 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 257*1e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::vector<std::string>>( 258*1e1e598dSJonathan Doman *crow::connections::systemBus, 259*1e1e598dSJonathan Doman "xyz.openbmc_project.ObjectMapper", 260*1e1e598dSJonathan Doman path + "/all_sensors", 261*1e1e598dSJonathan Doman "xyz.openbmc_project.Association", "endpoints", 262168e20c1SEd Tanous [health](const boost::system::error_code ec2, 263*1e1e598dSJonathan Doman const std::vector<std::string>& resp) { 26423a21a1cSEd Tanous if (ec2) 265b49ac873SJames Feist { 266b49ac873SJames Feist return; // no sensors = no failures 267b49ac873SJames Feist } 268*1e1e598dSJonathan Doman health->inventory = resp; 269*1e1e598dSJonathan Doman }); 270b49ac873SJames Feist 271b49ac873SJames Feist health->populate(); 272b49ac873SJames Feist 2731abe55efSEd Tanous if (connectionNames.size() < 1) 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"] = 2809f8bfa7cSGunnar Mills "#Chassis.v1_14_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"; 2857e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"] = 2867e860f15SJohn Edward Broadbent {{"target", "/redfish/v1/Chassis/" + chassisId + 287dd99e04bSP.K. Lee "/Actions/Chassis.Reset"}, 2881cb1a9e6SAppaRao Puli {"@Redfish.ActionInfo", "/redfish/v1/Chassis/" + 2891cb1a9e6SAppaRao Puli chassisId + 2901cb1a9e6SAppaRao Puli "/ResetActionInfo"}}; 291adbe192aSJason M. Bills asyncResp->res.jsonValue["PCIeDevices"] = { 292adbe192aSJason M. Bills {"@odata.id", 293adbe192aSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices"}}; 29449c53ac9SJohnathan Mantey 29549c53ac9SJohnathan Mantey const std::string& connectionName = 29649c53ac9SJohnathan Mantey connectionNames[0].first; 2971c8fba97SJames Feist 29823a21a1cSEd Tanous const std::vector<std::string>& interfaces2 = 2991c8fba97SJames Feist connectionNames[0].second; 3001c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 3011c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 3020fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 3031c8fba97SJames Feist 304476b9cc5STejas Patil const std::string assetTagInterface = 3050fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.AssetTag"; 306476b9cc5STejas Patil if (std::find(interfaces2.begin(), interfaces2.end(), 307476b9cc5STejas Patil assetTagInterface) != interfaces2.end()) 308476b9cc5STejas Patil { 309*1e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 310*1e1e598dSJonathan Doman *crow::connections::systemBus, connectionName, 311*1e1e598dSJonathan Doman path, assetTagInterface, "AssetTag", 312476b9cc5STejas Patil [asyncResp, chassisId(std::string(chassisId))]( 313476b9cc5STejas Patil const boost::system::error_code ec, 314*1e1e598dSJonathan Doman const std::string& property) { 315476b9cc5STejas Patil if (ec) 316476b9cc5STejas Patil { 317476b9cc5STejas Patil BMCWEB_LOG_DEBUG 3180fda0f12SGeorge Liu << "DBus response error for AssetTag"; 319476b9cc5STejas Patil messages::internalError(asyncResp->res); 320476b9cc5STejas Patil return; 321476b9cc5STejas Patil } 322476b9cc5STejas Patil asyncResp->res.jsonValue["AssetTag"] = 323*1e1e598dSJonathan Doman property; 324*1e1e598dSJonathan Doman }); 325476b9cc5STejas Patil } 326476b9cc5STejas Patil 3271c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 3281c8fba97SJames Feist { 3297e860f15SJohn Edward Broadbent if (std::find(interfaces2.begin(), 3307e860f15SJohn Edward Broadbent interfaces2.end(), 33123a21a1cSEd Tanous interface) != interfaces2.end()) 3321c8fba97SJames Feist { 3331c8fba97SJames Feist getIndicatorLedState(asyncResp); 3349f8bfa7cSGunnar Mills getLocationIndicatorActive(asyncResp); 3351c8fba97SJames Feist break; 3361c8fba97SJames Feist } 3371c8fba97SJames Feist } 3381c8fba97SJames Feist 33955c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 34062d5e2e4SEd Tanous [asyncResp, chassisId(std::string(chassisId))]( 34190728b54SEd Tanous const boost::system::error_code /*ec2*/, 3427e860f15SJohn Edward Broadbent const std::vector< 343168e20c1SEd Tanous std::pair<std::string, 344168e20c1SEd Tanous dbus::utility::DbusVariantType>>& 3457e860f15SJohn Edward Broadbent propertiesList) { 346168e20c1SEd Tanous for (const std::pair< 347168e20c1SEd Tanous std::string, 348168e20c1SEd Tanous dbus::utility::DbusVariantType>& 3491214b7e7SGunnar Mills property : propertiesList) 3501abe55efSEd Tanous { 3517e860f15SJohn Edward Broadbent // Store DBus properties that are also 3527e860f15SJohn Edward Broadbent // Redfish properties with same name and a 3537e860f15SJohn Edward Broadbent // string value 35499cffd7fSShawn McCarney const std::string& propertyName = 35599cffd7fSShawn McCarney property.first; 35699cffd7fSShawn McCarney if ((propertyName == "PartNumber") || 35799cffd7fSShawn McCarney (propertyName == "SerialNumber") || 35899cffd7fSShawn McCarney (propertyName == "Manufacturer") || 359caa11f7aSAlpana Kumari (propertyName == "Model") || 360caa11f7aSAlpana Kumari (propertyName == "SparePartNumber")) 36199cffd7fSShawn McCarney { 362daf36e2eSEd Tanous const std::string* value = 36399cffd7fSShawn McCarney std::get_if<std::string>( 36499cffd7fSShawn McCarney &property.second); 365caa11f7aSAlpana Kumari if (value == nullptr) 3661abe55efSEd Tanous { 367caa11f7aSAlpana Kumari BMCWEB_LOG_ERROR 368caa11f7aSAlpana Kumari << "Null value returned for " 369caa11f7aSAlpana Kumari << propertyName; 370caa11f7aSAlpana Kumari messages::internalError( 371caa11f7aSAlpana Kumari asyncResp->res); 372caa11f7aSAlpana Kumari return; 373daf36e2eSEd Tanous } 374caa11f7aSAlpana Kumari // SparePartNumber is optional on D-Bus 375caa11f7aSAlpana Kumari // so skip if it is empty 376caa11f7aSAlpana Kumari if (propertyName == "SparePartNumber") 377caa11f7aSAlpana Kumari { 378caa11f7aSAlpana Kumari if (*value == "") 379caa11f7aSAlpana Kumari { 380caa11f7aSAlpana Kumari continue; 381caa11f7aSAlpana Kumari } 382caa11f7aSAlpana Kumari } 383caa11f7aSAlpana Kumari asyncResp->res.jsonValue[propertyName] = 384caa11f7aSAlpana Kumari *value; 385daf36e2eSEd Tanous } 38699cffd7fSShawn McCarney } 38762d5e2e4SEd Tanous asyncResp->res.jsonValue["Name"] = chassisId; 38862d5e2e4SEd Tanous asyncResp->res.jsonValue["Id"] = chassisId; 3890256b694Szhanghch05 #ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL 39062d5e2e4SEd Tanous asyncResp->res.jsonValue["Thermal"] = { 3911abe55efSEd Tanous {"@odata.id", "/redfish/v1/Chassis/" + 3921abe55efSEd Tanous chassisId + "/Thermal"}}; 3932474adfaSEd Tanous // Power object 3942474adfaSEd Tanous asyncResp->res.jsonValue["Power"] = { 3952474adfaSEd Tanous {"@odata.id", "/redfish/v1/Chassis/" + 3962474adfaSEd Tanous chassisId + "/Power"}}; 3970256b694Szhanghch05 #endif 39895a3ecadSAnthony Wilson // SensorCollection 39995a3ecadSAnthony Wilson asyncResp->res.jsonValue["Sensors"] = { 40095a3ecadSAnthony Wilson {"@odata.id", "/redfish/v1/Chassis/" + 40195a3ecadSAnthony Wilson chassisId + "/Sensors"}}; 402029573d4SEd Tanous asyncResp->res.jsonValue["Status"] = { 403029573d4SEd Tanous {"State", "Enabled"}, 404029573d4SEd Tanous }; 4052474adfaSEd Tanous 406029573d4SEd Tanous asyncResp->res 407029573d4SEd Tanous .jsonValue["Links"]["ComputerSystems"] = { 4087e860f15SJohn Edward Broadbent {{"@odata.id", 4097e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system"}}}; 4107e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Links"]["ManagedBy"] = 4117e860f15SJohn Edward Broadbent {{{"@odata.id", 4127e860f15SJohn Edward Broadbent "/redfish/v1/Managers/bmc"}}}; 413beeca0aeSGunnar Mills getChassisState(asyncResp); 414daf36e2eSEd Tanous }, 4157e860f15SJohn Edward Broadbent connectionName, path, 4167e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "GetAll", 4171abe55efSEd Tanous "xyz.openbmc_project.Inventory.Decorator.Asset"); 4182c37b4b0SSharad Yadav 419308f70c7SWilly Tu for (const auto& interface : interfaces2) 4202c37b4b0SSharad Yadav { 421308f70c7SWilly Tu if (interface == "xyz.openbmc_project.Common.UUID") 4222c37b4b0SSharad Yadav { 423308f70c7SWilly Tu getChassisUUID(asyncResp, connectionName, path); 4242c37b4b0SSharad Yadav } 4250fda0f12SGeorge Liu else if ( 4260fda0f12SGeorge Liu interface == 4270fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.LocationCode") 4282c37b4b0SSharad Yadav { 429308f70c7SWilly Tu getChassisLocationCode(asyncResp, 430308f70c7SWilly Tu connectionName, path); 4312c37b4b0SSharad Yadav } 4322c37b4b0SSharad Yadav } 4332c37b4b0SSharad Yadav 434daf36e2eSEd Tanous return; 435daf36e2eSEd Tanous } 436e0d918bcSEd Tanous 437daf36e2eSEd Tanous // Couldn't find an object with that name. return an error 438f12894f8SJason M. Bills messages::resourceNotFound( 4399f8bfa7cSGunnar Mills asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId); 440daf36e2eSEd Tanous }, 441daf36e2eSEd Tanous "xyz.openbmc_project.ObjectMapper", 442daf36e2eSEd Tanous "/xyz/openbmc_project/object_mapper", 443daf36e2eSEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 444271584abSEd Tanous "/xyz/openbmc_project/inventory", 0, interfaces); 445c181942fSQiang XU 446c181942fSQiang XU getPhysicalSecurityData(asyncResp); 4477e860f15SJohn Edward Broadbent }); 4481c8fba97SJames Feist 4497e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/") 450ed398213SEd Tanous .privileges(redfish::privileges::patchChassis) 4517e860f15SJohn Edward Broadbent .methods( 4527e860f15SJohn Edward Broadbent boost::beast::http::verb:: 4537e860f15SJohn Edward Broadbent patch)([](const crow::Request& req, 4547e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4557e860f15SJohn Edward Broadbent const std::string& param) { 4569f8bfa7cSGunnar Mills std::optional<bool> locationIndicatorActive; 4571c8fba97SJames Feist std::optional<std::string> indicatorLed; 4581c8fba97SJames Feist 4597e860f15SJohn Edward Broadbent if (param.empty()) 4601c8fba97SJames Feist { 4611c8fba97SJames Feist return; 4621c8fba97SJames Feist } 4631c8fba97SJames Feist 4647e860f15SJohn Edward Broadbent if (!json_util::readJson( 4657e860f15SJohn Edward Broadbent req, asyncResp->res, "LocationIndicatorActive", 4667e860f15SJohn Edward Broadbent locationIndicatorActive, "IndicatorLED", indicatorLed)) 4671c8fba97SJames Feist { 4681c8fba97SJames Feist return; 4691c8fba97SJames Feist } 4701c8fba97SJames Feist 4719f8bfa7cSGunnar Mills // TODO (Gunnar): Remove IndicatorLED after enough time has passed 4729f8bfa7cSGunnar Mills if (!locationIndicatorActive && !indicatorLed) 4731c8fba97SJames Feist { 4741c8fba97SJames Feist return; // delete this when we support more patch properties 4751c8fba97SJames Feist } 476d6aa0093SGunnar Mills if (indicatorLed) 477d6aa0093SGunnar Mills { 4787e860f15SJohn Edward Broadbent asyncResp->res.addHeader( 4797e860f15SJohn Edward Broadbent boost::beast::http::field::warning, 4800fda0f12SGeorge Liu "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\""); 481d6aa0093SGunnar Mills } 4821c8fba97SJames Feist 4831c8fba97SJames Feist const std::array<const char*, 2> interfaces = { 4841c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Board", 4851c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Chassis"}; 4861c8fba97SJames Feist 4877e860f15SJohn Edward Broadbent const std::string& chassisId = param; 4881c8fba97SJames Feist 4891c8fba97SJames Feist crow::connections::systemBus->async_method_call( 4909f8bfa7cSGunnar Mills [asyncResp, chassisId, locationIndicatorActive, indicatorLed]( 4911c8fba97SJames Feist const boost::system::error_code ec, 4921c8fba97SJames Feist const crow::openbmc_mapper::GetSubTreeType& subtree) { 4931c8fba97SJames Feist if (ec) 4941c8fba97SJames Feist { 4951c8fba97SJames Feist messages::internalError(asyncResp->res); 4961c8fba97SJames Feist return; 4971c8fba97SJames Feist } 4981c8fba97SJames Feist 4991c8fba97SJames Feist // Iterate over all retrieved ObjectPaths. 5001c8fba97SJames Feist for (const std::pair< 5011c8fba97SJames Feist std::string, 5027e860f15SJohn Edward Broadbent std::vector<std::pair<std::string, 5037e860f15SJohn Edward Broadbent std::vector<std::string>>>>& 5041214b7e7SGunnar Mills object : subtree) 5051c8fba97SJames Feist { 5061c8fba97SJames Feist const std::string& path = object.first; 5071c8fba97SJames Feist const std::vector< 5081214b7e7SGunnar Mills std::pair<std::string, std::vector<std::string>>>& 5091214b7e7SGunnar Mills connectionNames = object.second; 5101c8fba97SJames Feist 511997093ebSGeorge Liu sdbusplus::message::object_path objPath(path); 512997093ebSGeorge Liu if (objPath.filename() != chassisId) 5131c8fba97SJames Feist { 5141c8fba97SJames Feist continue; 5151c8fba97SJames Feist } 5161c8fba97SJames Feist 5171c8fba97SJames Feist if (connectionNames.size() < 1) 5181c8fba97SJames Feist { 5191c8fba97SJames Feist BMCWEB_LOG_ERROR << "Got 0 Connection names"; 5201c8fba97SJames Feist continue; 5211c8fba97SJames Feist } 5221c8fba97SJames Feist 52323a21a1cSEd Tanous const std::vector<std::string>& interfaces3 = 5241c8fba97SJames Feist connectionNames[0].second; 5251c8fba97SJames Feist 5261c8fba97SJames Feist const std::array<const char*, 2> hasIndicatorLed = { 5271c8fba97SJames Feist "xyz.openbmc_project.Inventory.Item.Panel", 5280fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Board.Motherboard"}; 5291c8fba97SJames Feist bool indicatorChassis = false; 5301c8fba97SJames Feist for (const char* interface : hasIndicatorLed) 5311c8fba97SJames Feist { 5327e860f15SJohn Edward Broadbent if (std::find(interfaces3.begin(), 5337e860f15SJohn Edward Broadbent interfaces3.end(), 53423a21a1cSEd Tanous interface) != interfaces3.end()) 5351c8fba97SJames Feist { 5361c8fba97SJames Feist indicatorChassis = true; 5371c8fba97SJames Feist break; 5381c8fba97SJames Feist } 5391c8fba97SJames Feist } 5409f8bfa7cSGunnar Mills if (locationIndicatorActive) 5419f8bfa7cSGunnar Mills { 5429f8bfa7cSGunnar Mills if (indicatorChassis) 5439f8bfa7cSGunnar Mills { 5449f8bfa7cSGunnar Mills setLocationIndicatorActive( 5459f8bfa7cSGunnar Mills asyncResp, *locationIndicatorActive); 5469f8bfa7cSGunnar Mills } 5479f8bfa7cSGunnar Mills else 5489f8bfa7cSGunnar Mills { 5499f8bfa7cSGunnar Mills messages::propertyUnknown( 5509f8bfa7cSGunnar Mills asyncResp->res, "LocationIndicatorActive"); 5519f8bfa7cSGunnar Mills } 5529f8bfa7cSGunnar Mills } 5539f8bfa7cSGunnar Mills if (indicatorLed) 5549f8bfa7cSGunnar Mills { 5551c8fba97SJames Feist if (indicatorChassis) 5561c8fba97SJames Feist { 557f23b7296SEd Tanous setIndicatorLedState(asyncResp, *indicatorLed); 5581c8fba97SJames Feist } 5591c8fba97SJames Feist else 5601c8fba97SJames Feist { 5611c8fba97SJames Feist messages::propertyUnknown(asyncResp->res, 5621c8fba97SJames Feist "IndicatorLED"); 5631c8fba97SJames Feist } 5641c8fba97SJames Feist } 5651c8fba97SJames Feist return; 5661c8fba97SJames Feist } 5671c8fba97SJames Feist 5681c8fba97SJames Feist messages::resourceNotFound( 5699f8bfa7cSGunnar Mills asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId); 5701c8fba97SJames Feist }, 5711c8fba97SJames Feist "xyz.openbmc_project.ObjectMapper", 5721c8fba97SJames Feist "/xyz/openbmc_project/object_mapper", 5731c8fba97SJames Feist "xyz.openbmc_project.ObjectMapper", "GetSubTree", 5741c8fba97SJames Feist "/xyz/openbmc_project/inventory", 0, interfaces); 5757e860f15SJohn Edward Broadbent }); 5761c8fba97SJames Feist } 577dd99e04bSP.K. Lee 5788d1b46d7Szhanghch05 inline void 5798d1b46d7Szhanghch05 doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 580dd99e04bSP.K. Lee { 581c3b3c92aSVijay Khemka const char* busName = "xyz.openbmc_project.ObjectMapper"; 582c3b3c92aSVijay Khemka const char* path = "/xyz/openbmc_project/object_mapper"; 583c3b3c92aSVijay Khemka const char* interface = "xyz.openbmc_project.ObjectMapper"; 584c3b3c92aSVijay Khemka const char* method = "GetSubTreePaths"; 585c3b3c92aSVijay Khemka 586c3b3c92aSVijay Khemka const std::array<const char*, 1> interfaces = { 587c3b3c92aSVijay Khemka "xyz.openbmc_project.State.Chassis"}; 588c3b3c92aSVijay Khemka 589c3b3c92aSVijay Khemka // Use mapper to get subtree paths. 590c3b3c92aSVijay Khemka crow::connections::systemBus->async_method_call( 591c3b3c92aSVijay Khemka [asyncResp](const boost::system::error_code ec, 592c3b3c92aSVijay Khemka const std::vector<std::string>& chassisList) { 593c3b3c92aSVijay Khemka if (ec) 594c3b3c92aSVijay Khemka { 595c3b3c92aSVijay Khemka BMCWEB_LOG_DEBUG << "[mapper] Bad D-Bus request error: " << ec; 596c3b3c92aSVijay Khemka messages::internalError(asyncResp->res); 597c3b3c92aSVijay Khemka return; 598c3b3c92aSVijay Khemka } 599c3b3c92aSVijay Khemka 600dd99e04bSP.K. Lee const char* processName = "xyz.openbmc_project.State.Chassis"; 601dd99e04bSP.K. Lee const char* interfaceName = "xyz.openbmc_project.State.Chassis"; 602dd99e04bSP.K. Lee const char* destProperty = "RequestedPowerTransition"; 603dd99e04bSP.K. Lee const std::string propertyValue = 604dd99e04bSP.K. Lee "xyz.openbmc_project.State.Chassis.Transition.PowerCycle"; 605c3b3c92aSVijay Khemka std::string objectPath = 606c3b3c92aSVijay Khemka "/xyz/openbmc_project/state/chassis_system0"; 607c3b3c92aSVijay Khemka 608c3b3c92aSVijay Khemka /* Look for system reset chassis path */ 609c3b3c92aSVijay Khemka if ((std::find(chassisList.begin(), chassisList.end(), 610c3b3c92aSVijay Khemka objectPath)) == chassisList.end()) 611c3b3c92aSVijay Khemka { 612c3b3c92aSVijay Khemka /* We prefer to reset the full chassis_system, but if it doesn't 613c3b3c92aSVijay Khemka * exist on some platforms, fall back to a host-only power reset 614c3b3c92aSVijay Khemka */ 615c3b3c92aSVijay Khemka objectPath = "/xyz/openbmc_project/state/chassis0"; 616c3b3c92aSVijay Khemka } 617dd99e04bSP.K. Lee 618dd99e04bSP.K. Lee crow::connections::systemBus->async_method_call( 619dd99e04bSP.K. Lee [asyncResp](const boost::system::error_code ec) { 620dd99e04bSP.K. Lee // Use "Set" method to set the property value. 621dd99e04bSP.K. Lee if (ec) 622dd99e04bSP.K. Lee { 623c3b3c92aSVijay Khemka BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " 624c3b3c92aSVijay Khemka << ec; 625dd99e04bSP.K. Lee messages::internalError(asyncResp->res); 626dd99e04bSP.K. Lee return; 627dd99e04bSP.K. Lee } 628dd99e04bSP.K. Lee 629dd99e04bSP.K. Lee messages::success(asyncResp->res); 630dd99e04bSP.K. Lee }, 631c3b3c92aSVijay Khemka processName, objectPath, "org.freedesktop.DBus.Properties", 632c3b3c92aSVijay Khemka "Set", interfaceName, destProperty, 633168e20c1SEd Tanous dbus::utility::DbusVariantType{propertyValue}); 634c3b3c92aSVijay Khemka }, 635c3b3c92aSVijay Khemka busName, path, interface, method, "/", 0, interfaces); 636dd99e04bSP.K. Lee } 637dd99e04bSP.K. Lee 638dd99e04bSP.K. Lee /** 639dd99e04bSP.K. Lee * ChassisResetAction class supports the POST method for the Reset 640dd99e04bSP.K. Lee * action. 641dd99e04bSP.K. Lee * Function handles POST method request. 642dd99e04bSP.K. Lee * Analyzes POST body before sending Reset request data to D-Bus. 643dd99e04bSP.K. Lee */ 6447e860f15SJohn Edward Broadbent 6457e860f15SJohn Edward Broadbent inline void requestRoutesChassisResetAction(App& app) 646dd99e04bSP.K. Lee { 6477e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/") 648ed398213SEd Tanous .privileges(redfish::privileges::postChassis) 6497e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)( 6507e860f15SJohn Edward Broadbent [](const crow::Request& req, 6517e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6527e860f15SJohn Edward Broadbent const std::string&) { 653dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Post Chassis Reset."; 654dd99e04bSP.K. Lee 655dd99e04bSP.K. Lee std::string resetType; 656dd99e04bSP.K. Lee 6577e860f15SJohn Edward Broadbent if (!json_util::readJson(req, asyncResp->res, "ResetType", 6587e860f15SJohn Edward Broadbent resetType)) 659dd99e04bSP.K. Lee { 660dd99e04bSP.K. Lee return; 661dd99e04bSP.K. Lee } 662dd99e04bSP.K. Lee 663dd99e04bSP.K. Lee if (resetType != "PowerCycle") 664dd99e04bSP.K. Lee { 665dd99e04bSP.K. Lee BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: " 666dd99e04bSP.K. Lee << resetType; 6677e860f15SJohn Edward Broadbent messages::actionParameterNotSupported( 6687e860f15SJohn Edward Broadbent asyncResp->res, resetType, "ResetType"); 669dd99e04bSP.K. Lee 670dd99e04bSP.K. Lee return; 671dd99e04bSP.K. Lee } 672dd99e04bSP.K. Lee doChassisPowerCycle(asyncResp); 6737e860f15SJohn Edward Broadbent }); 674dd99e04bSP.K. Lee } 6751cb1a9e6SAppaRao Puli 6761cb1a9e6SAppaRao Puli /** 6771cb1a9e6SAppaRao Puli * ChassisResetActionInfo derived class for delivering Chassis 6781cb1a9e6SAppaRao Puli * ResetType AllowableValues using ResetInfo schema. 6791cb1a9e6SAppaRao Puli */ 6807e860f15SJohn Edward Broadbent inline void requestRoutesChassisResetActionInfo(App& app) 6811cb1a9e6SAppaRao Puli { 6827e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/") 683ed398213SEd Tanous .privileges(redfish::privileges::getActionInfo) 6847e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 6857e860f15SJohn Edward Broadbent [](const crow::Request&, 6867e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6877e860f15SJohn Edward Broadbent const std::string& chassisId) 6881cb1a9e6SAppaRao Puli 6891cb1a9e6SAppaRao Puli { 6908d1b46d7Szhanghch05 asyncResp->res.jsonValue = { 6918d1b46d7Szhanghch05 {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"}, 6928d1b46d7Szhanghch05 {"@odata.id", 6938d1b46d7Szhanghch05 "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo"}, 6941cb1a9e6SAppaRao Puli {"Name", "Reset Action Info"}, 6951cb1a9e6SAppaRao Puli {"Id", "ResetActionInfo"}, 6961cb1a9e6SAppaRao Puli {"Parameters", 6971cb1a9e6SAppaRao Puli {{{"Name", "ResetType"}, 6981cb1a9e6SAppaRao Puli {"Required", true}, 6991cb1a9e6SAppaRao Puli {"DataType", "String"}, 7001cb1a9e6SAppaRao Puli {"AllowableValues", {"PowerCycle"}}}}}}; 7017e860f15SJohn Edward Broadbent }); 7021cb1a9e6SAppaRao Puli } 7031cb1a9e6SAppaRao Puli 704e37f8451SRapkiewicz, Pawel } // namespace redfish 705