| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 1 | #include <arpa/inet.h> | 
 | 2 | #include <dirent.h> | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 3 | #include <fcntl.h> | 
 | 4 | #include <linux/i2c-dev.h> | 
 | 5 | #include <linux/i2c.h> | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 6 | #include <net/if.h> | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 7 | #include <sys/ioctl.h> | 
 | 8 | #include <sys/types.h> | 
 | 9 | #include <unistd.h> | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 10 |  | 
| Vernon Mauery | 6a98fe7 | 2019-03-11 15:57:48 -0700 | [diff] [blame] | 11 | #include <ipmid/utils.hpp> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 12 | #include <phosphor-logging/elog-errors.hpp> | 
| George Liu | b4b4091 | 2024-07-17 16:14:17 +0800 | [diff] [blame] | 13 | #include <phosphor-logging/lg2.hpp> | 
| William A. Kennington III | 4c00802 | 2018-10-12 17:18:14 -0700 | [diff] [blame] | 14 | #include <sdbusplus/message/types.hpp> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 15 | #include <xyz/openbmc_project/Common/error.hpp> | 
 | 16 |  | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 17 | #include <algorithm> | 
 | 18 | #include <chrono> | 
| Prithvi Pai | c1e7b5c | 2025-09-01 13:13:15 +0530 | [diff] [blame] | 19 | #include <sstream> | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 20 |  | 
| Tom Joseph | be703f7 | 2017-03-09 12:34:35 +0530 | [diff] [blame] | 21 | namespace ipmi | 
 | 22 | { | 
 | 23 |  | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 24 | using namespace phosphor::logging; | 
| Willy Tu | 523e2d1 | 2023-09-05 11:36:48 -0700 | [diff] [blame] | 25 | using namespace sdbusplus::error::xyz::openbmc_project::common; | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 26 |  | 
| Nagaraju Goruganti | 1fe5c83 | 2017-09-21 07:44:17 -0500 | [diff] [blame] | 27 | namespace network | 
 | 28 | { | 
 | 29 |  | 
 | 30 | /** @brief checks if the given ip is Link Local Ip or not. | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 31 |  *  @param[in] ipaddress - IPAddress. | 
 | 32 |  */ | 
| Nagaraju Goruganti | 1fe5c83 | 2017-09-21 07:44:17 -0500 | [diff] [blame] | 33 | bool isLinkLocalIP(const std::string& ipaddress); | 
 | 34 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 35 | } // namespace network | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 36 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 37 | // TODO There may be cases where an interface is implemented by multiple | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 38 | //  objects,to handle such cases we are interested on that object | 
 | 39 | //  which are on interested busname. | 
 | 40 | //  Currently mapper doesn't give the readable busname(gives busid) so we can't | 
 | 41 | //  use busname to find the object,will do later once the support is there. | 
 | 42 |  | 
| Patrick Williams | 69b4c28 | 2025-03-03 11:19:13 -0500 | [diff] [blame] | 43 | DbusObjectInfo getDbusObject( | 
 | 44 |     sdbusplus::bus_t& bus, const std::string& interface, | 
 | 45 |     const std::string& serviceRoot, const std::string& match) | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 46 | { | 
 | 47 |     std::vector<DbusInterface> interfaces; | 
 | 48 |     interfaces.emplace_back(interface); | 
 | 49 |  | 
| George Liu | 50f186c | 2024-02-04 16:51:26 +0800 | [diff] [blame] | 50 |     ObjectTree objectTree = getSubTree(bus, interfaces, serviceRoot); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 51 |     if (objectTree.empty()) | 
 | 52 |     { | 
| George Liu | b4b4091 | 2024-07-17 16:14:17 +0800 | [diff] [blame] | 53 |         lg2::error("No Object has implemented the interface: {INTERFACE}", | 
 | 54 |                    "INTERFACE", interface); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 55 |         elog<InternalFailure>(); | 
 | 56 |     } | 
 | 57 |  | 
 | 58 |     DbusObjectInfo objectInfo; | 
 | 59 |  | 
 | 60 |     // if match is empty then return the first object | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 61 |     if (match == "") | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 62 |     { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 63 |         objectInfo = std::make_pair( | 
 | 64 |             objectTree.begin()->first, | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 65 |             std::move(objectTree.begin()->second.begin()->first)); | 
 | 66 |         return objectInfo; | 
 | 67 |     } | 
 | 68 |  | 
 | 69 |     // else search the match string in the object path | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 70 |     auto found = std::find_if( | 
 | 71 |         objectTree.begin(), objectTree.end(), [&match](const auto& object) { | 
 | 72 |             return (object.first.find(match) != std::string::npos); | 
 | 73 |         }); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 74 |  | 
