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 { 45 interfacesFinder = std::make_unique<DBusInterfacesFinder>( 46 bus, deviceInterfacesService, deviceInterfaces, 47 std::bind_front(&DeviceFinder::interfaceFoundCallback, this)); 48 } 49 50 void DeviceFinder::interfaceFoundCallback( 51 [[maybe_unused]] const std::string& path, const std::string& interface, 52 const DbusPropertyMap& properties) 53 { 54 try 55 { 56 DeviceProperties device{}; 57 58 auto value = getPropertyValue(properties, typeProperty); 59 device.type = std::get<std::string>(value); 60 61 value = getPropertyValue(properties, nameProperty); 62 device.name = std::get<std::string>(value); 63 64 value = getPropertyValue(properties, busProperty); 65 device.bus = static_cast<uint8_t>(std::get<uint64_t>(value)); 66 67 value = getPropertyValue(properties, addressProperty); 68 device.address = static_cast<uint16_t>(std::get<uint64_t>(value)); 69 70 callback(device); 71 } 72 catch (const std::exception& e) 73 { 74 lg2::error( 75 "Unable to obtain properties of interface {INTERFACE}: {ERROR}", 76 "INTERFACE", interface, "ERROR", e); 77 } 78 } 79 80 const DbusVariant& 81 DeviceFinder::getPropertyValue(const DbusPropertyMap& properties, 82 const std::string& propertyName) 83 { 84 auto it = properties.find(propertyName); 85 if (it == properties.end()) 86 { 87 throw std::runtime_error{ 88 std::format("{} property not found", propertyName)}; 89 } 90 return it->second; 91 } 92 93 } // namespace phosphor::power::sequencer 94