1 #pragma once
2 
3 #include <fcntl.h>
4 #include <fmt/format.h>
5 #include <unistd.h>
6 
7 #include <phosphor-logging/elog-errors.hpp>
8 #include <phosphor-logging/elog.hpp>
9 #include <phosphor-logging/log.hpp>
10 #include <sdbusplus/bus.hpp>
11 #include <xyz/openbmc_project/Common/error.hpp>
12 
13 using namespace phosphor::logging;
14 using InternalFailure =
15     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
16 
17 namespace phosphor
18 {
19 namespace fan
20 {
21 namespace util
22 {
23 
24 constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
25 constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
26 constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
27 
28 constexpr auto INVENTORY_PATH = "/xyz/openbmc_project/inventory";
29 constexpr auto INVENTORY_INTF = "xyz.openbmc_project.Inventory.Manager";
30 constexpr auto INVENTORY_SVC = "xyz.openbmc_project.Inventory.Manager";
31 
32 constexpr auto OPERATIONAL_STATUS_INTF =
33     "xyz.openbmc_project.State.Decorator.OperationalStatus";
34 constexpr auto FUNCTIONAL_PROPERTY = "Functional";
35 
36 constexpr auto INV_ITEM_IFACE = "xyz.openbmc_project.Inventory.Item";
37 constexpr auto FAN_SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value";
38 
39 class FileDescriptor
40 {
41   public:
42     FileDescriptor() = delete;
43     FileDescriptor(const FileDescriptor&) = delete;
44     FileDescriptor(FileDescriptor&&) = default;
45     FileDescriptor& operator=(const FileDescriptor&) = delete;
46     FileDescriptor& operator=(FileDescriptor&&) = default;
47 
48     explicit FileDescriptor(int fd) : fd(fd) {}
49 
50     ~FileDescriptor()
51     {
52         if (fd != -1)
53         {
54             close(fd);
55         }
56     }
57 
58     int operator()()
59     {
60         return fd;
61     }
62 
63     void open(const std::string& pathname, int flags)
64     {
65         fd = ::open(pathname.c_str(), flags);
66         if (-1 == fd)
67         {
68             log<level::ERR>(
69                 fmt::format("Failed to open file device path {}", pathname)
70                     .c_str());
71             elog<InternalFailure>();
72         }
73     }
74 
75     bool is_open()
76     {
77         return fd != -1;
78     }
79 
80   private:
81     int fd = -1;
82 };
83 
84 /**
85  * @brief Get the object map for creating or updating an object property
86  *
87  * @param[in] path - The dbus object path name
88  * @param[in] intf - The dbus interface
89  * @param[in] prop - The dbus property
90  * @param[in] value - The property value
91  *
92  * @return - The full object path containing the property value
93  */
94 template <typename T>
95 auto getObjMap(const std::string& path, const std::string& intf,
96                const std::string& prop, const T& value)
97 {
98     using Property = std::string;
99     using Value = std::variant<T>;
100     using PropertyMap = std::map<Property, Value>;
101 
102     using Interface = std::string;
103     using InterfaceMap = std::map<Interface, PropertyMap>;
104 
105     using Object = sdbusplus::message::object_path;
106     using ObjectMap = std::map<Object, InterfaceMap>;
107 
108     ObjectMap objectMap;
109     InterfaceMap interfaceMap;
110     PropertyMap propertyMap;
111 
112     propertyMap.emplace(prop, value);
113     interfaceMap.emplace(intf, std::move(propertyMap));
114     objectMap.emplace(path, std::move(interfaceMap));
115 
116     return objectMap;
117 }
118 
119 } // namespace util
120 } // namespace fan
121 } // namespace phosphor
122