| Patrick Venture | 2e63352 | 2018-10-13 13:51:06 -0700 | [diff] [blame] | 75 |     if (found == objectTree.end()) | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 76 |     { | 
| George Liu | b4b4091 | 2024-07-17 16:14:17 +0800 | [diff] [blame] | 77 |         lg2::error("Failed to find object which matches: {MATCH}", "MATCH", | 
 | 78 |                    match); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 79 |         elog<InternalFailure>(); | 
| Patrick Venture | 2e63352 | 2018-10-13 13:51:06 -0700 | [diff] [blame] | 80 |         // elog<> throws an exception. | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 81 |     } | 
| Patrick Venture | 2e63352 | 2018-10-13 13:51:06 -0700 | [diff] [blame] | 82 |  | 
 | 83 |     return make_pair(found->first, std::move(found->second.begin()->first)); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 84 | } | 
 | 85 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 86 | Value getDbusProperty(sdbusplus::bus_t& bus, const std::string& service, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 87 |                       const std::string& objPath, const std::string& interface, | 
| Kun Yi | 5dcf41e | 2019-03-05 14:02:51 -0800 | [diff] [blame] | 88 |                       const std::string& property, | 
 | 89 |                       std::chrono::microseconds timeout) | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 90 | { | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 91 |     Value value; | 
 | 92 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 93 |     auto method = bus.new_method_call(service.c_str(), objPath.c_str(), | 
 | 94 |                                       PROP_INTF, METHOD_GET); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 95 |  | 
 | 96 |     method.append(interface, property); | 
 | 97 |  | 
| Kun Yi | 5dcf41e | 2019-03-05 14:02:51 -0800 | [diff] [blame] | 98 |     auto reply = bus.call(method, timeout.count()); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 99 |     reply.read(value); | 
 | 100 |  | 
 | 101 |     return value; | 
 | 102 | } | 
 | 103 |  | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 104 | PropertyMap getAllDbusProperties( | 
 | 105 |     sdbusplus::bus_t& bus, const std::string& service, | 
 | 106 |     const std::string& objPath, const std::string& interface, | 
 | 107 |     std::chrono::microseconds timeout) | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 108 | { | 
 | 109 |     PropertyMap properties; | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 110 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 111 |     auto method = bus.new_method_call(service.c_str(), objPath.c_str(), | 
 | 112 |                                       PROP_INTF, METHOD_GET_ALL); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 113 |  | 
 | 114 |     method.append(interface); | 
 | 115 |  | 
| Kun Yi | 5dcf41e | 2019-03-05 14:02:51 -0800 | [diff] [blame] | 116 |     auto reply = bus.call(method, timeout.count()); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 117 |     reply.read(properties); | 
| George Liu | 3e3cc35 | 2023-07-26 15:59:31 +0800 | [diff] [blame] | 118 |  | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 119 |     return properties; | 
 | 120 | } | 
 | 121 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 122 | ObjectValueTree getManagedObjects(sdbusplus::bus_t& bus, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 123 |                                   const std::string& service, | 
 | 124 |                                   const std::string& objPath) | 
