blob: e580481cce51ae8b66951c7191b94172845e39f5 [file] [log] [blame]
#pragma once
#include "events.hpp"
#include "functor.hpp"
#include "interface_ops.hpp"
#include "serialize.hpp"
#include "types.hpp"
#ifdef CREATE_ASSOCIATIONS
#include "association_manager.hpp"
#endif
#include <sdbusplus/server.hpp>
#include <xyz/openbmc_project/Inventory/Manager/server.hpp>
#include <any>
#include <map>
#include <memory>
#include <string>
#include <vector>
namespace sdbusplus
{
namespace bus
{
class bus;
}
} // namespace sdbusplus
namespace phosphor
{
namespace inventory
{
namespace manager
{
template <typename T>
using ServerObject = T;
using ManagerIface =
sdbusplus::xyz::openbmc_project::Inventory::server::Manager;
/** @class Manager
* @brief OpenBMC inventory manager implementation.
*
* A concrete implementation for the xyz.openbmc_project.Inventory.Manager
* DBus API.
*/
class Manager final : public ServerObject<ManagerIface>
{
public:
Manager() = delete;
Manager(const Manager&) = delete;
Manager& operator=(const Manager&) = delete;
Manager(Manager&&) = default;
Manager& operator=(Manager&&) = default;
~Manager() = default;
/** @brief Construct an inventory manager.
*
* @param[in] bus - An sdbusplus bus connection.
* @param[in] root - The DBus path on which to implement
* an inventory manager.
*/
Manager(sdbusplus::bus_t&&, const char*);
using EventInfo =
std::tuple<std::vector<EventBasePtr>, std::vector<Action>>;
/** @brief Start processing DBus messages.
*
* @param[in] busname - The DBus busname to own.
*/
void run(const char*);
/** @brief Provided for testing only. */
void shutdown() noexcept;
/** @brief sd_bus Notify method implementation callback. */
void
notify(std::map<sdbusplus::message::object_path, Object> objs) override;
/** @brief Event processing entry point. */
void handleEvent(sdbusplus::message_t&, const Event& event,
const EventInfo& info);
/** @brief Drop one or more objects from DBus. */
void destroyObjects(const std::vector<const char*>& paths);
/** @brief Add objects to DBus. */
void createObjects(
const std::map<sdbusplus::message::object_path, Object>& objs);
/** @brief Add or update objects on DBus. */
void updateObjects(
const std::map<sdbusplus::message::object_path, Object>& objs,
bool restoreFromCache = false);
/** @brief Restore persistent inventory items */
void restore();
/** @brief Invoke an sdbusplus server binding method.
*
* Invoke the requested method with a reference to the requested
* sdbusplus server binding interface as a parameter.
*
* @tparam T - The sdbusplus server binding interface type.
* @tparam U - The type of the sdbusplus server binding member.
* @tparam Args - Argument types of the binding member.
*
* @param[in] path - The DBus path on which the method should
* be invoked.
* @param[in] interface - The DBus interface hosting the method.
* @param[in] member - Pointer to sdbusplus server binding member.
* @param[in] args - Arguments to forward to the binding member.
*
* @returns - The return/value type of the binding method being
* called.
*/
template <typename T, typename U, typename... Args>
decltype(auto) invokeMethod(const char* path, const char* interface,
U&& member, Args&&... args)
{
auto& iface = getInterface<T>(path, interface);
return (iface.*member)(std::forward<Args>(args)...);
}
using SigArgs = std::vector<std::unique_ptr<
std::tuple<Manager*, const DbusSignal*, const EventInfo*>>>;
using SigArg = SigArgs::value_type::element_type;
private:
using InterfaceComposite = std::map<std::string, std::any>;
using ObjectReferences = std::map<std::string, InterfaceComposite>;
using Events = std::vector<EventInfo>;
// The int instantiations are safe since the signature of these
// functions don't change from one instantiation to the next.
using Makers =
std::map<std::string, std::tuple<MakeInterfaceType, AssignInterfaceType,
SerializeInterfaceType<SerialOps>,
DeserializeInterfaceType<SerialOps>
#ifdef CREATE_ASSOCIATIONS
,
GetPropertyValueType
#endif
>>;
/** @brief Provides weak references to interface holders.
*
* Common code for all types for the templated getInterface
* methods.
*
* @param[in] path - The DBus path for which the interface
* holder instance should be provided.
* @param[in] interface - The DBus interface for which the
* holder instance should be provided.
*
* @returns A weak reference to the holder instance.
*/
const std::any& getInterfaceHolder(const char*, const char*) const;
std::any& getInterfaceHolder(const char*, const char*);
/** @brief Provides weak references to interface holders.
*
* @tparam T - The sdbusplus server binding interface type.
*
* @param[in] path - The DBus path for which the interface
* should be provided.
* @param[in] interface - The DBus interface to obtain.
*
* @returns A weak reference to the interface holder.
*/
template <typename T>
auto& getInterface(const char* path, const char* interface)
{
auto& holder = getInterfaceHolder(path, interface);
return *std::any_cast<std::shared_ptr<T>&>(holder);
}
template <typename T>
auto& getInterface(const char* path, const char* interface) const
{
auto& holder = getInterfaceHolder(path, interface);
return *std::any_cast<T>(holder);
}
/** @brief Add or update interfaces on DBus. */
void updateInterfaces(const sdbusplus::message::object_path& path,
const Object& interfaces,
ObjectReferences::iterator pos, bool emitSignals,
bool restoreFromCache);
/** @brief Path prefix applied to any relative paths. */
const char* _root;
/** @brief A container of sdbusplus server interface references. */
ObjectReferences _refs;
/** @brief A container contexts for signal callbacks. */
SigArgs _sigargs;
/** @brief A container of sdbusplus signal matches. */
std::vector<sdbusplus::bus::match_t> _matches;
/** @brief Persistent sdbusplus DBus bus connection. */
sdbusplus::bus_t _bus;
/** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */
sdbusplus::server::manager_t _manager;
/** @brief A container of pimgen generated events and responses. */
static const Events _events;
/** @brief A container of pimgen generated factory methods. */
static const Makers _makers;
/** @brief Handles creating mapper associations for inventory objects */
#ifdef CREATE_ASSOCIATIONS
associations::Manager _associations;
#endif
/** @brief Manager status indicator */
volatile enum class ManagerStatus { STARTING, RUNNING, STOPPING } _status;
};
} // namespace manager
} // namespace inventory
} // namespace phosphor
// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4