1*ac6a4445SGunnar Mills /* 2*ac6a4445SGunnar Mills // Copyright (c) 2018 Intel Corporation 3*ac6a4445SGunnar Mills // 4*ac6a4445SGunnar Mills // Licensed under the Apache License, Version 2.0 (the "License"); 5*ac6a4445SGunnar Mills // you may not use this file except in compliance with the License. 6*ac6a4445SGunnar Mills // You may obtain a copy of the License at 7*ac6a4445SGunnar Mills // 8*ac6a4445SGunnar Mills // http://www.apache.org/licenses/LICENSE-2.0 9*ac6a4445SGunnar Mills // 10*ac6a4445SGunnar Mills // Unless required by applicable law or agreed to in writing, software 11*ac6a4445SGunnar Mills // distributed under the License is distributed on an "AS IS" BASIS, 12*ac6a4445SGunnar Mills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ac6a4445SGunnar Mills // See the License for the specific language governing permissions and 14*ac6a4445SGunnar Mills // limitations under the License. 15*ac6a4445SGunnar Mills */ 16*ac6a4445SGunnar Mills #pragma once 17*ac6a4445SGunnar Mills 18*ac6a4445SGunnar Mills #include "health.hpp" 19*ac6a4445SGunnar Mills 20*ac6a4445SGunnar Mills #include <boost/container/flat_map.hpp> 21*ac6a4445SGunnar Mills #include <node.hpp> 22*ac6a4445SGunnar Mills #include <utils/collection.hpp> 23*ac6a4445SGunnar Mills #include <utils/json_utils.hpp> 24*ac6a4445SGunnar Mills 25*ac6a4445SGunnar Mills namespace redfish 26*ac6a4445SGunnar Mills { 27*ac6a4445SGunnar Mills 28*ac6a4445SGunnar Mills using InterfacesProperties = boost::container::flat_map< 29*ac6a4445SGunnar Mills std::string, 30*ac6a4445SGunnar Mills boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>; 31*ac6a4445SGunnar Mills 32*ac6a4445SGunnar Mills inline void 33*ac6a4445SGunnar Mills getCpuDataByInterface(const std::shared_ptr<AsyncResp>& aResp, 34*ac6a4445SGunnar Mills const InterfacesProperties& cpuInterfacesProperties) 35*ac6a4445SGunnar Mills { 36*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get CPU resources by interface."; 37*ac6a4445SGunnar Mills 38*ac6a4445SGunnar Mills // Added for future purpose. Once present and functional attributes added 39*ac6a4445SGunnar Mills // in busctl call, need to add actual logic to fetch original values. 40*ac6a4445SGunnar Mills bool present = false; 41*ac6a4445SGunnar Mills const bool functional = true; 42*ac6a4445SGunnar Mills auto health = std::make_shared<HealthPopulate>(aResp); 43*ac6a4445SGunnar Mills health->populate(); 44*ac6a4445SGunnar Mills 45*ac6a4445SGunnar Mills for (const auto& interface : cpuInterfacesProperties) 46*ac6a4445SGunnar Mills { 47*ac6a4445SGunnar Mills for (const auto& property : interface.second) 48*ac6a4445SGunnar Mills { 49*ac6a4445SGunnar Mills if (property.first == "CoreCount") 50*ac6a4445SGunnar Mills { 51*ac6a4445SGunnar Mills const uint16_t* coresCount = 52*ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 53*ac6a4445SGunnar Mills if (coresCount == nullptr) 54*ac6a4445SGunnar Mills { 55*ac6a4445SGunnar Mills // Important property not in desired type 56*ac6a4445SGunnar Mills messages::internalError(aResp->res); 57*ac6a4445SGunnar Mills return; 58*ac6a4445SGunnar Mills } 59*ac6a4445SGunnar Mills if (*coresCount == 0) 60*ac6a4445SGunnar Mills { 61*ac6a4445SGunnar Mills // Slot is not populated, set status end return 62*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Absent"; 63*ac6a4445SGunnar Mills // HTTP Code will be set up automatically, just return 64*ac6a4445SGunnar Mills return; 65*ac6a4445SGunnar Mills } 66*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 67*ac6a4445SGunnar Mills present = true; 68*ac6a4445SGunnar Mills aResp->res.jsonValue["TotalCores"] = *coresCount; 69*ac6a4445SGunnar Mills } 70*ac6a4445SGunnar Mills else if (property.first == "Socket") 71*ac6a4445SGunnar Mills { 72*ac6a4445SGunnar Mills const std::string* value = 73*ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 74*ac6a4445SGunnar Mills if (value != nullptr) 75*ac6a4445SGunnar Mills { 76*ac6a4445SGunnar Mills aResp->res.jsonValue["Socket"] = *value; 77*ac6a4445SGunnar Mills } 78*ac6a4445SGunnar Mills } 79*ac6a4445SGunnar Mills else if (property.first == "ThreadCount") 80*ac6a4445SGunnar Mills { 81*ac6a4445SGunnar Mills const int64_t* value = std::get_if<int64_t>(&property.second); 82*ac6a4445SGunnar Mills if (value != nullptr) 83*ac6a4445SGunnar Mills { 84*ac6a4445SGunnar Mills aResp->res.jsonValue["TotalThreads"] = *value; 85*ac6a4445SGunnar Mills } 86*ac6a4445SGunnar Mills } 87*ac6a4445SGunnar Mills else if (property.first == "Family") 88*ac6a4445SGunnar Mills { 89*ac6a4445SGunnar Mills const std::string* value = 90*ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 91*ac6a4445SGunnar Mills if (value != nullptr) 92*ac6a4445SGunnar Mills { 93*ac6a4445SGunnar Mills aResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] = 94*ac6a4445SGunnar Mills *value; 95*ac6a4445SGunnar Mills } 96*ac6a4445SGunnar Mills } 97*ac6a4445SGunnar Mills else if (property.first == "Id") 98*ac6a4445SGunnar Mills { 99*ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 100*ac6a4445SGunnar Mills if (value != nullptr && *value != 0) 101*ac6a4445SGunnar Mills { 102*ac6a4445SGunnar Mills present = true; 103*ac6a4445SGunnar Mills aResp->res 104*ac6a4445SGunnar Mills .jsonValue["ProcessorId"]["IdentificationRegisters"] = 105*ac6a4445SGunnar Mills boost::lexical_cast<std::string>(*value); 106*ac6a4445SGunnar Mills } 107*ac6a4445SGunnar Mills } 108*ac6a4445SGunnar Mills } 109*ac6a4445SGunnar Mills } 110*ac6a4445SGunnar Mills 111*ac6a4445SGunnar Mills if (present == false) 112*ac6a4445SGunnar Mills { 113*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Absent"; 114*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 115*ac6a4445SGunnar Mills } 116*ac6a4445SGunnar Mills else 117*ac6a4445SGunnar Mills { 118*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 119*ac6a4445SGunnar Mills if (functional) 120*ac6a4445SGunnar Mills { 121*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 122*ac6a4445SGunnar Mills } 123*ac6a4445SGunnar Mills else 124*ac6a4445SGunnar Mills { 125*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "Critical"; 126*ac6a4445SGunnar Mills } 127*ac6a4445SGunnar Mills } 128*ac6a4445SGunnar Mills 129*ac6a4445SGunnar Mills return; 130*ac6a4445SGunnar Mills } 131*ac6a4445SGunnar Mills 132*ac6a4445SGunnar Mills inline void getCpuDataByService(std::shared_ptr<AsyncResp> aResp, 133*ac6a4445SGunnar Mills const std::string& cpuId, 134*ac6a4445SGunnar Mills const std::string& service, 135*ac6a4445SGunnar Mills const std::string& objPath) 136*ac6a4445SGunnar Mills { 137*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system cpu resources by service."; 138*ac6a4445SGunnar Mills 139*ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 140*ac6a4445SGunnar Mills [cpuId, service, objPath, aResp{std::move(aResp)}]( 141*ac6a4445SGunnar Mills const boost::system::error_code ec, 142*ac6a4445SGunnar Mills const dbus::utility::ManagedObjectType& dbusData) { 143*ac6a4445SGunnar Mills if (ec) 144*ac6a4445SGunnar Mills { 145*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 146*ac6a4445SGunnar Mills messages::internalError(aResp->res); 147*ac6a4445SGunnar Mills return; 148*ac6a4445SGunnar Mills } 149*ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = cpuId; 150*ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "Processor"; 151*ac6a4445SGunnar Mills aResp->res.jsonValue["ProcessorType"] = "CPU"; 152*ac6a4445SGunnar Mills 153*ac6a4445SGunnar Mills bool slotPresent = false; 154*ac6a4445SGunnar Mills std::string corePath = objPath + "/core"; 155*ac6a4445SGunnar Mills size_t totalCores = 0; 156*ac6a4445SGunnar Mills for (const auto& object : dbusData) 157*ac6a4445SGunnar Mills { 158*ac6a4445SGunnar Mills if (object.first.str == objPath) 159*ac6a4445SGunnar Mills { 160*ac6a4445SGunnar Mills getCpuDataByInterface(aResp, object.second); 161*ac6a4445SGunnar Mills } 162*ac6a4445SGunnar Mills else if (boost::starts_with(object.first.str, corePath)) 163*ac6a4445SGunnar Mills { 164*ac6a4445SGunnar Mills for (const auto& interface : object.second) 165*ac6a4445SGunnar Mills { 166*ac6a4445SGunnar Mills if (interface.first == 167*ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item") 168*ac6a4445SGunnar Mills { 169*ac6a4445SGunnar Mills for (const auto& property : interface.second) 170*ac6a4445SGunnar Mills { 171*ac6a4445SGunnar Mills if (property.first == "Present") 172*ac6a4445SGunnar Mills { 173*ac6a4445SGunnar Mills const bool* present = 174*ac6a4445SGunnar Mills std::get_if<bool>(&property.second); 175*ac6a4445SGunnar Mills if (present != nullptr) 176*ac6a4445SGunnar Mills { 177*ac6a4445SGunnar Mills if (*present == true) 178*ac6a4445SGunnar Mills { 179*ac6a4445SGunnar Mills slotPresent = true; 180*ac6a4445SGunnar Mills totalCores++; 181*ac6a4445SGunnar Mills } 182*ac6a4445SGunnar Mills } 183*ac6a4445SGunnar Mills } 184*ac6a4445SGunnar Mills } 185*ac6a4445SGunnar Mills } 186*ac6a4445SGunnar Mills } 187*ac6a4445SGunnar Mills } 188*ac6a4445SGunnar Mills } 189*ac6a4445SGunnar Mills // In getCpuDataByInterface(), state and health are set 190*ac6a4445SGunnar Mills // based on the present and functional status. If core 191*ac6a4445SGunnar Mills // count is zero, then it has a higher precedence. 192*ac6a4445SGunnar Mills if (slotPresent) 193*ac6a4445SGunnar Mills { 194*ac6a4445SGunnar Mills if (totalCores == 0) 195*ac6a4445SGunnar Mills { 196*ac6a4445SGunnar Mills // Slot is not populated, set status end return 197*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Absent"; 198*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 199*ac6a4445SGunnar Mills } 200*ac6a4445SGunnar Mills aResp->res.jsonValue["TotalCores"] = totalCores; 201*ac6a4445SGunnar Mills } 202*ac6a4445SGunnar Mills return; 203*ac6a4445SGunnar Mills }, 204*ac6a4445SGunnar Mills service, "/xyz/openbmc_project/inventory", 205*ac6a4445SGunnar Mills "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 206*ac6a4445SGunnar Mills } 207*ac6a4445SGunnar Mills 208*ac6a4445SGunnar Mills inline void getCpuAssetData(std::shared_ptr<AsyncResp> aResp, 209*ac6a4445SGunnar Mills const std::string& service, 210*ac6a4445SGunnar Mills const std::string& objPath) 211*ac6a4445SGunnar Mills { 212*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get Cpu Asset Data"; 213*ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 214*ac6a4445SGunnar Mills [objPath, aResp{std::move(aResp)}]( 215*ac6a4445SGunnar Mills const boost::system::error_code ec, 216*ac6a4445SGunnar Mills const boost::container::flat_map< 217*ac6a4445SGunnar Mills std::string, std::variant<std::string, uint32_t, uint16_t, 218*ac6a4445SGunnar Mills bool>>& properties) { 219*ac6a4445SGunnar Mills if (ec) 220*ac6a4445SGunnar Mills { 221*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 222*ac6a4445SGunnar Mills messages::internalError(aResp->res); 223*ac6a4445SGunnar Mills return; 224*ac6a4445SGunnar Mills } 225*ac6a4445SGunnar Mills 226*ac6a4445SGunnar Mills for (const auto& property : properties) 227*ac6a4445SGunnar Mills { 228*ac6a4445SGunnar Mills if (property.first == "SerialNumber") 229*ac6a4445SGunnar Mills { 230*ac6a4445SGunnar Mills const std::string* sn = 231*ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 232*ac6a4445SGunnar Mills if (sn != nullptr && !sn->empty()) 233*ac6a4445SGunnar Mills { 234*ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *sn; 235*ac6a4445SGunnar Mills } 236*ac6a4445SGunnar Mills } 237*ac6a4445SGunnar Mills else if (property.first == "Model") 238*ac6a4445SGunnar Mills { 239*ac6a4445SGunnar Mills const std::string* model = 240*ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 241*ac6a4445SGunnar Mills if (model != nullptr && !model->empty()) 242*ac6a4445SGunnar Mills { 243*ac6a4445SGunnar Mills aResp->res.jsonValue["Model"] = *model; 244*ac6a4445SGunnar Mills } 245*ac6a4445SGunnar Mills } 246*ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 247*ac6a4445SGunnar Mills { 248*ac6a4445SGunnar Mills 249*ac6a4445SGunnar Mills const std::string* mfg = 250*ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 251*ac6a4445SGunnar Mills if (mfg != nullptr) 252*ac6a4445SGunnar Mills { 253*ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *mfg; 254*ac6a4445SGunnar Mills 255*ac6a4445SGunnar Mills // Otherwise would be unexpected. 256*ac6a4445SGunnar Mills if (mfg->find("Intel") != std::string::npos) 257*ac6a4445SGunnar Mills { 258*ac6a4445SGunnar Mills aResp->res.jsonValue["ProcessorArchitecture"] = 259*ac6a4445SGunnar Mills "x86"; 260*ac6a4445SGunnar Mills aResp->res.jsonValue["InstructionSet"] = "x86-64"; 261*ac6a4445SGunnar Mills } 262*ac6a4445SGunnar Mills else if (mfg->find("IBM") != std::string::npos) 263*ac6a4445SGunnar Mills { 264*ac6a4445SGunnar Mills aResp->res.jsonValue["ProcessorArchitecture"] = 265*ac6a4445SGunnar Mills "Power"; 266*ac6a4445SGunnar Mills aResp->res.jsonValue["InstructionSet"] = "PowerISA"; 267*ac6a4445SGunnar Mills } 268*ac6a4445SGunnar Mills } 269*ac6a4445SGunnar Mills } 270*ac6a4445SGunnar Mills } 271*ac6a4445SGunnar Mills }, 272*ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", 273*ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Decorator.Asset"); 274*ac6a4445SGunnar Mills } 275*ac6a4445SGunnar Mills 276*ac6a4445SGunnar Mills inline void getCpuRevisionData(std::shared_ptr<AsyncResp> aResp, 277*ac6a4445SGunnar Mills const std::string& service, 278*ac6a4445SGunnar Mills const std::string& objPath) 279*ac6a4445SGunnar Mills { 280*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get Cpu Revision Data"; 281*ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 282*ac6a4445SGunnar Mills [objPath, aResp{std::move(aResp)}]( 283*ac6a4445SGunnar Mills const boost::system::error_code ec, 284*ac6a4445SGunnar Mills const boost::container::flat_map< 285*ac6a4445SGunnar Mills std::string, std::variant<std::string, uint32_t, uint16_t, 286*ac6a4445SGunnar Mills bool>>& properties) { 287*ac6a4445SGunnar Mills if (ec) 288*ac6a4445SGunnar Mills { 289*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 290*ac6a4445SGunnar Mills messages::internalError(aResp->res); 291*ac6a4445SGunnar Mills return; 292*ac6a4445SGunnar Mills } 293*ac6a4445SGunnar Mills 294*ac6a4445SGunnar Mills for (const auto& property : properties) 295*ac6a4445SGunnar Mills { 296*ac6a4445SGunnar Mills if (property.first == "Version") 297*ac6a4445SGunnar Mills { 298*ac6a4445SGunnar Mills const std::string* ver = 299*ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 300*ac6a4445SGunnar Mills if (ver != nullptr) 301*ac6a4445SGunnar Mills { 302*ac6a4445SGunnar Mills aResp->res.jsonValue["Version"] = *ver; 303*ac6a4445SGunnar Mills } 304*ac6a4445SGunnar Mills break; 305*ac6a4445SGunnar Mills } 306*ac6a4445SGunnar Mills } 307*ac6a4445SGunnar Mills }, 308*ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", 309*ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Decorator.Revision"); 310*ac6a4445SGunnar Mills } 311*ac6a4445SGunnar Mills 312*ac6a4445SGunnar Mills inline void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp, 313*ac6a4445SGunnar Mills const std::string& acclrtrId, 314*ac6a4445SGunnar Mills const std::string& service, 315*ac6a4445SGunnar Mills const std::string& objPath) 316*ac6a4445SGunnar Mills { 317*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 318*ac6a4445SGunnar Mills << "Get available system Accelerator resources by service."; 319*ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 320*ac6a4445SGunnar Mills [acclrtrId, aResp{std::move(aResp)}]( 321*ac6a4445SGunnar Mills const boost::system::error_code ec, 322*ac6a4445SGunnar Mills const boost::container::flat_map< 323*ac6a4445SGunnar Mills std::string, std::variant<std::string, uint32_t, uint16_t, 324*ac6a4445SGunnar Mills bool>>& properties) { 325*ac6a4445SGunnar Mills if (ec) 326*ac6a4445SGunnar Mills { 327*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 328*ac6a4445SGunnar Mills messages::internalError(aResp->res); 329*ac6a4445SGunnar Mills return; 330*ac6a4445SGunnar Mills } 331*ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = acclrtrId; 332*ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "Processor"; 333*ac6a4445SGunnar Mills const bool* accPresent = nullptr; 334*ac6a4445SGunnar Mills const bool* accFunctional = nullptr; 335*ac6a4445SGunnar Mills 336*ac6a4445SGunnar Mills for (const auto& property : properties) 337*ac6a4445SGunnar Mills { 338*ac6a4445SGunnar Mills if (property.first == "Functional") 339*ac6a4445SGunnar Mills { 340*ac6a4445SGunnar Mills accFunctional = std::get_if<bool>(&property.second); 341*ac6a4445SGunnar Mills } 342*ac6a4445SGunnar Mills else if (property.first == "Present") 343*ac6a4445SGunnar Mills { 344*ac6a4445SGunnar Mills accPresent = std::get_if<bool>(&property.second); 345*ac6a4445SGunnar Mills } 346*ac6a4445SGunnar Mills } 347*ac6a4445SGunnar Mills 348*ac6a4445SGunnar Mills std::string state = "Enabled"; 349*ac6a4445SGunnar Mills std::string health = "OK"; 350*ac6a4445SGunnar Mills 351*ac6a4445SGunnar Mills if (accPresent != nullptr && *accPresent == false) 352*ac6a4445SGunnar Mills { 353*ac6a4445SGunnar Mills state = "Absent"; 354*ac6a4445SGunnar Mills } 355*ac6a4445SGunnar Mills 356*ac6a4445SGunnar Mills if ((accFunctional != nullptr) && (*accFunctional == false)) 357*ac6a4445SGunnar Mills { 358*ac6a4445SGunnar Mills if (state == "Enabled") 359*ac6a4445SGunnar Mills { 360*ac6a4445SGunnar Mills health = "Critical"; 361*ac6a4445SGunnar Mills } 362*ac6a4445SGunnar Mills } 363*ac6a4445SGunnar Mills 364*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = state; 365*ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = health; 366*ac6a4445SGunnar Mills aResp->res.jsonValue["ProcessorType"] = "Accelerator"; 367*ac6a4445SGunnar Mills }, 368*ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 369*ac6a4445SGunnar Mills } 370*ac6a4445SGunnar Mills 371*ac6a4445SGunnar Mills inline void getProcessorData(std::shared_ptr<AsyncResp> aResp, 372*ac6a4445SGunnar Mills const std::string& processorId, 373*ac6a4445SGunnar Mills const std::vector<const char*>& inventoryItems) 374*ac6a4445SGunnar Mills { 375*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system processor resources."; 376*ac6a4445SGunnar Mills 377*ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 378*ac6a4445SGunnar Mills [processorId, aResp{std::move(aResp)}]( 379*ac6a4445SGunnar Mills const boost::system::error_code ec, 380*ac6a4445SGunnar Mills const boost::container::flat_map< 381*ac6a4445SGunnar Mills std::string, boost::container::flat_map< 382*ac6a4445SGunnar Mills std::string, std::vector<std::string>>>& 383*ac6a4445SGunnar Mills subtree) { 384*ac6a4445SGunnar Mills if (ec) 385*ac6a4445SGunnar Mills { 386*ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 387*ac6a4445SGunnar Mills messages::internalError(aResp->res); 388*ac6a4445SGunnar Mills return; 389*ac6a4445SGunnar Mills } 390*ac6a4445SGunnar Mills for (const auto& object : subtree) 391*ac6a4445SGunnar Mills { 392*ac6a4445SGunnar Mills if (boost::ends_with(object.first, processorId)) 393*ac6a4445SGunnar Mills { 394*ac6a4445SGunnar Mills for (const auto& service : object.second) 395*ac6a4445SGunnar Mills { 396*ac6a4445SGunnar Mills for (const auto& inventory : service.second) 397*ac6a4445SGunnar Mills { 398*ac6a4445SGunnar Mills if (inventory == "xyz.openbmc_project." 399*ac6a4445SGunnar Mills "Inventory.Decorator.Asset") 400*ac6a4445SGunnar Mills { 401*ac6a4445SGunnar Mills getCpuAssetData(aResp, service.first, 402*ac6a4445SGunnar Mills object.first); 403*ac6a4445SGunnar Mills } 404*ac6a4445SGunnar Mills else if (inventory == 405*ac6a4445SGunnar Mills "xyz.openbmc_project." 406*ac6a4445SGunnar Mills "Inventory.Decorator.Revision") 407*ac6a4445SGunnar Mills { 408*ac6a4445SGunnar Mills getCpuRevisionData(aResp, service.first, 409*ac6a4445SGunnar Mills object.first); 410*ac6a4445SGunnar Mills } 411*ac6a4445SGunnar Mills else if (inventory == "xyz.openbmc_project." 412*ac6a4445SGunnar Mills "Inventory.Item.Cpu") 413*ac6a4445SGunnar Mills { 414*ac6a4445SGunnar Mills getCpuDataByService(aResp, processorId, 415*ac6a4445SGunnar Mills service.first, 416*ac6a4445SGunnar Mills object.first); 417*ac6a4445SGunnar Mills } 418*ac6a4445SGunnar Mills else if (inventory == "xyz.openbmc_project." 419*ac6a4445SGunnar Mills "Inventory.Item.Accelerator") 420*ac6a4445SGunnar Mills { 421*ac6a4445SGunnar Mills getAcceleratorDataByService(aResp, processorId, 422*ac6a4445SGunnar Mills service.first, 423*ac6a4445SGunnar Mills object.first); 424*ac6a4445SGunnar Mills } 425*ac6a4445SGunnar Mills } 426*ac6a4445SGunnar Mills } 427*ac6a4445SGunnar Mills return; 428*ac6a4445SGunnar Mills } 429*ac6a4445SGunnar Mills } 430*ac6a4445SGunnar Mills // Object not found 431*ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Processor", processorId); 432*ac6a4445SGunnar Mills return; 433*ac6a4445SGunnar Mills }, 434*ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 435*ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 436*ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 437*ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, inventoryItems); 438*ac6a4445SGunnar Mills } 439*ac6a4445SGunnar Mills 440*ac6a4445SGunnar Mills class ProcessorCollection : public Node 441*ac6a4445SGunnar Mills { 442*ac6a4445SGunnar Mills public: 443*ac6a4445SGunnar Mills /* 444*ac6a4445SGunnar Mills * Default Constructor 445*ac6a4445SGunnar Mills */ 446*ac6a4445SGunnar Mills ProcessorCollection(App& app) : 447*ac6a4445SGunnar Mills Node(app, "/redfish/v1/Systems/system/Processors/") 448*ac6a4445SGunnar Mills { 449*ac6a4445SGunnar Mills entityPrivileges = { 450*ac6a4445SGunnar Mills {boost::beast::http::verb::get, {{"Login"}}}, 451*ac6a4445SGunnar Mills {boost::beast::http::verb::head, {{"Login"}}}, 452*ac6a4445SGunnar Mills {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 453*ac6a4445SGunnar Mills {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 454*ac6a4445SGunnar Mills {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 455*ac6a4445SGunnar Mills {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 456*ac6a4445SGunnar Mills } 457*ac6a4445SGunnar Mills 458*ac6a4445SGunnar Mills private: 459*ac6a4445SGunnar Mills /** 460*ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 461*ac6a4445SGunnar Mills */ 462*ac6a4445SGunnar Mills void doGet(crow::Response& res, const crow::Request&, 463*ac6a4445SGunnar Mills const std::vector<std::string>&) override 464*ac6a4445SGunnar Mills { 465*ac6a4445SGunnar Mills res.jsonValue["@odata.type"] = 466*ac6a4445SGunnar Mills "#ProcessorCollection.ProcessorCollection"; 467*ac6a4445SGunnar Mills res.jsonValue["Name"] = "Processor Collection"; 468*ac6a4445SGunnar Mills 469*ac6a4445SGunnar Mills res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/"; 470*ac6a4445SGunnar Mills auto asyncResp = std::make_shared<AsyncResp>(res); 471*ac6a4445SGunnar Mills 472*ac6a4445SGunnar Mills collection_util::getResourceList( 473*ac6a4445SGunnar Mills asyncResp, "Processors", 474*ac6a4445SGunnar Mills {"xyz.openbmc_project.Inventory.Item.Cpu", 475*ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Accelerator"}); 476*ac6a4445SGunnar Mills } 477*ac6a4445SGunnar Mills }; 478*ac6a4445SGunnar Mills 479*ac6a4445SGunnar Mills class Processor : public Node 480*ac6a4445SGunnar Mills { 481*ac6a4445SGunnar Mills public: 482*ac6a4445SGunnar Mills /* 483*ac6a4445SGunnar Mills * Default Constructor 484*ac6a4445SGunnar Mills */ 485*ac6a4445SGunnar Mills Processor(App& app) : 486*ac6a4445SGunnar Mills Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string()) 487*ac6a4445SGunnar Mills { 488*ac6a4445SGunnar Mills entityPrivileges = { 489*ac6a4445SGunnar Mills {boost::beast::http::verb::get, {{"Login"}}}, 490*ac6a4445SGunnar Mills {boost::beast::http::verb::head, {{"Login"}}}, 491*ac6a4445SGunnar Mills {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 492*ac6a4445SGunnar Mills {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 493*ac6a4445SGunnar Mills {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 494*ac6a4445SGunnar Mills {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 495*ac6a4445SGunnar Mills } 496*ac6a4445SGunnar Mills 497*ac6a4445SGunnar Mills private: 498*ac6a4445SGunnar Mills /** 499*ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 500*ac6a4445SGunnar Mills */ 501*ac6a4445SGunnar Mills void doGet(crow::Response& res, const crow::Request&, 502*ac6a4445SGunnar Mills const std::vector<std::string>& params) override 503*ac6a4445SGunnar Mills { 504*ac6a4445SGunnar Mills // Check if there is required param, truly entering this shall be 505*ac6a4445SGunnar Mills // impossible 506*ac6a4445SGunnar Mills if (params.size() != 1) 507*ac6a4445SGunnar Mills { 508*ac6a4445SGunnar Mills messages::internalError(res); 509*ac6a4445SGunnar Mills 510*ac6a4445SGunnar Mills res.end(); 511*ac6a4445SGunnar Mills return; 512*ac6a4445SGunnar Mills } 513*ac6a4445SGunnar Mills const std::string& processorId = params[0]; 514*ac6a4445SGunnar Mills res.jsonValue["@odata.type"] = "#Processor.v1_9_0.Processor"; 515*ac6a4445SGunnar Mills res.jsonValue["@odata.id"] = 516*ac6a4445SGunnar Mills "/redfish/v1/Systems/system/Processors/" + processorId; 517*ac6a4445SGunnar Mills 518*ac6a4445SGunnar Mills auto asyncResp = std::make_shared<AsyncResp>(res); 519*ac6a4445SGunnar Mills 520*ac6a4445SGunnar Mills getProcessorData(asyncResp, processorId, 521*ac6a4445SGunnar Mills {"xyz.openbmc_project.Inventory.Item.Cpu", 522*ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Decorator.Asset", 523*ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Accelerator"}); 524*ac6a4445SGunnar Mills } 525*ac6a4445SGunnar Mills }; 526*ac6a4445SGunnar Mills 527*ac6a4445SGunnar Mills } // namespace redfish 528