| Dhruvaraj Subhashchandran | 5c0beec | 2018-01-23 04:47:06 -0600 | [diff] [blame] | 125 | { | 
 | 126 |     ipmi::ObjectValueTree interfaces; | 
 | 127 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 128 |     auto method = bus.new_method_call(service.c_str(), objPath.c_str(), | 
 | 129 |                                       "org.freedesktop.DBus.ObjectManager", | 
 | 130 |                                       "GetManagedObjects"); | 
| Dhruvaraj Subhashchandran | 5c0beec | 2018-01-23 04:47:06 -0600 | [diff] [blame] | 131 |     auto reply = bus.call(method); | 
| Dhruvaraj Subhashchandran | 5c0beec | 2018-01-23 04:47:06 -0600 | [diff] [blame] | 132 |     reply.read(interfaces); | 
| George Liu | 3e3cc35 | 2023-07-26 15:59:31 +0800 | [diff] [blame] | 133 |  | 
| Dhruvaraj Subhashchandran | 5c0beec | 2018-01-23 04:47:06 -0600 | [diff] [blame] | 134 |     return interfaces; | 
 | 135 | } | 
 | 136 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 137 | void setDbusProperty(sdbusplus::bus_t& bus, const std::string& service, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 138 |                      const std::string& objPath, const std::string& interface, | 
| Kun Yi | 5dcf41e | 2019-03-05 14:02:51 -0800 | [diff] [blame] | 139 |                      const std::string& property, const Value& value, | 
 | 140 |                      std::chrono::microseconds timeout) | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 141 | { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 142 |     auto method = bus.new_method_call(service.c_str(), objPath.c_str(), | 
 | 143 |                                       PROP_INTF, METHOD_SET); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 144 |  | 
 | 145 |     method.append(interface, property, value); | 
 | 146 |  | 
| Kun Yi | 5dcf41e | 2019-03-05 14:02:51 -0800 | [diff] [blame] | 147 |     if (!bus.call(method, timeout.count())) | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 148 |     { | 
| George Liu | b4b4091 | 2024-07-17 16:14:17 +0800 | [diff] [blame] | 149 |         lg2::error("Failed to set {PROPERTY}, path: {PATH}, " | 
 | 150 |                    "interface: {INTERFACE}", | 
 | 151 |                    "PROPERTY", property, "PATH", objPath, "INTERFACE", | 
 | 152 |                    interface); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 153 |         elog<InternalFailure>(); | 
 | 154 |     } | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 155 | } | 
 | 156 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 157 | ServiceCache::ServiceCache(const std::string& intf, const std::string& path) : | 
| Vernon Mauery | 5401250 | 2018-11-07 10:17:31 -0800 | [diff] [blame] | 158 |     intf(intf), path(path), cachedService(std::nullopt), | 
 | 159 |     cachedBusName(std::nullopt) | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 160 | {} | 
| William A. Kennington III | e47fdfb | 2018-03-15 17:09:28 -0700 | [diff] [blame] | 161 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 162 | ServiceCache::ServiceCache(std::string&& intf, std::string&& path) : | 
| Vernon Mauery | 5401250 | 2018-11-07 10:17:31 -0800 | [diff] [blame] | 163 |     intf(std::move(intf)), path(std::move(path)), cachedService(std::nullopt), | 
 | 164 |     cachedBusName(std::nullopt) | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 165 | {} | 
| William A. Kennington III | e47fdfb | 2018-03-15 17:09:28 -0700 | [diff] [blame] | 166 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 167 | const std::string& ServiceCache::getService(sdbusplus::bus_t& bus) | 
| William A. Kennington III | e47fdfb | 2018-03-15 17:09:28 -0700 | [diff] [blame] | 168 | { | 
 | 169 |     if (!isValid(bus)) | 
 | 170 |     { | 
 | 171 |         cachedBusName = bus.get_unique_name(); | 
 | 172 |         cachedService = ::ipmi::getService(bus, intf, path); | 
 | 173 |     } | 
| Jayanth Othayoth | 195d552 | 2025-06-07 02:28:07 -0500 | [diff] [blame] | 174 |  | 
 | 175 |     if (!cachedService) | 
 | 176 |     { | 
 | 177 |         throw std::runtime_error("Service not cached"); | 
 | 178 |     } | 
| William A. Kennington III | e47fdfb | 2018-03-15 17:09:28 -0700 | [diff] [blame] | 179 |     return cachedService.value(); | 
 | 180 | } | 
 | 181 |  | 
 | 182 | void ServiceCache::invalidate() | 
 | 183 | { | 
| Vernon Mauery | 5401250 | 2018-11-07 10:17:31 -0800 | [diff] [blame] | 184 |     cachedBusName = std::nullopt; | 
 | 185 |     cachedService = std::nullopt; | 
| William A. Kennington III | e47fdfb | 2018-03-15 17:09:28 -0700 | [diff] [blame] | 186 | } | 
 | 187 |  | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 188 | sdbusplus::message_t ServiceCache::newMethodCall( | 
 | 189 |     sdbusplus::bus_t& bus, const char* intf, const char* method) | 
