1 #pragma once
2 
3 #include <chrono>
4 #include <ipmid/types.hpp>
5 #include <optional>
6 #include <sdbusplus/server.hpp>
7 
8 namespace ipmi
9 {
10 
11 using namespace std::literals::chrono_literals;
12 
13 constexpr auto MAPPER_BUS_NAME = "xyz.openbmc_project.ObjectMapper";
14 constexpr auto MAPPER_OBJ = "/xyz/openbmc_project/object_mapper";
15 constexpr auto MAPPER_INTF = "xyz.openbmc_project.ObjectMapper";
16 
17 constexpr auto ROOT = "/";
18 constexpr auto HOST_MATCH = "host0";
19 
20 constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
21 constexpr auto DELETE_INTERFACE = "xyz.openbmc_project.Object.Delete";
22 
23 constexpr auto METHOD_GET = "Get";
24 constexpr auto METHOD_GET_ALL = "GetAll";
25 constexpr auto METHOD_SET = "Set";
26 
27 /* Use a value of 5s which aligns with BT/KCS bridged timeouts, rather
28  * than the default 25s D-Bus timeout. */
29 constexpr std::chrono::microseconds IPMI_DBUS_TIMEOUT = 5s;
30 
31 /** @class ServiceCache
32  *  @brief Caches lookups of service names from the object mapper.
33  *  @details Most ipmi commands need to talk to other dbus daemons to perform
34  *           their intended actions on the BMC. This usually means they will
35  *           first look up the service name providing the interface they
36  *           require. This class reduces the number of such calls by caching
37  *           the lookup for a specific service.
38  */
39 class ServiceCache
40 {
41   public:
42     /** @brief Creates a new service cache for the given interface
43      *         and path.
44      *
45      *  @param[in] intf - The interface used for each lookup
46      *  @param[in] path - The path used for each lookup
47      */
48     ServiceCache(const std::string& intf, const std::string& path);
49     ServiceCache(std::string&& intf, std::string&& path);
50 
51     /** @brief Gets the service name from the cache or does in a
52      *         lookup when invalid.
53      *
54      *  @param[in] bus - The bus associated with and used for looking
55      *                   up the service.
56      */
57     const std::string& getService(sdbusplus::bus::bus& bus);
58 
59     /** @brief Invalidates the current service name */
60     void invalidate();
61 
62     /** @brief A wrapper around sdbusplus bus.new_method_call
63      *
64      *  @param[in] bus - The bus used for calling the method
65      *  @param[in] intf - The interface containing the method
66      *  @param[in] method - The method name
67      *  @return The message containing the method call.
68      */
69     sdbusplus::message::message newMethodCall(sdbusplus::bus::bus& bus,
70                                               const char* intf,
71                                               const char* method);
72 
73     /** @brief Check to see if the current cache is valid
74      *
75      * @param[in] bus - The bus used for the service lookup
76      * @return True if the cache is valid false otherwise.
77      */
78     bool isValid(sdbusplus::bus::bus& bus) const;
79 
80   private:
81     /** @brief DBUS interface provided by the service */
82     const std::string intf;
83     /** @brief DBUS path provided by the service */
84     const std::string path;
85     /** @brief The name of the service if valid */
86     std::optional<std::string> cachedService;
87     /** @brief The name of the bus used in the service lookup */
88     std::optional<std::string> cachedBusName;
89 };
90 
91 /**
92  * @brief Get the DBUS Service name for the input dbus path
93  *
94  * @param[in] bus - DBUS Bus Object
95  * @param[in] intf - DBUS Interface
96  * @param[in] path - DBUS Object Path
97  *
98  */
99 std::string getService(sdbusplus::bus::bus& bus, const std::string& intf,
100                        const std::string& path);
101 
102 /** @brief Gets the dbus object info implementing the given interface
103  *         from the given subtree.
104  *  @param[in] bus - DBUS Bus Object.
105  *  @param[in] interface - Dbus interface.
106  *  @param[in] subtreePath - subtree from where the search should start.
107  *  @param[in] match - identifier for object.
108  *  @return On success returns the object having objectpath and servicename.
109  */
110 DbusObjectInfo getDbusObject(sdbusplus::bus::bus& bus,
111                              const std::string& interface,
112                              const std::string& subtreePath = ROOT,
113                              const std::string& match = {});
114 
115 /** @brief Get the ipObject of first dbus IP object of Non-LinkLocalIPAddress
116  *         type from the given subtree, if not available gets IP object of
117  *         LinkLocalIPAddress type.
118  *  @param[in] bus - DBUS Bus Object.
119  *  @param[in] interface - Dbus interface.
120  *  @param[in] subtreePath - subtree from where the search should start.
121  *  @param[in] match - identifier for object.
122  *  @return On success returns the object having objectpath and servicename.
123  */
124 DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
125                            const std::string& interface,
126                            const std::string& subtreePath,
127                            const std::string& match);
128 
129 /** @brief Gets the value associated with the given object
130  *         and the interface.
131  *  @param[in] bus - DBUS Bus Object.
132  *  @param[in] service - Dbus service name.
133  *  @param[in] objPath - Dbus object path.
134  *  @param[in] interface - Dbus interface.
135  *  @param[in] property - name of the property.
136  *  @return On success returns the value of the property.
137  */
138 Value getDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
139                       const std::string& objPath, const std::string& interface,
140                       const std::string& property,
141                       std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);
142 
143 /** @brief Gets all the properties associated with the given object
144  *         and the interface.
145  *  @param[in] bus - DBUS Bus Object.
146  *  @param[in] service - Dbus service name.
147  *  @param[in] objPath - Dbus object path.
148  *  @param[in] interface - Dbus interface.
149  *  @return On success returns the map of name value pair.
150  */
151 PropertyMap
152     getAllDbusProperties(sdbusplus::bus::bus& bus, const std::string& service,
153                          const std::string& objPath,
154                          const std::string& interface,
155                          std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);
156 
157 /** @brief Gets all managed objects associated with the given object
158  *         path and service.
159  *  @param[in] bus - D-Bus Bus Object.
160  *  @param[in] service - D-Bus service name.
161  *  @param[in] objPath - D-Bus object path.
162  *  @return On success returns the map of name value pair.
163  */
164 ObjectValueTree getManagedObjects(sdbusplus::bus::bus& bus,
165                                   const std::string& service,
166                                   const std::string& objPath);
167 
168 /** @brief Sets the property value of the given object.
169  *  @param[in] bus - DBUS Bus Object.
170  *  @param[in] service - Dbus service name.
171  *  @param[in] objPath - Dbus object path.
172  *  @param[in] interface - Dbus interface.
173  *  @param[in] property - name of the property.
174  *  @param[in] value - value which needs to be set.
175  */
176 void setDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
177                      const std::string& objPath, const std::string& interface,
178                      const std::string& property, const Value& value,
179                      std::chrono::microseconds timeout = IPMI_DBUS_TIMEOUT);
180 
181 /** @brief  Gets all the dbus objects from the given service root
182  *          which matches the object identifier.
183  *  @param[in] bus - DBUS Bus Object.
184  *  @param[in] serviceRoot - Service root path.
185  *  @param[in] interface - Dbus interface.
186  *  @param[in] match - Identifier for a path.
187  *  @returns map of object path and service info.
188  */
189 ObjectTree getAllDbusObjects(sdbusplus::bus::bus& bus,
190                              const std::string& serviceRoot,
191                              const std::string& interface,
192                              const std::string& match = {});
193 
194 /** @brief Deletes all the dbus objects from the given service root
195            which matches the object identifier.
196  *  @param[in] bus - DBUS Bus Object.
197  *  @param[in] serviceRoot - Service root path.
198  *  @param[in] interface - Dbus interface.
199  *  @param[in] match - Identifier for object.
200  */
201 void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
202                           const std::string& serviceRoot,
203                           const std::string& interface,
204                           const std::string& match = {});
205 
206 /** @brief Gets the ancestor objects of the given object
207            which implements the given interface.
208  *  @param[in] bus - Dbus bus object.
209  *  @param[in] path - Child Dbus object path.
210  *  @param[in] interfaces - Dbus interface list.
211  *  @return map of object path and service info.
212  */
213 ObjectTree getAllAncestors(sdbusplus::bus::bus& bus, const std::string& path,
214                            InterfaceList&& interfaces);
215 
216 /** @struct VariantToDoubleVisitor
217  *  @brief Visitor to convert variants to doubles
218  *  @details Performs a static cast on the underlying type
219  */
220 struct VariantToDoubleVisitor
221 {
222     template <typename T>
223     std::enable_if_t<std::is_arithmetic<T>::value, double>
224         operator()(const T& t) const
225     {
226         return static_cast<double>(t);
227     }
228 
229     template <typename T>
230     std::enable_if_t<!std::is_arithmetic<T>::value, double>
231         operator()(const T& t) const
232     {
233         throw std::invalid_argument("Cannot translate type to double");
234     }
235 };
236 
237 namespace method_no_args
238 {
239 
240 /** @brief Calls the Dbus method which waits for response.
241  *  @param[in] bus - DBUS Bus Object.
242  *  @param[in] service - Dbus service name.
243  *  @param[in] objPath - Dbus object path.
244  *  @param[in] interface - Dbus interface.
245  *  @param[in] method - Dbus method.
246  */
247 void callDbusMethod(sdbusplus::bus::bus& bus, const std::string& service,
248                     const std::string& objPath, const std::string& interface,
249                     const std::string& method);
250 
251 } // namespace method_no_args
252 
253 namespace network
254 {
255 
256 constexpr auto ROOT = "/xyz/openbmc_project/network";
257 constexpr auto SERVICE = "xyz.openbmc_project.Network";
258 constexpr auto IP_TYPE = "ipv4";
259 constexpr auto IPV4_PREFIX = "169.254";
260 constexpr auto IPV6_PREFIX = "fe80";
261 constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
262 constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
263 constexpr auto SYSTEMCONFIG_INTERFACE =
264     "xyz.openbmc_project.Network.SystemConfiguration";
265 constexpr auto ETHERNET_INTERFACE =
266     "xyz.openbmc_project.Network.EthernetInterface";
267 constexpr auto IP_CREATE_INTERFACE = "xyz.openbmc_project.Network.IP.Create";
268 constexpr auto VLAN_CREATE_INTERFACE =
269     "xyz.openbmc_project.Network.VLAN.Create";
270 constexpr auto VLAN_INTERFACE = "xyz.openbmc_project.Network.VLAN";
271 
272 /* @brief converts the given subnet into prefix notation.
273  * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
274  * @param[in] mask - Subnet Mask.
275  * @returns prefix.
276  */
277 uint8_t toPrefix(int addressFamily, const std::string& subnetMask);
278 
279 /** @brief Sets the ip on the system.
280  *  @param[in] bus - DBUS Bus Object.
281  *  @param[in] service - Dbus service name.
282  *  @param[in] objPath - Dbus object path.
283  *  @param[in] protocolType - Protocol type
284  *  @param[in] ipaddress - IPaddress.
285  *  @param[in] prefix - Prefix length.
286  */
287 void createIP(sdbusplus::bus::bus& bus, const std::string& service,
288               const std::string& objPath, const std::string& protocolType,
289               const std::string& ipaddress, uint8_t prefix);
290 
291 /** @brief Creates the VLAN on the given interface.
292  *  @param[in] bus - DBUS Bus Object.
293  *  @param[in] service - Dbus service name.
294  *  @param[in] objPath - Dbus object path.
295  *  @param[in] interface - EthernetInterface.
296  *  @param[in] vlanID - Vlan ID.
297  */
298 void createVLAN(sdbusplus::bus::bus& bus, const std::string& service,
299                 const std::string& objPath, const std::string& interface,
300                 uint32_t vlanID);
301 
302 /** @brief Gets the vlan id from the given object path.
303  *  @param[in] path - Dbus object path.
304  */
305 uint32_t getVLAN(const std::string& path);
306 
307 } // namespace network
308 } // namespace ipmi
309