1452de22eSShawn McCarney /**
2452de22eSShawn McCarney  * Copyright © 2024 IBM Corporation
3452de22eSShawn McCarney  *
4452de22eSShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
5452de22eSShawn McCarney  * you may not use this file except in compliance with the License.
6452de22eSShawn McCarney  * You may obtain a copy of the License at
7452de22eSShawn McCarney  *
8452de22eSShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
9452de22eSShawn McCarney  *
10452de22eSShawn McCarney  * Unless required by applicable law or agreed to in writing, software
11452de22eSShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
12452de22eSShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13452de22eSShawn McCarney  * See the License for the specific language governing permissions and
14452de22eSShawn McCarney  * limitations under the License.
15452de22eSShawn McCarney  */
16452de22eSShawn McCarney 
17452de22eSShawn McCarney #include "device_finder.hpp"
18452de22eSShawn McCarney 
19452de22eSShawn McCarney #include <phosphor-logging/lg2.hpp>
20452de22eSShawn McCarney 
21452de22eSShawn McCarney #include <exception>
22452de22eSShawn McCarney #include <format>
23452de22eSShawn McCarney #include <stdexcept>
24452de22eSShawn McCarney #include <utility>
25452de22eSShawn McCarney #include <variant>
26452de22eSShawn McCarney #include <vector>
27452de22eSShawn McCarney 
28452de22eSShawn McCarney namespace phosphor::power::sequencer
29452de22eSShawn McCarney {
30452de22eSShawn McCarney 
31452de22eSShawn McCarney const std::string deviceInterfacesService = "xyz.openbmc_project.EntityManager";
32452de22eSShawn McCarney 
33452de22eSShawn McCarney const std::vector<std::string> deviceInterfaces{
34452de22eSShawn McCarney     "xyz.openbmc_project.Configuration.UCD90160",
35452de22eSShawn McCarney     "xyz.openbmc_project.Configuration.UCD90320"};
36452de22eSShawn McCarney 
37452de22eSShawn McCarney const std::string typeProperty = "Type";
38452de22eSShawn McCarney const std::string nameProperty = "Name";
39452de22eSShawn McCarney const std::string busProperty = "Bus";
40452de22eSShawn McCarney const std::string addressProperty = "Address";
41452de22eSShawn McCarney 
DeviceFinder(sdbusplus::bus_t & bus,Callback callback)42452de22eSShawn McCarney DeviceFinder::DeviceFinder(sdbusplus::bus_t& bus, Callback callback) :
43*1838dbf9SShawn McCarney     callback{std::move(callback)}
44*1838dbf9SShawn McCarney {
45*1838dbf9SShawn McCarney     interfacesFinder = std::make_unique<DBusInterfacesFinder>(
46452de22eSShawn McCarney         bus, deviceInterfacesService, deviceInterfaces,
47*1838dbf9SShawn McCarney         std::bind_front(&DeviceFinder::interfaceFoundCallback, this));
48*1838dbf9SShawn McCarney }
49452de22eSShawn McCarney 
interfaceFoundCallback(const std::string & path,const std::string & interface,const DbusPropertyMap & properties)50452de22eSShawn McCarney void DeviceFinder::interfaceFoundCallback(
51452de22eSShawn McCarney     [[maybe_unused]] const std::string& path, const std::string& interface,
52452de22eSShawn McCarney     const DbusPropertyMap& properties)
53452de22eSShawn McCarney {
54452de22eSShawn McCarney     try
55452de22eSShawn McCarney     {
56452de22eSShawn McCarney         DeviceProperties device{};
57452de22eSShawn McCarney 
58452de22eSShawn McCarney         auto value = getPropertyValue(properties, typeProperty);
59452de22eSShawn McCarney         device.type = std::get<std::string>(value);
60452de22eSShawn McCarney 
61452de22eSShawn McCarney         value = getPropertyValue(properties, nameProperty);
62452de22eSShawn McCarney         device.name = std::get<std::string>(value);
63452de22eSShawn McCarney 
64452de22eSShawn McCarney         value = getPropertyValue(properties, busProperty);
65452de22eSShawn McCarney         device.bus = static_cast<uint8_t>(std::get<uint64_t>(value));
66452de22eSShawn McCarney 
67452de22eSShawn McCarney         value = getPropertyValue(properties, addressProperty);
68452de22eSShawn McCarney         device.address = static_cast<uint16_t>(std::get<uint64_t>(value));
69452de22eSShawn McCarney 
70452de22eSShawn McCarney         callback(device);
71452de22eSShawn McCarney     }
72452de22eSShawn McCarney     catch (const std::exception& e)
73452de22eSShawn McCarney     {
74452de22eSShawn McCarney         lg2::error(
75452de22eSShawn McCarney             "Unable to obtain properties of interface {INTERFACE}: {ERROR}",
76452de22eSShawn McCarney             "INTERFACE", interface, "ERROR", e);
77452de22eSShawn McCarney     }
78452de22eSShawn McCarney }
79452de22eSShawn McCarney 
80452de22eSShawn McCarney const DbusVariant&
getPropertyValue(const DbusPropertyMap & properties,const std::string & propertyName)81452de22eSShawn McCarney     DeviceFinder::getPropertyValue(const DbusPropertyMap& properties,
82452de22eSShawn McCarney                                    const std::string& propertyName)
83452de22eSShawn McCarney {
84452de22eSShawn McCarney     auto it = properties.find(propertyName);
85452de22eSShawn McCarney     if (it == properties.end())
86452de22eSShawn McCarney     {
87452de22eSShawn McCarney         throw std::runtime_error{
88452de22eSShawn McCarney             std::format("{} property not found", propertyName)};
89452de22eSShawn McCarney     }
90452de22eSShawn McCarney     return it->second;
91452de22eSShawn McCarney }
92452de22eSShawn McCarney 
93452de22eSShawn McCarney } // namespace phosphor::power::sequencer
94