| William A. Kennington III | e47fdfb | 2018-03-15 17:09:28 -0700 | [diff] [blame] | 190 | { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 191 |     return bus.new_method_call(getService(bus).c_str(), path.c_str(), intf, | 
 | 192 |                                method); | 
| William A. Kennington III | e47fdfb | 2018-03-15 17:09:28 -0700 | [diff] [blame] | 193 | } | 
 | 194 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 195 | bool ServiceCache::isValid(sdbusplus::bus_t& bus) const | 
| William A. Kennington III | e47fdfb | 2018-03-15 17:09:28 -0700 | [diff] [blame] | 196 | { | 
 | 197 |     return cachedService && cachedBusName == bus.get_unique_name(); | 
 | 198 | } | 
 | 199 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 200 | std::string getService(sdbusplus::bus_t& bus, const std::string& intf, | 
| Tom Joseph | be703f7 | 2017-03-09 12:34:35 +0530 | [diff] [blame] | 201 |                        const std::string& path) | 
 | 202 | { | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 203 |     auto mapperCall = | 
 | 204 |         bus.new_method_call("xyz.openbmc_project.ObjectMapper", | 
 | 205 |                             "/xyz/openbmc_project/object_mapper", | 
 | 206 |                             "xyz.openbmc_project.ObjectMapper", "GetObject"); | 
| Tom Joseph | be703f7 | 2017-03-09 12:34:35 +0530 | [diff] [blame] | 207 |  | 
 | 208 |     mapperCall.append(path); | 
 | 209 |     mapperCall.append(std::vector<std::string>({intf})); | 
 | 210 |  | 
 | 211 |     auto mapperResponseMsg = bus.call(mapperCall); | 
 | 212 |  | 
| Tom Joseph | be703f7 | 2017-03-09 12:34:35 +0530 | [diff] [blame] | 213 |     std::map<std::string, std::vector<std::string>> mapperResponse; | 
 | 214 |     mapperResponseMsg.read(mapperResponse); | 
 | 215 |  | 
 | 216 |     if (mapperResponse.begin() == mapperResponse.end()) | 
 | 217 |     { | 
 | 218 |         throw std::runtime_error("ERROR in reading the mapper response"); | 
 | 219 |     } | 
 | 220 |  | 
 | 221 |     return mapperResponse.begin()->first; | 
 | 222 | } | 
 | 223 |  | 
| George Liu | 50f186c | 2024-02-04 16:51:26 +0800 | [diff] [blame] | 224 | ObjectTree getSubTree(sdbusplus::bus_t& bus, const InterfaceList& interfaces, | 
 | 225 |                       const std::string& subtreePath, int32_t depth) | 
 | 226 | { | 
 | 227 |     auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, | 
 | 228 |                                           MAPPER_INTF, "GetSubTree"); | 
 | 229 |  | 
 | 230 |     mapperCall.append(subtreePath, depth, interfaces); | 
 | 231 |  | 
 | 232 |     auto mapperReply = bus.call(mapperCall); | 
 | 233 |     ObjectTree objectTree; | 
 | 234 |     mapperReply.read(objectTree); | 
 | 235 |  | 
 | 236 |     return objectTree; | 
 | 237 | } | 
 | 238 |  | 
