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