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