| Patrick Williams | 69b4c28 | 2025-03-03 11:19:13 -0500 | [diff] [blame] | 239 | ipmi::ObjectTree getAllDbusObjects( | 
 | 240 |     sdbusplus::bus_t& bus, const std::string& serviceRoot, | 
 | 241 |     const std::string& interface, const std::string& match) | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 242 | { | 
 | 243 |     std::vector<std::string> interfaces; | 
 | 244 |     interfaces.emplace_back(interface); | 
| Ratan Gupta | cc8feb4 | 2017-07-25 21:52:10 +0530 | [diff] [blame] | 245 |  | 
| George Liu | 50f186c | 2024-02-04 16:51:26 +0800 | [diff] [blame] | 246 |     ObjectTree objectTree = getSubTree(bus, interfaces, serviceRoot); | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 247 |     for (auto it = objectTree.begin(); it != objectTree.end();) | 
 | 248 |     { | 
 | 249 |         if (it->first.find(match) == std::string::npos) | 
 | 250 |         { | 
 | 251 |             it = objectTree.erase(it); | 
 | 252 |         } | 
 | 253 |         else | 
 | 254 |         { | 
 | 255 |             ++it; | 
 | 256 |         } | 
 | 257 |     } | 
 | 258 |  | 
 | 259 |     return objectTree; | 
 | 260 | } | 
 | 261 |  | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 262 | namespace method_no_args | 
 | 263 | { | 
 | 264 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 265 | void callDbusMethod(sdbusplus::bus_t& bus, const std::string& service, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 266 |                     const std::string& objPath, const std::string& interface, | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 267 |                     const std::string& method) | 
 | 268 |  | 
 | 269 | { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 270 |     auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(), | 
 | 271 |                                          interface.c_str(), method.c_str()); | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 272 |     auto reply = bus.call(busMethod); | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 273 | } | 
 | 274 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 275 | } // namespace method_no_args | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 276 |  | 
 | 277 | /********* Begin co-routine yielding alternatives ***************/ | 
 | 278 |  | 
| Patrick Williams | 69b4c28 | 2025-03-03 11:19:13 -0500 | [diff] [blame] | 279 | boost::system::error_code getService(Context::ptr ctx, const std::string& intf, | 
 | 280 |                                      const std::string& path, | 
 | 281 |                                      std::string& service) | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 282 | { | 
 | 283 |     boost::system::error_code ec; | 
 | 284 |     std::map<std::string, std::vector<std::string>> mapperResponse = | 
 | 285 |         ctx->bus->yield_method_call<decltype(mapperResponse)>( | 
 | 286 |             ctx->yield, ec, "xyz.openbmc_project.ObjectMapper", | 
 | 287 |             "/xyz/openbmc_project/object_mapper", | 
| Jason M. Bills | f596798 | 2020-03-06 10:42:08 -0800 | [diff] [blame] | 288 |             "xyz.openbmc_project.ObjectMapper", "GetObject", path, | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 289 |             std::vector<std::string>({intf})); | 
 | 290 |  | 
 | 291 |     if (!ec) | 
 | 292 |     { | 
 | 293 |         service = std::move(mapperResponse.begin()->first); | 
 | 294 |     } | 
 | 295 |     return ec; | 
 | 296 | } | 
 | 297 |  | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 298 | boost::system::error_code getSubTree( | 
 | 299 |     Context::ptr ctx, const InterfaceList& interfaces, | 
 | 300 |     const std::string& subtreePath, int32_t depth, ObjectTree& objectTree) | 
| George Liu | 50f186c | 2024-02-04 16:51:26 +0800 | [diff] [blame] | 301 | { | 
 | 302 |     boost::system::error_code ec; | 
 | 303 |     objectTree = ctx->bus->yield_method_call<ObjectTree>( | 
 | 304 |         ctx->yield, ec, MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF, "GetSubTree", | 
 | 305 |         subtreePath, depth, interfaces); | 
 | 306 |  | 
 | 307 |     return ec; | 
 | 308 | } | 
 | 309 |  | 
