1 /** 2 * Copyright © 2024 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "device_finder.hpp" 18 19 #include <phosphor-logging/lg2.hpp> 20 21 #include <exception> 22 #include <format> 23 #include <stdexcept> 24 #include <utility> 25 #include <variant> 26 #include <vector> 27 28 namespace phosphor::power::sequencer 29 { 30 31 const std::string deviceInterfacesService = "xyz.openbmc_project.EntityManager"; 32 33 const std::vector<std::string> deviceInterfaces{ 34 "xyz.openbmc_project.Configuration.UCD90160", 35 "xyz.openbmc_project.Configuration.UCD90320"}; 36 37 const std::string typeProperty = "Type"; 38 const std::string nameProperty = "Name"; 39 const std::string busProperty = "Bus"; 40 const std::string addressProperty = "Address"; 41 42 DeviceFinder::DeviceFinder(sdbusplus::bus_t& bus, Callback callback) : 43 callback{std::move(callback)}, 44 interfacesFinder{ 45 bus, deviceInterfacesService, deviceInterfaces, 46 std::bind_front(&DeviceFinder::interfaceFoundCallback, this)} 47 {} 48 49 void DeviceFinder::interfaceFoundCallback( 50 [[maybe_unused]] const std::string& path, const std::string& interface, 51 const DbusPropertyMap& properties) 52 { 53 try 54 { 55 DeviceProperties device{}; 56 57 auto value = getPropertyValue(properties, typeProperty); 58 device.type = std::get<std::string>(value); 59 60 value = getPropertyValue(properties, nameProperty); 61 device.name = std::get<std::string>(value); 62 63 value = getPropertyValue(properties, busProperty); 64 device.bus = static_cast<uint8_t>(std::get<uint64_t>(value)); 65 66 value = getPropertyValue(properties, addressProperty); 67 device.address = static_cast<uint16_t>(std::get<uint64_t>(value)); 68 69 callback(device); 70 } 71 catch (const std::exception& e) 72 { 73 lg2::error( 74 "Unable to obtain properties of interface {INTERFACE}: {ERROR}", 75 "INTERFACE", interface, "ERROR", e); 76 } 77 } 78 79 const DbusVariant& 80 DeviceFinder::getPropertyValue(const DbusPropertyMap& properties, 81 const std::string& propertyName) 82 { 83 auto it = properties.find(propertyName); 84 if (it == properties.end()) 85 { 86 throw std::runtime_error{ 87 std::format("{} property not found", propertyName)}; 88 } 89 return it->second; 90 } 91 92 } // namespace phosphor::power::sequencer 93