Create OCC pass-through objects
Create OCC pass-through d-bus objects when corresponding CPU objects are
created in the inventory.
Resolves openbmc/openbmc#1450.
Change-Id: I8da879f51ebef8dcc3d25358def81c5e0dce0617
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/occ_pass_through.hpp b/occ_pass_through.hpp
index 070e371..c9f6566 100644
--- a/occ_pass_through.hpp
+++ b/occ_pass_through.hpp
@@ -1,14 +1,20 @@
#pragma once
#include <string>
+#include <cstring>
+#include <map>
#include <vector>
+#include <experimental/filesystem>
#include <unistd.h>
#include <sdbusplus/bus.hpp>
+#include <functional>
#include <sdbusplus/server/object.hpp>
#include <org/open_power/OCC/PassThrough/server.hpp>
#include "config.h"
#include "file.hpp"
+namespace sdbusRule = sdbusplus::bus::match::rules;
+
namespace open_power
{
namespace occ
@@ -16,20 +22,86 @@
namespace pass_through
{
-/** @brief Make occ pass-through d-bus object pathname
- * @param[in] occ - occ name
- * @returns occ pass-through path
- */
-inline auto object(const std::string& occ)
-{
- return std::string(OCC_PASS_THROUGH_ROOT) +
- '/' +
- occ;
-}
+class PassThrough;
-/** @brief Put occ pass through objects on the bus
+namespace manager
+{
+
+/** @class Manager
+ * @brief Builds and manages OCC pass-through objects
*/
-void run();
+struct Manager
+{
+ public:
+ Manager() = delete;
+ Manager(const Manager&) = delete;
+ Manager& operator=(const Manager&) = delete;
+ Manager(Manager&&) = default;
+ Manager& operator=(Manager&&) = default;
+ ~Manager() = default;
+
+ /** @brief Ctor - Add OCC pass-through objects on the bus. Create
+ * OCC objects when corresponding CPU inventory is created.
+ * @param[in] bus - handle to the bus
+ */
+ Manager(sdbusplus::bus::bus& bus):
+ bus(bus)
+ {
+ for (auto id = 0; id < MAX_CPUS; ++id)
+ {
+ auto path = std::string(CPU_PATH) + std::to_string(id);
+ cpuMatches.emplace_back(
+ bus,
+ sdbusRule::interfacesAdded() +
+ sdbusRule::argNpath(0, path),
+ std::bind(std::mem_fn(&Manager::cpuCreated),
+ this, std::placeholders::_1));
+ }
+ }
+
+ /** @brief Callback that responds to cpu creation in the inventory -
+ * by creating the occ passthrough object.
+ *
+ * @param[in] msg - bus message
+ *
+ * @returns 0 to indicate success
+ */
+ int cpuCreated(sdbusplus::message::message& msg)
+ {
+ namespace fs = std::experimental::filesystem;
+
+ sdbusplus::message::object_path o;
+ msg.read(o);
+ fs::path cpuPath(std::string(std::move(o)));
+ auto cpu = cpuPath.filename();
+
+ auto occPath = fs::path(OCC_PASS_THROUGH_ROOT);
+ std::string name{cpu.c_str()};
+ auto index = name.find(CPU_NAME);
+ name.replace(index, std::strlen(CPU_NAME), OCC_NAME);
+ occPath /= name;
+
+ objects.emplace_back(
+ std::make_unique<PassThrough>(
+ bus,
+ occPath.c_str()));
+
+ return 0;
+ }
+
+ private:
+ /** @brief reference to the bus */
+ sdbusplus::bus::bus& bus;
+
+ /** @brief OCC pass-through objects */
+ std::vector<std::unique_ptr<PassThrough>> objects;
+
+ /** @brief sbdbusplus match objects */
+ std::vector<sdbusplus::bus::match_t> cpuMatches;
+};
+
+} // namespace manager
+
using Iface = sdbusplus::server::object::object<
sdbusplus::org::open_power::OCC::server::PassThrough>;