| Patrick Williams | 69b4c28 | 2025-03-03 11:19:13 -0500 | [diff] [blame] | 310 | boost::system::error_code getDbusObject( | 
 | 311 |     Context::ptr ctx, const std::string& interface, | 
 | 312 |     const std::string& subtreePath, const std::string& match, | 
 | 313 |     DbusObjectInfo& dbusObject) | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 314 | { | 
 | 315 |     std::vector<DbusInterface> interfaces; | 
 | 316 |     interfaces.emplace_back(interface); | 
 | 317 |  | 
 | 318 |     auto depth = 0; | 
| George Liu | 50f186c | 2024-02-04 16:51:26 +0800 | [diff] [blame] | 319 |     ObjectTree objectTree; | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 320 |     boost::system::error_code ec = | 
 | 321 |         getSubTree(ctx, interfaces, subtreePath, depth, objectTree); | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 322 |  | 
 | 323 |     if (ec) | 
 | 324 |     { | 
 | 325 |         return ec; | 
 | 326 |     } | 
 | 327 |  | 
 | 328 |     if (objectTree.empty()) | 
 | 329 |     { | 
| George Liu | b4b4091 | 2024-07-17 16:14:17 +0800 | [diff] [blame] | 330 |         lg2::error("No Object has implemented the interface: {INTERFACE}, " | 
 | 331 |                    "NetFn: {NETFN}, Cmd: {CMD}", | 
 | 332 |                    "INTERFACE", interface, "NETFN", lg2::hex, ctx->netFn, "CMD", | 
 | 333 |                    lg2::hex, ctx->cmd); | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 334 |         return boost::system::errc::make_error_code( | 
 | 335 |             boost::system::errc::no_such_process); | 
 | 336 |     } | 
 | 337 |  | 
 | 338 |     // if match is empty then return the first object | 
 | 339 |     if (match == "") | 
 | 340 |     { | 
 | 341 |         dbusObject = std::make_pair( | 
 | 342 |             std::move(objectTree.begin()->first), | 
 | 343 |             std::move(objectTree.begin()->second.begin()->first)); | 
 | 344 |         return ec; | 
 | 345 |     } | 
 | 346 |  | 
 | 347 |     // else search the match string in the object path | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 348 |     auto found = std::find_if( | 
 | 349 |         objectTree.begin(), objectTree.end(), [&match](const auto& object) { | 
 | 350 |             return (object.first.find(match) != std::string::npos); | 
 | 351 |         }); | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 352 |  | 
 | 353 |     if (found == objectTree.end()) | 
 | 354 |     { | 
| George Liu | b4b4091 | 2024-07-17 16:14:17 +0800 | [diff] [blame] | 355 |         lg2::error("Failed to find object which matches: {MATCH}, " | 
 | 356 |                    "NetFn: {NETFN}, Cmd: {CMD}", | 
 | 357 |                    "MATCH", match, "NETFN", lg2::hex, ctx->netFn, "CMD", | 
 | 358 |                    lg2::hex, ctx->cmd); | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 359 |         // set ec | 
 | 360 |         return boost::system::errc::make_error_code( | 
 | 361 |             boost::system::errc::no_such_file_or_directory); | 
 | 362 |     } | 
 | 363 |  | 
 | 364 |     dbusObject = std::make_pair(std::move(found->first), | 
 | 365 |                                 std::move(found->second.begin()->first)); | 
 | 366 |     return ec; | 
 | 367 | } | 
 | 368 |  | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 369 | boost::system::error_code getAllDbusProperties( | 
 | 370 |     Context::ptr ctx, const std::string& service, const std::string& objPath, | 
 | 371 |     const std::string& interface, PropertyMap& properties) | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 372 | { | 
 | 373 |     boost::system::error_code ec; | 
 | 374 |     properties = ctx->bus->yield_method_call<PropertyMap>( | 
 | 375 |         ctx->yield, ec, service.c_str(), objPath.c_str(), PROP_INTF, | 
 | 376 |         METHOD_GET_ALL, interface); | 
 | 377 |     return ec; | 
 | 378 | } | 
 | 379 |  | 
