pseq: Create class for finding devices
Create class for finding power sequencer devices in the system.
Tested:
* See test plan at
https://gist.github.com/smccarney/115a90a26a04e28c226d4e86eaf84cbf
Change-Id: I024eb6ccf82ea30c08c558194c19afcba8dcf5a2
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/phosphor-power-sequencer/src/device_finder.cpp b/phosphor-power-sequencer/src/device_finder.cpp
new file mode 100644
index 0000000..65d3651
--- /dev/null
+++ b/phosphor-power-sequencer/src/device_finder.cpp
@@ -0,0 +1,92 @@
+/**
+ * Copyright © 2024 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "device_finder.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <exception>
+#include <format>
+#include <stdexcept>
+#include <utility>
+#include <variant>
+#include <vector>
+
+namespace phosphor::power::sequencer
+{
+
+const std::string deviceInterfacesService = "xyz.openbmc_project.EntityManager";
+
+const std::vector<std::string> deviceInterfaces{
+ "xyz.openbmc_project.Configuration.UCD90160",
+ "xyz.openbmc_project.Configuration.UCD90320"};
+
+const std::string typeProperty = "Type";
+const std::string nameProperty = "Name";
+const std::string busProperty = "Bus";
+const std::string addressProperty = "Address";
+
+DeviceFinder::DeviceFinder(sdbusplus::bus_t& bus, Callback callback) :
+ callback{std::move(callback)},
+ interfacesFinder{
+ bus, deviceInterfacesService, deviceInterfaces,
+ std::bind_front(&DeviceFinder::interfaceFoundCallback, this)}
+{}
+
+void DeviceFinder::interfaceFoundCallback(
+ [[maybe_unused]] const std::string& path, const std::string& interface,
+ const DbusPropertyMap& properties)
+{
+ try
+ {
+ DeviceProperties device{};
+
+ auto value = getPropertyValue(properties, typeProperty);
+ device.type = std::get<std::string>(value);
+
+ value = getPropertyValue(properties, nameProperty);
+ device.name = std::get<std::string>(value);
+
+ value = getPropertyValue(properties, busProperty);
+ device.bus = static_cast<uint8_t>(std::get<uint64_t>(value));
+
+ value = getPropertyValue(properties, addressProperty);
+ device.address = static_cast<uint16_t>(std::get<uint64_t>(value));
+
+ callback(device);
+ }
+ catch (const std::exception& e)
+ {
+ lg2::error(
+ "Unable to obtain properties of interface {INTERFACE}: {ERROR}",
+ "INTERFACE", interface, "ERROR", e);
+ }
+}
+
+const DbusVariant&
+ DeviceFinder::getPropertyValue(const DbusPropertyMap& properties,
+ const std::string& propertyName)
+{
+ auto it = properties.find(propertyName);
+ if (it == properties.end())
+ {
+ throw std::runtime_error{
+ std::format("{} property not found", propertyName)};
+ }
+ return it->second;
+}
+
+} // namespace phosphor::power::sequencer