| Patrick Williams | 69b4c28 | 2025-03-03 11:19:13 -0500 | [diff] [blame] | 380 | boost::system::error_code setDbusProperty( | 
 | 381 |     Context::ptr ctx, const std::string& service, const std::string& objPath, | 
 | 382 |     const std::string& interface, const std::string& property, | 
 | 383 |     const Value& value) | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 384 | { | 
 | 385 |     boost::system::error_code ec; | 
 | 386 |     ctx->bus->yield_method_call(ctx->yield, ec, service.c_str(), | 
 | 387 |                                 objPath.c_str(), PROP_INTF, METHOD_SET, | 
 | 388 |                                 interface, property, value); | 
 | 389 |     return ec; | 
 | 390 | } | 
 | 391 |  | 
| Patrick Williams | 69b4c28 | 2025-03-03 11:19:13 -0500 | [diff] [blame] | 392 | boost::system::error_code getAllDbusObjects( | 
 | 393 |     Context::ptr ctx, const std::string& serviceRoot, | 
 | 394 |     const std::string& interface, const std::string& match, | 
 | 395 |     ObjectTree& objectTree) | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 396 | { | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 397 |     std::vector<std::string> interfaces; | 
 | 398 |     interfaces.emplace_back(interface); | 
 | 399 |  | 
 | 400 |     auto depth = 0; | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 401 |     boost::system::error_code ec = | 
 | 402 |         getSubTree(ctx, interfaces, serviceRoot, depth, objectTree); | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 403 |     if (ec) | 
 | 404 |     { | 
 | 405 |         return ec; | 
 | 406 |     } | 
 | 407 |  | 
 | 408 |     for (auto it = objectTree.begin(); it != objectTree.end();) | 
 | 409 |     { | 
 | 410 |         if (it->first.find(match) == std::string::npos) | 
 | 411 |         { | 
 | 412 |             it = objectTree.erase(it); | 
 | 413 |         } | 
 | 414 |         else | 
 | 415 |         { | 
 | 416 |             ++it; | 
 | 417 |         } | 
 | 418 |     } | 
 | 419 |  | 
 | 420 |     return ec; | 
 | 421 | } | 
 | 422 |  | 
| Patrick Williams | 69b4c28 | 2025-03-03 11:19:13 -0500 | [diff] [blame] | 423 | boost::system::error_code getManagedObjects( | 
 | 424 |     Context::ptr ctx, const std::string& service, const std::string& objPath, | 
 | 425 |     ObjectValueTree& objects) | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 426 | { | 
 | 427 |     boost::system::error_code ec; | 
 | 428 |     objects = ctx->bus->yield_method_call<ipmi::ObjectValueTree>( | 
 | 429 |         ctx->yield, ec, service.c_str(), objPath.c_str(), | 
 | 430 |         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); | 
 | 431 |     return ec; | 
 | 432 | } | 
 | 433 |  | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 434 | boost::system::error_code callDbusMethod( | 
 | 435 |     Context::ptr ctx, const std::string& service, const std::string& objPath, | 
 | 436 |     const std::string& interface, const std::string& method) | 
| Albert Zhang | b53049e | 2022-04-02 15:39:51 +0800 | [diff] [blame] | 437 | { | 
 | 438 |     boost::system::error_code ec; | 
 | 439 |     ctx->bus->yield_method_call(ctx->yield, ec, service, objPath, interface, | 
 | 440 |                                 method); | 
 | 441 |     return ec; | 
 | 442 | } | 
 | 443 |  | 
| Vernon Mauery | eeb0f98 | 2019-05-29 16:36:58 -0700 | [diff] [blame] | 444 | /********* End co-routine yielding alternatives ***************/ | 
 | 445 |  | 
| Matt Simmering | 68d9d40 | 2023-11-09 14:22:11 -0800 | [diff] [blame] | 446 | ipmi::Cc i2cWriteRead(std::string i2cBus, const uint8_t targetAddr, | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 447 |                       std::vector<uint8_t> writeData, | 
 | 448 |                       std::vector<uint8_t>& readBuf) | 
 | 449 | { | 
 | 450 |     // Open the i2c device, for low-level combined data write/read | 
 | 451 |     int i2cDev = ::open(i2cBus.c_str(), O_RDWR | O_CLOEXEC); | 
 | 452 |     if (i2cDev < 0) | 
 | 453 |     { | 
| George Liu | b4b4091 | 2024-07-17 16:14:17 +0800 | [diff] [blame] | 454 |         lg2::error("Failed to open i2c bus: {BUS}", "BUS", i2cBus); | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 455 |         return ipmi::ccInvalidFieldRequest; | 
 | 456 |     } | 
 | 457 |  | 
 | 458 |     const size_t writeCount = writeData.size(); | 
 | 459 |     const size_t readCount = readBuf.size(); | 
 | 460 |     int msgCount = 0; | 
| Willy Tu | 11d6889 | 2022-01-20 10:37:34 -0800 | [diff] [blame] | 461 |     i2c_msg i2cmsg[2] = {}; | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 462 |     if (writeCount) | 
 | 463 |     { | 
| Matt Simmering | 68d9d40 | 2023-11-09 14:22:11 -0800 | [diff] [blame] | 464 |         // Data will be writtern to the target address | 
 | 465 |         i2cmsg[msgCount].addr = targetAddr; | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 466 |         i2cmsg[msgCount].flags = 0x00; | 
 | 467 |         i2cmsg[msgCount].len = writeCount; | 
 | 468 |         i2cmsg[msgCount].buf = writeData.data(); | 
 | 469 |         msgCount++; | 
 | 470 |     } | 
 | 471 |     if (readCount) | 
 | 472 |     { | 
| Matt Simmering | 68d9d40 | 2023-11-09 14:22:11 -0800 | [diff] [blame] | 473 |         // Data will be read into the buffer from the target address | 
 | 474 |         i2cmsg[msgCount].addr = targetAddr; | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 475 |         i2cmsg[msgCount].flags = I2C_M_RD; | 
 | 476 |         i2cmsg[msgCount].len = readCount; | 
 | 477 |         i2cmsg[msgCount].buf = readBuf.data(); | 
 | 478 |         msgCount++; | 
 | 479 |     } | 
 | 480 |  | 
| Willy Tu | 11d6889 | 2022-01-20 10:37:34 -0800 | [diff] [blame] | 481 |     i2c_rdwr_ioctl_data msgReadWrite = {}; | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 482 |     msgReadWrite.msgs = i2cmsg; | 
 | 483 |     msgReadWrite.nmsgs = msgCount; | 
 | 484 |  | 
 | 485 |     // Perform the combined write/read | 
 | 486 |     int ret = ::ioctl(i2cDev, I2C_RDWR, &msgReadWrite); | 
 | 487 |     ::close(i2cDev); | 
 | 488 |  | 
 | 489 |     if (ret < 0) | 
 | 490 |     { | 
| George Liu | b4b4091 | 2024-07-17 16:14:17 +0800 | [diff] [blame] | 491 |         lg2::error("I2C WR Failed! {RET}", "RET", ret); | 
| Yong Li | 7dc4ac0 | 2019-08-23 17:44:32 +0800 | [diff] [blame] | 492 |         return ipmi::ccUnspecifiedError; | 
 | 493 |     } | 
 | 494 |     if (readCount) | 
 | 495 |     { | 
 | 496 |         readBuf.resize(msgReadWrite.msgs[msgCount - 1].len); | 
 | 497 |     } | 
 | 498 |  | 
 | 499 |     return ipmi::ccSuccess; | 
 | 500 | } | 
 | 501 |  | 
| Prithvi Pai | c1e7b5c | 2025-09-01 13:13:15 +0530 | [diff] [blame] | 502 | std::vector<std::string> split(const std::string& srcStr, char delim) | 
 | 503 | { | 
 | 504 |     std::vector<std::string> out; | 
 | 505 |     std::stringstream ss(srcStr); | 
 | 506 |     std::string item; | 
 | 507 |  | 
 | 508 |     while (std::getline(ss, item, delim)) | 
 | 509 |     { | 
 | 510 |         if (!item.empty()) | 
 | 511 |         { | 
 | 512 |             out.emplace_back(item); | 
 | 513 |         } | 
 | 514 |     } | 
 | 515 |     return out; | 
 | 516 | } | 
 | 517 |  | 
| Tom Joseph | be703f7 | 2017-03-09 12:34:35 +0530 | [diff] [blame] | 518 | } // namespace ipmi |