| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 1 | #include "config.h" | 
 | 2 |  | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 3 | #include "ibm_vpd_utils.hpp" | 
| Patrick Venture | c83c4dc | 2018-11-01 16:29:18 -0700 | [diff] [blame] | 4 |  | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 5 | #include "common_utility.hpp" | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 6 | #include "defines.hpp" | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 7 | #include "vpd_exceptions.hpp" | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 8 |  | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 9 | #include <boost/algorithm/string.hpp> | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 10 | #include <gpiod.hpp> | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 11 | #include <nlohmann/json.hpp> | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 12 | #include <phosphor-logging/elog-errors.hpp> | 
| Patrick Venture | c83c4dc | 2018-11-01 16:29:18 -0700 | [diff] [blame] | 13 | #include <phosphor-logging/log.hpp> | 
 | 14 | #include <sdbusplus/server.hpp> | 
| Patrick Williams | c78d887 | 2023-05-10 07:50:56 -0500 | [diff] [blame] | 15 | #include <xyz/openbmc_project/Common/error.hpp> | 
 | 16 |  | 
 | 17 | #include <filesystem> | 
 | 18 | #include <fstream> | 
 | 19 | #include <iomanip> | 
 | 20 | #include <regex> | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 21 | #include <sstream> | 
 | 22 | #include <vector> | 
| Deepak Kodihalli | 7679449 | 2017-02-16 23:48:18 -0600 | [diff] [blame] | 23 |  | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 24 | using json = nlohmann::json; | 
 | 25 |  | 
| Deepak Kodihalli | 7679449 | 2017-02-16 23:48:18 -0600 | [diff] [blame] | 26 | namespace openpower | 
 | 27 | { | 
 | 28 | namespace vpd | 
 | 29 | { | 
| SunnySrivastava1984 | 945a02d | 2020-05-06 01:55:41 -0500 | [diff] [blame] | 30 | using namespace openpower::vpd::constants; | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 31 | using namespace inventory; | 
 | 32 | using namespace phosphor::logging; | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 33 | using namespace sdbusplus::xyz::openbmc_project::Common::Error; | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 34 | using namespace record; | 
 | 35 | using namespace openpower::vpd::exceptions; | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 36 | using namespace common::utility; | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 37 | using Severity = openpower::vpd::constants::PelSeverity; | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 38 | namespace fs = std::filesystem; | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 39 |  | 
 | 40 | // mapping of severity enum to severity interface | 
 | 41 | static std::unordered_map<Severity, std::string> sevMap = { | 
 | 42 |     {Severity::INFORMATIONAL, | 
 | 43 |      "xyz.openbmc_project.Logging.Entry.Level.Informational"}, | 
 | 44 |     {Severity::DEBUG, "xyz.openbmc_project.Logging.Entry.Level.Debug"}, | 
 | 45 |     {Severity::NOTICE, "xyz.openbmc_project.Logging.Entry.Level.Notice"}, | 
 | 46 |     {Severity::WARNING, "xyz.openbmc_project.Logging.Entry.Level.Warning"}, | 
 | 47 |     {Severity::CRITICAL, "xyz.openbmc_project.Logging.Entry.Level.Critical"}, | 
 | 48 |     {Severity::EMERGENCY, "xyz.openbmc_project.Logging.Entry.Level.Emergency"}, | 
 | 49 |     {Severity::ERROR, "xyz.openbmc_project.Logging.Entry.Level.Error"}, | 
 | 50 |     {Severity::ALERT, "xyz.openbmc_project.Logging.Entry.Level.Alert"}}; | 
 | 51 |  | 
| Deepak Kodihalli | 7679449 | 2017-02-16 23:48:18 -0600 | [diff] [blame] | 52 | namespace inventory | 
 | 53 | { | 
 | 54 |  | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 55 | MapperResponse | 
 | 56 |     getObjectSubtreeForInterfaces(const std::string& root, const int32_t depth, | 
 | 57 |                                   const std::vector<std::string>& interfaces) | 
 | 58 | { | 
 | 59 |     auto bus = sdbusplus::bus::new_default(); | 
 | 60 |     auto mapperCall = bus.new_method_call(mapperDestination, mapperObjectPath, | 
 | 61 |                                           mapperInterface, "GetSubTree"); | 
 | 62 |     mapperCall.append(root); | 
 | 63 |     mapperCall.append(depth); | 
 | 64 |     mapperCall.append(interfaces); | 
 | 65 |  | 
 | 66 |     MapperResponse result = {}; | 
 | 67 |  | 
 | 68 |     try | 
 | 69 |     { | 
 | 70 |         auto response = bus.call(mapperCall); | 
 | 71 |  | 
 | 72 |         response.read(result); | 
 | 73 |     } | 
| Patrick Williams | 2eb0176 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 74 |     catch (const sdbusplus::exception_t& e) | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 75 |     { | 
 | 76 |         log<level::ERR>("Error in mapper GetSubTree", | 
 | 77 |                         entry("ERROR=%s", e.what())); | 
 | 78 |     } | 
 | 79 |  | 
 | 80 |     return result; | 
 | 81 | } | 
 | 82 |  | 
| Deepak Kodihalli | 7679449 | 2017-02-16 23:48:18 -0600 | [diff] [blame] | 83 | } // namespace inventory | 
 | 84 |  | 
| SunnySrivastava1984 | f6d541e | 2020-02-04 12:50:40 -0600 | [diff] [blame] | 85 | LE2ByteData readUInt16LE(Binary::const_iterator iterator) | 
 | 86 | { | 
 | 87 |     LE2ByteData lowByte = *iterator; | 
 | 88 |     LE2ByteData highByte = *(iterator + 1); | 
 | 89 |     lowByte |= (highByte << 8); | 
 | 90 |     return lowByte; | 
 | 91 | } | 
 | 92 |  | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 93 | /** @brief Encodes a keyword for D-Bus. | 
 | 94 |  */ | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 95 | std::string encodeKeyword(const std::string& kw, const std::string& encoding) | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 96 | { | 
 | 97 |     if (encoding == "MAC") | 
 | 98 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 99 |         std::string res{}; | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 100 |         size_t first = kw[0]; | 
 | 101 |         res += toHex(first >> 4); | 
 | 102 |         res += toHex(first & 0x0f); | 
 | 103 |         for (size_t i = 1; i < kw.size(); ++i) | 
 | 104 |         { | 
 | 105 |             res += ":"; | 
 | 106 |             res += toHex(kw[i] >> 4); | 
 | 107 |             res += toHex(kw[i] & 0x0f); | 
 | 108 |         } | 
 | 109 |         return res; | 
 | 110 |     } | 
 | 111 |     else if (encoding == "DATE") | 
 | 112 |     { | 
 | 113 |         // Date, represent as | 
 | 114 |         // <year>-<month>-<day> <hour>:<min> | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 115 |         std::string res{}; | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 116 |         static constexpr uint8_t skipPrefix = 3; | 
 | 117 |  | 
 | 118 |         auto strItr = kw.begin(); | 
 | 119 |         advance(strItr, skipPrefix); | 
 | 120 |         for_each(strItr, kw.end(), [&res](size_t c) { res += c; }); | 
 | 121 |  | 
 | 122 |         res.insert(BD_YEAR_END, 1, '-'); | 
 | 123 |         res.insert(BD_MONTH_END, 1, '-'); | 
 | 124 |         res.insert(BD_DAY_END, 1, ' '); | 
 | 125 |         res.insert(BD_HOUR_END, 1, ':'); | 
 | 126 |  | 
 | 127 |         return res; | 
 | 128 |     } | 
 | 129 |     else // default to string encoding | 
 | 130 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 131 |         return std::string(kw.begin(), kw.end()); | 
| SunnySrivastava1984 | d076da8 | 2020-03-05 05:33:35 -0600 | [diff] [blame] | 132 |     } | 
 | 133 | } | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 134 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 135 | std::string readBusProperty(const std::string& obj, const std::string& inf, | 
 | 136 |                             const std::string& prop) | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 137 | { | 
 | 138 |     std::string propVal{}; | 
 | 139 |     std::string object = INVENTORY_PATH + obj; | 
 | 140 |     auto bus = sdbusplus::bus::new_default(); | 
 | 141 |     auto properties = bus.new_method_call( | 
 | 142 |         "xyz.openbmc_project.Inventory.Manager", object.c_str(), | 
 | 143 |         "org.freedesktop.DBus.Properties", "Get"); | 
 | 144 |     properties.append(inf); | 
 | 145 |     properties.append(prop); | 
 | 146 |     auto result = bus.call(properties); | 
 | 147 |     if (!result.is_method_error()) | 
 | 148 |     { | 
| Sunny Srivastava | 28abd6e | 2021-07-28 02:58:28 -0500 | [diff] [blame] | 149 |         inventory::Value val; | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 150 |         result.read(val); | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 151 |         if (auto pVal = std::get_if<Binary>(&val)) | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 152 |         { | 
 | 153 |             propVal.assign(reinterpret_cast<const char*>(pVal->data()), | 
 | 154 |                            pVal->size()); | 
 | 155 |         } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 156 |         else if (auto pVal = std::get_if<std::string>(&val)) | 
| SunnySrivastava1984 | bca5aaa | 2020-04-21 05:31:04 -0500 | [diff] [blame] | 157 |         { | 
 | 158 |             propVal.assign(pVal->data(), pVal->size()); | 
 | 159 |         } | 
| Sunny Srivastava | 28abd6e | 2021-07-28 02:58:28 -0500 | [diff] [blame] | 160 |         else if (auto pVal = get_if<bool>(&val)) | 
 | 161 |         { | 
 | 162 |             if (*pVal == false) | 
 | 163 |             { | 
 | 164 |                 propVal = "false"; | 
 | 165 |             } | 
 | 166 |             else | 
 | 167 |             { | 
 | 168 |                 propVal = "true"; | 
 | 169 |             } | 
 | 170 |         } | 
| SunnySrivastava1984 | 4330654 | 2020-04-01 02:50:20 -0500 | [diff] [blame] | 171 |     } | 
 | 172 |     return propVal; | 
 | 173 | } | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 174 |  | 
 | 175 | void createPEL(const std::map<std::string, std::string>& additionalData, | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 176 |                const Severity& sev, const std::string& errIntf, sd_bus* sdBus) | 
 | 177 | { | 
 | 178 |     // This pointer will be NULL in case the call is made from ibm-read-vpd. In | 
 | 179 |     // that case a sync call will do. | 
 | 180 |     if (sdBus == nullptr) | 
 | 181 |     { | 
 | 182 |         createSyncPEL(additionalData, sev, errIntf); | 
 | 183 |     } | 
 | 184 |     else | 
 | 185 |     { | 
 | 186 |         std::string errDescription{}; | 
 | 187 |         auto pos = additionalData.find("DESCRIPTION"); | 
 | 188 |         if (pos != additionalData.end()) | 
 | 189 |         { | 
 | 190 |             errDescription = pos->second; | 
 | 191 |         } | 
 | 192 |         else | 
 | 193 |         { | 
 | 194 |             errDescription = "Description field missing in additional data"; | 
 | 195 |         } | 
 | 196 |  | 
 | 197 |         std::string pelSeverity = | 
 | 198 |             "xyz.openbmc_project.Logging.Entry.Level.Error"; | 
 | 199 |         auto itr = sevMap.find(sev); | 
 | 200 |         if (itr != sevMap.end()) | 
 | 201 |         { | 
 | 202 |             pelSeverity = itr->second; | 
 | 203 |         } | 
 | 204 |  | 
 | 205 |         // Implies this is a call from Manager. Hence we need to make an async | 
 | 206 |         // call to avoid deadlock with Phosphor-logging. | 
 | 207 |         auto rc = sd_bus_call_method_async( | 
 | 208 |             sdBus, NULL, loggerService, loggerObjectPath, loggerCreateInterface, | 
 | 209 |             "Create", NULL, NULL, "ssa{ss}", errIntf.c_str(), | 
 | 210 |             pelSeverity.c_str(), 1, "DESCRIPTION", errDescription.c_str()); | 
 | 211 |  | 
 | 212 |         if (rc < 0) | 
 | 213 |         { | 
 | 214 |             log<level::ERR>("Error calling sd_bus_call_method_async", | 
 | 215 |                             entry("RC=%d", rc), entry("MSG=%s", strerror(-rc))); | 
 | 216 |         } | 
 | 217 |     } | 
 | 218 | } | 
 | 219 |  | 
 | 220 | void createSyncPEL(const std::map<std::string, std::string>& additionalData, | 
 | 221 |                    const Severity& sev, const std::string& errIntf) | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 222 | { | 
 | 223 |     try | 
 | 224 |     { | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 225 |         std::string pelSeverity = | 
 | 226 |             "xyz.openbmc_project.Logging.Entry.Level.Error"; | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 227 |         auto bus = sdbusplus::bus::new_default(); | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 228 |         auto service = getService(bus, loggerObjectPath, loggerCreateInterface); | 
 | 229 |         auto method = bus.new_method_call(service.c_str(), loggerObjectPath, | 
 | 230 |                                           loggerCreateInterface, "Create"); | 
 | 231 |  | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 232 |         auto itr = sevMap.find(sev); | 
 | 233 |         if (itr != sevMap.end()) | 
 | 234 |         { | 
 | 235 |             pelSeverity = itr->second; | 
 | 236 |         } | 
 | 237 |  | 
 | 238 |         method.append(errIntf, pelSeverity, additionalData); | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 239 |         auto resp = bus.call(method); | 
 | 240 |     } | 
| Patrick Williams | 2eb0176 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 241 |     catch (const sdbusplus::exception_t& e) | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 242 |     { | 
| Sunny Srivastava | 5ef6ccc | 2022-05-30 01:35:13 -0500 | [diff] [blame] | 243 |         std::cerr << "Dbus call to phosphor-logging Create failed. Reason:" | 
 | 244 |                   << e.what(); | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 245 |     } | 
 | 246 | } | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 247 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 248 | inventory::VPDfilepath getVpdFilePath(const std::string& jsonFile, | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 249 |                                       const std::string& ObjPath) | 
 | 250 | { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 251 |     std::ifstream inventoryJson(jsonFile); | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 252 |     const auto& jsonObject = json::parse(inventoryJson); | 
 | 253 |     inventory::VPDfilepath filePath{}; | 
 | 254 |  | 
 | 255 |     if (jsonObject.find("frus") == jsonObject.end()) | 
 | 256 |     { | 
 | 257 |         throw(VpdJsonException( | 
 | 258 |             "Invalid JSON structure - frus{} object not found in ", jsonFile)); | 
 | 259 |     } | 
 | 260 |  | 
 | 261 |     const nlohmann::json& groupFRUS = | 
 | 262 |         jsonObject["frus"].get_ref<const nlohmann::json::object_t&>(); | 
 | 263 |     for (const auto& itemFRUS : groupFRUS.items()) | 
 | 264 |     { | 
 | 265 |         const std::vector<nlohmann::json>& groupEEPROM = | 
 | 266 |             itemFRUS.value().get_ref<const nlohmann::json::array_t&>(); | 
 | 267 |         for (const auto& itemEEPROM : groupEEPROM) | 
 | 268 |         { | 
 | 269 |             if (itemEEPROM["inventoryPath"] | 
 | 270 |                     .get_ref<const nlohmann::json::string_t&>() == ObjPath) | 
 | 271 |             { | 
 | 272 |                 filePath = itemFRUS.key(); | 
 | 273 |                 return filePath; | 
 | 274 |             } | 
 | 275 |         } | 
 | 276 |     } | 
 | 277 |  | 
 | 278 |     return filePath; | 
 | 279 | } | 
 | 280 |  | 
 | 281 | bool isPathInJson(const std::string& eepromPath) | 
 | 282 | { | 
 | 283 |     bool present = false; | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 284 |     std::ifstream inventoryJson(INVENTORY_JSON_SYM_LINK); | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 285 |  | 
 | 286 |     try | 
 | 287 |     { | 
 | 288 |         auto js = json::parse(inventoryJson); | 
 | 289 |         if (js.find("frus") == js.end()) | 
 | 290 |         { | 
 | 291 |             throw(VpdJsonException( | 
 | 292 |                 "Invalid JSON structure - frus{} object not found in ", | 
 | 293 |                 INVENTORY_JSON_SYM_LINK)); | 
 | 294 |         } | 
 | 295 |         json fruJson = js["frus"]; | 
 | 296 |  | 
 | 297 |         if (fruJson.find(eepromPath) != fruJson.end()) | 
 | 298 |         { | 
 | 299 |             present = true; | 
 | 300 |         } | 
 | 301 |     } | 
| Patrick Williams | 8e15b93 | 2021-10-06 13:04:22 -0500 | [diff] [blame] | 302 |     catch (const json::parse_error& ex) | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 303 |     { | 
 | 304 |         throw(VpdJsonException("Json Parsing failed", INVENTORY_JSON_SYM_LINK)); | 
 | 305 |     } | 
 | 306 |     return present; | 
 | 307 | } | 
 | 308 |  | 
 | 309 | bool isRecKwInDbusJson(const std::string& recordName, | 
 | 310 |                        const std::string& keyword) | 
 | 311 | { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 312 |     std::ifstream propertyJson(DBUS_PROP_JSON); | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 313 |     json dbusProperty; | 
 | 314 |     bool present = false; | 
 | 315 |  | 
 | 316 |     if (propertyJson.is_open()) | 
 | 317 |     { | 
 | 318 |         try | 
 | 319 |         { | 
 | 320 |             auto dbusPropertyJson = json::parse(propertyJson); | 
 | 321 |             if (dbusPropertyJson.find("dbusProperties") == | 
 | 322 |                 dbusPropertyJson.end()) | 
 | 323 |             { | 
 | 324 |                 throw(VpdJsonException("dbusProperties{} object not found in " | 
 | 325 |                                        "DbusProperties json : ", | 
 | 326 |                                        DBUS_PROP_JSON)); | 
 | 327 |             } | 
 | 328 |  | 
 | 329 |             dbusProperty = dbusPropertyJson["dbusProperties"]; | 
 | 330 |             if (dbusProperty.contains(recordName)) | 
 | 331 |             { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 332 |                 const std::vector<std::string>& kwdsToPublish = | 
 | 333 |                     dbusProperty[recordName]; | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 334 |                 if (find(kwdsToPublish.begin(), kwdsToPublish.end(), keyword) != | 
 | 335 |                     kwdsToPublish.end()) // present | 
 | 336 |                 { | 
 | 337 |                     present = true; | 
 | 338 |                 } | 
 | 339 |             } | 
 | 340 |         } | 
| Patrick Williams | 8e15b93 | 2021-10-06 13:04:22 -0500 | [diff] [blame] | 341 |         catch (const json::parse_error& ex) | 
| PriyangaRamasamy | c0a534f | 2020-08-24 21:29:18 +0530 | [diff] [blame] | 342 |         { | 
 | 343 |             throw(VpdJsonException("Json Parsing failed", DBUS_PROP_JSON)); | 
 | 344 |         } | 
 | 345 |     } | 
 | 346 |     else | 
 | 347 |     { | 
 | 348 |         // If dbus properties json is not available, we assume the given | 
 | 349 |         // record-keyword is part of dbus-properties json. So setting the bool | 
 | 350 |         // variable to true. | 
 | 351 |         present = true; | 
 | 352 |     } | 
 | 353 |     return present; | 
 | 354 | } | 
 | 355 |  | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 356 | vpdType vpdTypeCheck(const Binary& vpdVector) | 
 | 357 | { | 
 | 358 |     // Read first 3 Bytes to check the 11S bar code format | 
 | 359 |     std::string is11SFormat = ""; | 
 | 360 |     for (uint8_t i = 0; i < FORMAT_11S_LEN; i++) | 
 | 361 |     { | 
 | 362 |         is11SFormat += vpdVector[MEMORY_VPD_DATA_START + i]; | 
 | 363 |     } | 
 | 364 |  | 
 | 365 |     if (vpdVector[IPZ_DATA_START] == KW_VAL_PAIR_START_TAG) | 
 | 366 |     { | 
 | 367 |         // IPZ VPD FORMAT | 
 | 368 |         return vpdType::IPZ_VPD; | 
 | 369 |     } | 
 | 370 |     else if (vpdVector[KW_VPD_DATA_START] == KW_VPD_START_TAG) | 
 | 371 |     { | 
 | 372 |         // KEYWORD VPD FORMAT | 
 | 373 |         return vpdType::KEYWORD_VPD; | 
 | 374 |     } | 
| jinuthomas | 6555e7e | 2023-02-14 21:48:00 -0600 | [diff] [blame] | 375 |     else if (((vpdVector[SPD_BYTE_3] & SPD_BYTE_BIT_0_3_MASK) == | 
 | 376 |               SPD_MODULE_TYPE_DDIMM) && | 
| jinuthomas | 0abbb9c | 2023-05-05 01:37:07 -0500 | [diff] [blame] | 377 |              (is11SFormat.compare(MEMORY_VPD_START_TAG) == 0)) | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 378 |     { | 
| jinuthomas | 6555e7e | 2023-02-14 21:48:00 -0600 | [diff] [blame] | 379 |         // DDIMM Memory VPD format | 
 | 380 |         if ((vpdVector[SPD_BYTE_2] & SPD_BYTE_MASK) == SPD_DRAM_TYPE_DDR5) | 
 | 381 |         { | 
 | 382 |             return vpdType::DDR5_DDIMM_MEMORY_VPD; | 
 | 383 |         } | 
 | 384 |         else if ((vpdVector[SPD_BYTE_2] & SPD_BYTE_MASK) == SPD_DRAM_TYPE_DDR4) | 
 | 385 |         { | 
 | 386 |             return vpdType::DDR4_DDIMM_MEMORY_VPD; | 
 | 387 |         } | 
 | 388 |     } | 
 | 389 |     else if ((vpdVector[SPD_BYTE_2] & SPD_BYTE_MASK) == SPD_DRAM_TYPE_DDR5) | 
 | 390 |     { | 
 | 391 |         // ISDIMM Memory VPD format | 
 | 392 |         return vpdType::DDR5_ISDIMM_MEMORY_VPD; | 
 | 393 |     } | 
 | 394 |     else if ((vpdVector[SPD_BYTE_2] & SPD_BYTE_MASK) == SPD_DRAM_TYPE_DDR4) | 
 | 395 |     { | 
 | 396 |         // ISDIMM Memory VPD format | 
 | 397 |         return vpdType::DDR4_ISDIMM_MEMORY_VPD; | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 398 |     } | 
 | 399 |  | 
 | 400 |     // INVALID VPD FORMAT | 
 | 401 |     return vpdType::INVALID_VPD_FORMAT; | 
 | 402 | } | 
 | 403 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 404 | const std::string getIM(const Parsed& vpdMap) | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 405 | { | 
 | 406 |     Binary imVal; | 
 | 407 |     auto property = vpdMap.find("VSBP"); | 
 | 408 |     if (property != vpdMap.end()) | 
 | 409 |     { | 
 | 410 |         auto kw = (property->second).find("IM"); | 
 | 411 |         if (kw != (property->second).end()) | 
 | 412 |         { | 
 | 413 |             copy(kw->second.begin(), kw->second.end(), back_inserter(imVal)); | 
 | 414 |         } | 
 | 415 |     } | 
 | 416 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 417 |     std::ostringstream oss; | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 418 |     for (auto& i : imVal) | 
 | 419 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 420 |         oss << std::setw(2) << std::setfill('0') << std::hex | 
 | 421 |             << static_cast<int>(i); | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 422 |     } | 
 | 423 |  | 
 | 424 |     return oss.str(); | 
 | 425 | } | 
 | 426 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 427 | const std::string getHW(const Parsed& vpdMap) | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 428 | { | 
 | 429 |     Binary hwVal; | 
 | 430 |     auto prop = vpdMap.find("VINI"); | 
 | 431 |     if (prop != vpdMap.end()) | 
 | 432 |     { | 
 | 433 |         auto kw = (prop->second).find("HW"); | 
 | 434 |         if (kw != (prop->second).end()) | 
 | 435 |         { | 
 | 436 |             copy(kw->second.begin(), kw->second.end(), back_inserter(hwVal)); | 
 | 437 |         } | 
 | 438 |     } | 
 | 439 |  | 
| Alpana Kumari | 88d2ae8 | 2021-11-10 03:23:31 -0600 | [diff] [blame] | 440 |     // The planar pass only comes from the LSB of the HW keyword, | 
 | 441 |     // where as the MSB is used for other purposes such as signifying clock | 
 | 442 |     // termination. | 
 | 443 |     hwVal[0] = 0x00; | 
 | 444 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 445 |     std::ostringstream hwString; | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 446 |     for (auto& i : hwVal) | 
 | 447 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 448 |         hwString << std::setw(2) << std::setfill('0') << std::hex | 
 | 449 |                  << static_cast<int>(i); | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 450 |     } | 
 | 451 |  | 
 | 452 |     return hwString.str(); | 
 | 453 | } | 
 | 454 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 455 | std::string getSystemsJson(const Parsed& vpdMap) | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 456 | { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 457 |     std::string jsonPath = "/usr/share/vpd/"; | 
 | 458 |     std::string jsonName{}; | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 459 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 460 |     std::ifstream systemJson(SYSTEM_JSON); | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 461 |     if (!systemJson) | 
 | 462 |     { | 
 | 463 |         throw((VpdJsonException("Failed to access Json path", SYSTEM_JSON))); | 
 | 464 |     } | 
 | 465 |  | 
 | 466 |     try | 
 | 467 |     { | 
 | 468 |         auto js = json::parse(systemJson); | 
 | 469 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 470 |         std::string hwKeyword = getHW(vpdMap); | 
 | 471 |         const std::string imKeyword = getIM(vpdMap); | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 472 |  | 
| Alpana Kumari | 1b02611 | 2022-03-02 23:41:38 -0600 | [diff] [blame] | 473 |         transform(hwKeyword.begin(), hwKeyword.end(), hwKeyword.begin(), | 
 | 474 |                   ::toupper); | 
 | 475 |  | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 476 |         if (js.find("system") == js.end()) | 
 | 477 |         { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 478 |             throw std::runtime_error("Invalid systems Json"); | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 479 |         } | 
 | 480 |  | 
 | 481 |         if (js["system"].find(imKeyword) == js["system"].end()) | 
 | 482 |         { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 483 |             throw std::runtime_error( | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 484 |                 "Invalid system. This system type is not present " | 
 | 485 |                 "in the systemsJson. IM: " + | 
 | 486 |                 imKeyword); | 
 | 487 |         } | 
 | 488 |  | 
 | 489 |         if ((js["system"][imKeyword].find("constraint") != | 
 | 490 |              js["system"][imKeyword].end()) && | 
| Alpana Kumari | 1b02611 | 2022-03-02 23:41:38 -0600 | [diff] [blame] | 491 |             js["system"][imKeyword]["constraint"].find("HW") != | 
 | 492 |                 js["system"][imKeyword]["constraint"].end()) | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 493 |         { | 
| Alpana Kumari | 1b02611 | 2022-03-02 23:41:38 -0600 | [diff] [blame] | 494 |             // collect hw versions from json, and check hwKeyword  is part of it | 
 | 495 |             // if hwKeyword is found there then load respective json | 
 | 496 |             // otherwise load default one. | 
 | 497 |             for (const auto& hwVersion : | 
 | 498 |                  js["system"][imKeyword]["constraint"]["HW"]) | 
 | 499 |             { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 500 |                 std::string hw = hwVersion; | 
| Alpana Kumari | 1b02611 | 2022-03-02 23:41:38 -0600 | [diff] [blame] | 501 |                 transform(hw.begin(), hw.end(), hw.begin(), ::toupper); | 
 | 502 |  | 
 | 503 |                 if (hw == hwKeyword) | 
 | 504 |                 { | 
 | 505 |                     jsonName = js["system"][imKeyword]["constraint"]["json"]; | 
 | 506 |                     break; | 
 | 507 |                 } | 
 | 508 |             } | 
 | 509 |  | 
 | 510 |             if (jsonName.empty() && js["system"][imKeyword].find("default") != | 
 | 511 |                                         js["system"][imKeyword].end()) | 
 | 512 |             { | 
 | 513 |                 jsonName = js["system"][imKeyword]["default"]; | 
 | 514 |             } | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 515 |         } | 
 | 516 |         else if (js["system"][imKeyword].find("default") != | 
 | 517 |                  js["system"][imKeyword].end()) | 
 | 518 |         { | 
 | 519 |             jsonName = js["system"][imKeyword]["default"]; | 
 | 520 |         } | 
 | 521 |         else | 
 | 522 |         { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 523 |             throw std::runtime_error( | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 524 |                 "Bad System json. Neither constraint nor default found"); | 
 | 525 |         } | 
 | 526 |  | 
 | 527 |         jsonPath += jsonName; | 
 | 528 |     } | 
 | 529 |  | 
| Patrick Williams | 8e15b93 | 2021-10-06 13:04:22 -0500 | [diff] [blame] | 530 |     catch (const json::parse_error& ex) | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 531 |     { | 
 | 532 |         throw(VpdJsonException("Json Parsing failed", SYSTEM_JSON)); | 
 | 533 |     } | 
 | 534 |     return jsonPath; | 
 | 535 | } | 
 | 536 |  | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 537 | void udevToGenericPath(std::string& file, const std::string& driver) | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 538 | { | 
 | 539 |     // Sample udevEvent i2c path : | 
 | 540 |     // "/sys/devices/platform/ahb/ahb:apb/ahb:apb:bus@1e78a000/1e78a480.i2c-bus/i2c-8/8-0051/8-00510/nvmem" | 
 | 541 |     // find if the path contains the word i2c in it. | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 542 |     if (file.find("i2c") != std::string::npos) | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 543 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 544 |         std::string i2cBusAddr{}; | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 545 |  | 
 | 546 |         // Every udev i2c path should have the common pattern | 
 | 547 |         // "i2c-bus_number/bus_number-vpd_address". Search for | 
 | 548 |         // "bus_number-vpd_address". | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 549 |         std::regex i2cPattern("((i2c)-[0-9]+\\/)([0-9]+-[0-9]{4})"); | 
 | 550 |         std::smatch match; | 
 | 551 |         if (std::regex_search(file, match, i2cPattern)) | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 552 |         { | 
 | 553 |             i2cBusAddr = match.str(3); | 
 | 554 |         } | 
 | 555 |         else | 
 | 556 |         { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 557 |             std::cerr << "The given udev path < " << file | 
 | 558 |                       << " > doesn't match the required pattern. Skipping VPD " | 
 | 559 |                          "collection." | 
 | 560 |                       << std::endl; | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 561 |             exit(EXIT_SUCCESS); | 
 | 562 |         } | 
 | 563 |         // Forming the generic file path | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 564 |         file = i2cPathPrefix + driver + "/" + i2cBusAddr + "/eeprom"; | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 565 |     } | 
 | 566 |     // Sample udevEvent spi path : | 
 | 567 |     // "/sys/devices/platform/ahb/ahb:apb/1e79b000.fsi/fsi-master/fsi0/slave@00:00/00:00:00:04/spi_master/spi2/spi2.0/spi2.00/nvmem" | 
 | 568 |     // find if the path contains the word spi in it. | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 569 |     else if (file.find("spi") != std::string::npos) | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 570 |     { | 
 | 571 |         // Every udev spi path will have common pattern "spi<Digit>/", which | 
 | 572 |         // describes the spi bus number at which the fru is connected; Followed | 
 | 573 |         // by a slash following the vpd address of the fru. Taking the above | 
 | 574 |         // input as a common key, we try to search for the pattern "spi<Digit>/" | 
 | 575 |         // using regular expression. | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 576 |         std::regex spiPattern("((spi)[0-9]+)(\\/)"); | 
 | 577 |         std::string spiBus{}; | 
 | 578 |         std::smatch match; | 
 | 579 |         if (std::regex_search(file, match, spiPattern)) | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 580 |         { | 
 | 581 |             spiBus = match.str(1); | 
 | 582 |         } | 
 | 583 |         else | 
 | 584 |         { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 585 |             std::cerr << "The given udev path < " << file | 
 | 586 |                       << " > doesn't match the required pattern. Skipping VPD " | 
 | 587 |                          "collection." | 
 | 588 |                       << std::endl; | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 589 |             exit(EXIT_SUCCESS); | 
 | 590 |         } | 
 | 591 |         // Forming the generic path | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 592 |         file = spiPathPrefix + driver + "/" + spiBus + ".0/eeprom"; | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 593 |     } | 
 | 594 |     else | 
 | 595 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 596 |         std::cerr << "\n The given EEPROM path < " << file | 
 | 597 |                   << " > is not valid. It's neither I2C nor " | 
 | 598 |                      "SPI path. Skipping VPD collection.." | 
 | 599 |                   << std::endl; | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 600 |         exit(EXIT_SUCCESS); | 
 | 601 |     } | 
 | 602 | } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 603 | std::string getBadVpdName(const std::string& file) | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 604 | { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 605 |     std::string badVpd = BAD_VPD_DIR; | 
 | 606 |     if (file.find("i2c") != std::string::npos) | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 607 |     { | 
 | 608 |         badVpd += "i2c-"; | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 609 |         std::regex i2cPattern("(at24/)([0-9]+-[0-9]+)\\/"); | 
 | 610 |         std::smatch match; | 
 | 611 |         if (std::regex_search(file, match, i2cPattern)) | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 612 |         { | 
 | 613 |             badVpd += match.str(2); | 
 | 614 |         } | 
 | 615 |     } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 616 |     else if (file.find("spi") != std::string::npos) | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 617 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 618 |         std::regex spiPattern("((spi)[0-9]+)(.0)"); | 
 | 619 |         std::smatch match; | 
 | 620 |         if (std::regex_search(file, match, spiPattern)) | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 621 |         { | 
 | 622 |             badVpd += match.str(1); | 
 | 623 |         } | 
 | 624 |     } | 
 | 625 |     return badVpd; | 
 | 626 | } | 
 | 627 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 628 | void dumpBadVpd(const std::string& file, const Binary& vpdVector) | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 629 | { | 
 | 630 |     fs::path badVpdDir = BAD_VPD_DIR; | 
 | 631 |     fs::create_directory(badVpdDir); | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 632 |     std::string badVpdPath = getBadVpdName(file); | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 633 |     if (fs::exists(badVpdPath)) | 
 | 634 |     { | 
 | 635 |         std::error_code ec; | 
 | 636 |         fs::remove(badVpdPath, ec); | 
 | 637 |         if (ec) // error code | 
 | 638 |         { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 639 |             std::string error = "Error removing the existing broken vpd in "; | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 640 |             error += badVpdPath; | 
 | 641 |             error += ". Error code : "; | 
 | 642 |             error += ec.value(); | 
 | 643 |             error += ". Error message : "; | 
 | 644 |             error += ec.message(); | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 645 |             throw std::runtime_error(error); | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 646 |         } | 
 | 647 |     } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 648 |     std::ofstream badVpdFileStream(badVpdPath, std::ofstream::binary); | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 649 |     if (!badVpdFileStream) | 
 | 650 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 651 |         throw std::runtime_error( | 
 | 652 |             "Failed to open bad vpd file path in /tmp/bad-vpd. " | 
 | 653 |             "Unable to dump the broken/bad vpd file."); | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 654 |     } | 
 | 655 |     badVpdFileStream.write(reinterpret_cast<const char*>(vpdVector.data()), | 
 | 656 |                            vpdVector.size()); | 
 | 657 | } | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 658 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 659 | const std::string getKwVal(const Parsed& vpdMap, const std::string& rec, | 
 | 660 |                            const std::string& kwd) | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 661 | { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 662 |     std::string kwVal{}; | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 663 |  | 
 | 664 |     auto findRec = vpdMap.find(rec); | 
 | 665 |  | 
 | 666 |     // check if record is found in map we got by parser | 
 | 667 |     if (findRec != vpdMap.end()) | 
 | 668 |     { | 
 | 669 |         auto findKwd = findRec->second.find(kwd); | 
 | 670 |  | 
 | 671 |         if (findKwd != findRec->second.end()) | 
 | 672 |         { | 
 | 673 |             kwVal = findKwd->second; | 
 | 674 |         } | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 675 |         else | 
 | 676 |         { | 
 | 677 |             std::cout << "Keyword not found" << std::endl; | 
 | 678 |         } | 
 | 679 |     } | 
 | 680 |     else | 
 | 681 |     { | 
 | 682 |         std::cerr << "Record not found" << std::endl; | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 683 |     } | 
 | 684 |  | 
 | 685 |     return kwVal; | 
 | 686 | } | 
 | 687 |  | 
| GiridhariKrishnan | 6363910 | 2023-03-02 05:55:47 -0600 | [diff] [blame] | 688 | std::string hexString(const std::variant<Binary, std::string>& kw) | 
| Priyanga Ramasamy | c9ecf8e | 2021-10-08 02:28:52 -0500 | [diff] [blame] | 689 | { | 
| GiridhariKrishnan | 6363910 | 2023-03-02 05:55:47 -0600 | [diff] [blame] | 690 |     std::string hexString; | 
 | 691 |     std::visit( | 
 | 692 |         [&hexString](auto&& kw) { | 
| Patrick Williams | c78d887 | 2023-05-10 07:50:56 -0500 | [diff] [blame] | 693 |         std::stringstream ss; | 
 | 694 |         std::string hexRep = "0x"; | 
 | 695 |         ss << hexRep; | 
 | 696 |         for (auto& kwVal : kw) | 
 | 697 |         { | 
 | 698 |             ss << std::setfill('0') << std::setw(2) << std::hex | 
 | 699 |                << static_cast<int>(kwVal); | 
 | 700 |         } | 
 | 701 |         hexString = ss.str(); | 
| GiridhariKrishnan | 6363910 | 2023-03-02 05:55:47 -0600 | [diff] [blame] | 702 |         }, | 
 | 703 |         kw); | 
 | 704 |     return hexString; | 
| Priyanga Ramasamy | c9ecf8e | 2021-10-08 02:28:52 -0500 | [diff] [blame] | 705 | } | 
 | 706 |  | 
| GiridhariKrishnan | 6363910 | 2023-03-02 05:55:47 -0600 | [diff] [blame] | 707 | std::string getPrintableValue(const std::variant<Binary, std::string>& kwVal) | 
| Priyanga Ramasamy | 0243493 | 2021-10-07 16:26:05 -0500 | [diff] [blame] | 708 | { | 
| GiridhariKrishnan | 6363910 | 2023-03-02 05:55:47 -0600 | [diff] [blame] | 709 |     std::string kwString{}; | 
 | 710 |     std::visit( | 
 | 711 |         [&kwString](auto&& kwVal) { | 
| Patrick Williams | c78d887 | 2023-05-10 07:50:56 -0500 | [diff] [blame] | 712 |         const auto it = | 
 | 713 |             std::find_if(kwVal.begin(), kwVal.end(), | 
 | 714 |                          [](const auto& kw) { return !isprint(kw); }); | 
 | 715 |         if (it != kwVal.end()) | 
 | 716 |         { | 
| girik | 390fccb | 2023-05-02 07:42:47 -0500 | [diff] [blame] | 717 |             kwString = hexString(kwVal); | 
| Patrick Williams | c78d887 | 2023-05-10 07:50:56 -0500 | [diff] [blame] | 718 |         } | 
 | 719 |         else | 
 | 720 |         { | 
 | 721 |             kwString = std::string(kwVal.begin(), kwVal.end()); | 
 | 722 |         } | 
| GiridhariKrishnan | 6363910 | 2023-03-02 05:55:47 -0600 | [diff] [blame] | 723 |         }, | 
 | 724 |         kwVal); | 
 | 725 |     return kwString; | 
| Priyanga Ramasamy | 0243493 | 2021-10-07 16:26:05 -0500 | [diff] [blame] | 726 | } | 
 | 727 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 728 | void executePostFailAction(const nlohmann::json& json, const std::string& file) | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 729 | { | 
 | 730 |     if ((json["frus"][file].at(0)).find("postActionFail") == | 
 | 731 |         json["frus"][file].at(0).end()) | 
 | 732 |     { | 
 | 733 |         return; | 
 | 734 |     } | 
 | 735 |  | 
 | 736 |     uint8_t pinValue = 0; | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 737 |     std::string pinName; | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 738 |  | 
 | 739 |     for (const auto& postAction : | 
 | 740 |          (json["frus"][file].at(0))["postActionFail"].items()) | 
 | 741 |     { | 
 | 742 |         if (postAction.key() == "pin") | 
 | 743 |         { | 
 | 744 |             pinName = postAction.value(); | 
 | 745 |         } | 
 | 746 |         else if (postAction.key() == "value") | 
 | 747 |         { | 
 | 748 |             // Get the value to set | 
 | 749 |             pinValue = postAction.value(); | 
 | 750 |         } | 
 | 751 |     } | 
 | 752 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 753 |     std::cout << "Setting GPIO: " << pinName << " to " << (int)pinValue | 
 | 754 |               << std::endl; | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 755 |  | 
 | 756 |     try | 
 | 757 |     { | 
 | 758 |         gpiod::line outputLine = gpiod::find_line(pinName); | 
 | 759 |  | 
 | 760 |         if (!outputLine) | 
 | 761 |         { | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 762 |             throw GpioException( | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 763 |                 "Couldn't find output line for the GPIO. Skipping " | 
 | 764 |                 "this GPIO action."); | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 765 |         } | 
 | 766 |         outputLine.request( | 
 | 767 |             {"Disable line", ::gpiod::line_request::DIRECTION_OUTPUT, 0}, | 
 | 768 |             pinValue); | 
 | 769 |     } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 770 |     catch (const std::exception& e) | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 771 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 772 |         std::string i2cBusAddr; | 
 | 773 |         std::string errMsg = e.what(); | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 774 |         errMsg += "\nGPIO: " + pinName; | 
 | 775 |  | 
 | 776 |         if ((json["frus"][file].at(0)["postActionFail"].find( | 
 | 777 |                 "gpioI2CAddress")) != | 
 | 778 |             json["frus"][file].at(0)["postActionFail"].end()) | 
 | 779 |         { | 
 | 780 |             i2cBusAddr = | 
 | 781 |                 json["frus"][file].at(0)["postActionFail"]["gpioI2CAddress"]; | 
| Sunny Srivastava | fdf9ff2 | 2022-06-15 11:15:54 -0500 | [diff] [blame] | 782 |             errMsg += " i2cBusAddress: " + i2cBusAddr; | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 783 |         } | 
 | 784 |  | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 785 |         throw GpioException(e.what()); | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 786 |     } | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 787 |  | 
 | 788 |     return; | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 789 | } | 
 | 790 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 791 | std::optional<bool> isPresent(const nlohmann::json& json, | 
 | 792 |                               const std::string& file) | 
| Santosh Puranik | 53b38ed | 2022-04-10 23:15:22 +0530 | [diff] [blame] | 793 |  | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 794 | { | 
 | 795 |     if ((json["frus"][file].at(0)).find("presence") != | 
 | 796 |         json["frus"][file].at(0).end()) | 
 | 797 |     { | 
 | 798 |         if (((json["frus"][file].at(0)["presence"]).find("pin") != | 
 | 799 |              json["frus"][file].at(0)["presence"].end()) && | 
 | 800 |             ((json["frus"][file].at(0)["presence"]).find("value") != | 
 | 801 |              json["frus"][file].at(0)["presence"].end())) | 
 | 802 |         { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 803 |             std::string presPinName = | 
 | 804 |                 json["frus"][file].at(0)["presence"]["pin"]; | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 805 |             Byte presPinValue = json["frus"][file].at(0)["presence"]["value"]; | 
 | 806 |  | 
 | 807 |             try | 
 | 808 |             { | 
 | 809 |                 gpiod::line presenceLine = gpiod::find_line(presPinName); | 
 | 810 |  | 
 | 811 |                 if (!presenceLine) | 
 | 812 |                 { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 813 |                     std::cerr << "Couldn't find the presence line for - " | 
 | 814 |                               << presPinName << std::endl; | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 815 |  | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 816 |                     throw GpioException( | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 817 |                         "Couldn't find the presence line for the " | 
 | 818 |                         "GPIO. Skipping this GPIO action."); | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 819 |                 } | 
 | 820 |  | 
 | 821 |                 presenceLine.request({"Read the presence line", | 
 | 822 |                                       gpiod::line_request::DIRECTION_INPUT, 0}); | 
 | 823 |  | 
 | 824 |                 Byte gpioData = presenceLine.get_value(); | 
 | 825 |  | 
| Santosh Puranik | 53b38ed | 2022-04-10 23:15:22 +0530 | [diff] [blame] | 826 |                 return (gpioData == presPinValue); | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 827 |             } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 828 |             catch (const std::exception& e) | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 829 |             { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 830 |                 std::string i2cBusAddr; | 
 | 831 |                 std::string errMsg = e.what(); | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 832 |                 errMsg += " GPIO : " + presPinName; | 
 | 833 |  | 
 | 834 |                 if ((json["frus"][file].at(0)["presence"]) | 
 | 835 |                         .find("gpioI2CAddress") != | 
 | 836 |                     json["frus"][file].at(0)["presence"].end()) | 
 | 837 |                 { | 
 | 838 |                     i2cBusAddr = | 
 | 839 |                         json["frus"][file].at(0)["presence"]["gpioI2CAddress"]; | 
| Sunny Srivastava | fdf9ff2 | 2022-06-15 11:15:54 -0500 | [diff] [blame] | 840 |                     errMsg += " i2cBusAddress: " + i2cBusAddr; | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 841 |                 } | 
 | 842 |  | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 843 |                 // Take failure postAction | 
 | 844 |                 executePostFailAction(json, file); | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 845 |                 throw GpioException(errMsg); | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 846 |             } | 
 | 847 |         } | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 848 |         else | 
 | 849 |         { | 
 | 850 |             // missing required informations | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 851 |             std::cerr | 
 | 852 |                 << "VPD inventory JSON missing basic informations of presence " | 
 | 853 |                    "for this FRU : [" | 
 | 854 |                 << file << "]. Executing executePostFailAction." << std::endl; | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 855 |  | 
 | 856 |             // Take failure postAction | 
 | 857 |             executePostFailAction(json, file); | 
 | 858 |  | 
 | 859 |             return false; | 
 | 860 |         } | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 861 |     } | 
| Santosh Puranik | 53b38ed | 2022-04-10 23:15:22 +0530 | [diff] [blame] | 862 |     return std::optional<bool>{}; | 
 | 863 | } | 
 | 864 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 865 | bool executePreAction(const nlohmann::json& json, const std::string& file) | 
| Santosh Puranik | 53b38ed | 2022-04-10 23:15:22 +0530 | [diff] [blame] | 866 | { | 
 | 867 |     auto present = isPresent(json, file); | 
 | 868 |     if (present && !present.value()) | 
 | 869 |     { | 
 | 870 |         executePostFailAction(json, file); | 
 | 871 |         return false; | 
 | 872 |     } | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 873 |  | 
 | 874 |     if ((json["frus"][file].at(0)).find("preAction") != | 
 | 875 |         json["frus"][file].at(0).end()) | 
 | 876 |     { | 
 | 877 |         if (((json["frus"][file].at(0)["preAction"]).find("pin") != | 
 | 878 |              json["frus"][file].at(0)["preAction"].end()) && | 
 | 879 |             ((json["frus"][file].at(0)["preAction"]).find("value") != | 
 | 880 |              json["frus"][file].at(0)["preAction"].end())) | 
 | 881 |         { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 882 |             std::string pinName = json["frus"][file].at(0)["preAction"]["pin"]; | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 883 |             // Get the value to set | 
 | 884 |             Byte pinValue = json["frus"][file].at(0)["preAction"]["value"]; | 
 | 885 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 886 |             std::cout << "Setting GPIO: " << pinName << " to " << (int)pinValue | 
 | 887 |                       << std::endl; | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 888 |             try | 
 | 889 |             { | 
 | 890 |                 gpiod::line outputLine = gpiod::find_line(pinName); | 
 | 891 |  | 
 | 892 |                 if (!outputLine) | 
 | 893 |                 { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 894 |                     std::cerr << "Couldn't find the line for output pin - " | 
 | 895 |                               << pinName << std::endl; | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 896 |                     throw GpioException( | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 897 |                         "Couldn't find output line for the GPIO. " | 
 | 898 |                         "Skipping this GPIO action."); | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 899 |                 } | 
 | 900 |                 outputLine.request({"FRU pre-action", | 
 | 901 |                                     ::gpiod::line_request::DIRECTION_OUTPUT, 0}, | 
 | 902 |                                    pinValue); | 
 | 903 |             } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 904 |             catch (const std::exception& e) | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 905 |             { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 906 |                 std::string i2cBusAddr; | 
 | 907 |                 std::string errMsg = e.what(); | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 908 |                 errMsg += " GPIO : " + pinName; | 
 | 909 |  | 
 | 910 |                 if ((json["frus"][file].at(0)["preAction"]) | 
 | 911 |                         .find("gpioI2CAddress") != | 
 | 912 |                     json["frus"][file].at(0)["preAction"].end()) | 
 | 913 |                 { | 
 | 914 |                     i2cBusAddr = | 
 | 915 |                         json["frus"][file].at(0)["preAction"]["gpioI2CAddress"]; | 
| Sunny Srivastava | fdf9ff2 | 2022-06-15 11:15:54 -0500 | [diff] [blame] | 916 |                     errMsg += " i2cBusAddress: " + i2cBusAddr; | 
| Alpana Kumari | 6bd095f | 2022-02-23 10:20:20 -0600 | [diff] [blame] | 917 |                 } | 
 | 918 |  | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 919 |                 // Take failure postAction | 
 | 920 |                 executePostFailAction(json, file); | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 921 |                 throw GpioException(errMsg); | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 922 |             } | 
 | 923 |         } | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 924 |         else | 
 | 925 |         { | 
 | 926 |             // missing required informations | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 927 |             std::cerr | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 928 |                 << "VPD inventory JSON missing basic informations of preAction " | 
 | 929 |                    "for this FRU : [" | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 930 |                 << file << "]. Executing executePostFailAction." << std::endl; | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 931 |  | 
 | 932 |             // Take failure postAction | 
 | 933 |             executePostFailAction(json, file); | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 934 |             return false; | 
 | 935 |         } | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 936 |     } | 
 | 937 |     return true; | 
 | 938 | } | 
 | 939 |  | 
| Priyanga Ramasamy | aa8a893 | 2022-01-27 09:12:41 -0600 | [diff] [blame] | 940 | void insertOrMerge(inventory::InterfaceMap& map, | 
 | 941 |                    const inventory::Interface& interface, | 
 | 942 |                    inventory::PropertyMap&& property) | 
 | 943 | { | 
 | 944 |     if (map.find(interface) != map.end()) | 
 | 945 |     { | 
 | 946 |         auto& prop = map.at(interface); | 
 | 947 |         prop.insert(property.begin(), property.end()); | 
 | 948 |     } | 
 | 949 |     else | 
 | 950 |     { | 
 | 951 |         map.emplace(interface, property); | 
 | 952 |     } | 
 | 953 | } | 
| Santosh Puranik | f2d3b53 | 2022-04-19 06:44:07 -0500 | [diff] [blame] | 954 |  | 
 | 955 | BIOSAttrValueType readBIOSAttribute(const std::string& attrName) | 
 | 956 | { | 
 | 957 |     std::tuple<std::string, BIOSAttrValueType, BIOSAttrValueType> attrVal; | 
 | 958 |     auto bus = sdbusplus::bus::new_default(); | 
 | 959 |     auto method = bus.new_method_call( | 
 | 960 |         "xyz.openbmc_project.BIOSConfigManager", | 
 | 961 |         "/xyz/openbmc_project/bios_config/manager", | 
 | 962 |         "xyz.openbmc_project.BIOSConfig.Manager", "GetAttribute"); | 
 | 963 |     method.append(attrName); | 
 | 964 |     try | 
 | 965 |     { | 
 | 966 |         auto result = bus.call(method); | 
 | 967 |         result.read(std::get<0>(attrVal), std::get<1>(attrVal), | 
 | 968 |                     std::get<2>(attrVal)); | 
 | 969 |     } | 
 | 970 |     catch (const sdbusplus::exception::SdBusError& e) | 
 | 971 |     { | 
 | 972 |         std::cerr << "Failed to read BIOS Attribute: " << attrName << std::endl; | 
 | 973 |         std::cerr << e.what() << std::endl; | 
 | 974 |     } | 
 | 975 |     return std::get<1>(attrVal); | 
 | 976 | } | 
| Priyanga Ramasamy | 335873f | 2022-05-18 01:31:54 -0500 | [diff] [blame] | 977 |  | 
 | 978 | std::string getPowerState() | 
 | 979 | { | 
 | 980 |     // TODO: How do we handle multiple chassis? | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 981 |     std::string powerState{}; | 
| Priyanga Ramasamy | 335873f | 2022-05-18 01:31:54 -0500 | [diff] [blame] | 982 |     auto bus = sdbusplus::bus::new_default(); | 
| Patrick Williams | c78d887 | 2023-05-10 07:50:56 -0500 | [diff] [blame] | 983 |     auto properties = bus.new_method_call("xyz.openbmc_project.State.Chassis", | 
 | 984 |                                           "/xyz/openbmc_project/state/chassis0", | 
 | 985 |                                           "org.freedesktop.DBus.Properties", | 
 | 986 |                                           "Get"); | 
| Priyanga Ramasamy | 335873f | 2022-05-18 01:31:54 -0500 | [diff] [blame] | 987 |     properties.append("xyz.openbmc_project.State.Chassis"); | 
 | 988 |     properties.append("CurrentPowerState"); | 
 | 989 |     auto result = bus.call(properties); | 
 | 990 |     if (!result.is_method_error()) | 
 | 991 |     { | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 992 |         std::variant<std::string> val; | 
| Priyanga Ramasamy | 335873f | 2022-05-18 01:31:54 -0500 | [diff] [blame] | 993 |         result.read(val); | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 994 |         if (auto pVal = std::get_if<std::string>(&val)) | 
| Priyanga Ramasamy | 335873f | 2022-05-18 01:31:54 -0500 | [diff] [blame] | 995 |         { | 
 | 996 |             powerState = *pVal; | 
 | 997 |         } | 
 | 998 |     } | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 999 |     std::cout << "Power state is: " << powerState << std::endl; | 
| Priyanga Ramasamy | 335873f | 2022-05-18 01:31:54 -0500 | [diff] [blame] | 1000 |     return powerState; | 
 | 1001 | } | 
| Santosh Puranik | 6b2b537 | 2022-06-02 20:49:02 +0530 | [diff] [blame] | 1002 |  | 
 | 1003 | Binary getVpdDataInVector(const nlohmann::json& js, const std::string& file) | 
 | 1004 | { | 
 | 1005 |     uint32_t offset = 0; | 
 | 1006 |     // check if offset present? | 
 | 1007 |     for (const auto& item : js["frus"][file]) | 
 | 1008 |     { | 
 | 1009 |         if (item.find("offset") != item.end()) | 
 | 1010 |         { | 
 | 1011 |             offset = item["offset"]; | 
 | 1012 |         } | 
 | 1013 |     } | 
 | 1014 |  | 
 | 1015 |     // TODO: Figure out a better way to get max possible VPD size. | 
 | 1016 |     auto maxVPDSize = std::min(std::filesystem::file_size(file), | 
 | 1017 |                                static_cast<uintmax_t>(65504)); | 
 | 1018 |  | 
 | 1019 |     Binary vpdVector; | 
 | 1020 |     vpdVector.resize(maxVPDSize); | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 1021 |     std::ifstream vpdFile; | 
 | 1022 |     vpdFile.open(file, std::ios::binary); | 
| Santosh Puranik | 6b2b537 | 2022-06-02 20:49:02 +0530 | [diff] [blame] | 1023 |  | 
| Priyanga Ramasamy | e008432 | 2022-09-27 06:28:33 -0500 | [diff] [blame] | 1024 |     vpdFile.seekg(offset, std::ios_base::cur); | 
| Santosh Puranik | 6b2b537 | 2022-06-02 20:49:02 +0530 | [diff] [blame] | 1025 |     vpdFile.read(reinterpret_cast<char*>(&vpdVector[0]), maxVPDSize); | 
 | 1026 |     vpdVector.resize(vpdFile.gcount()); | 
 | 1027 |  | 
 | 1028 |     // Make sure we reset the EEPROM pointer to a "safe" location if it was DIMM | 
 | 1029 |     // SPD that we just read. | 
 | 1030 |     for (const auto& item : js["frus"][file]) | 
 | 1031 |     { | 
 | 1032 |         if (item.find("extraInterfaces") != item.end()) | 
 | 1033 |         { | 
 | 1034 |             if (item["extraInterfaces"].find( | 
 | 1035 |                     "xyz.openbmc_project.Inventory.Item.Dimm") != | 
 | 1036 |                 item["extraInterfaces"].end()) | 
 | 1037 |             { | 
 | 1038 |                 // moves the EEPROM pointer to 2048 'th byte. | 
 | 1039 |                 vpdFile.seekg(2047, std::ios::beg); | 
 | 1040 |                 // Read that byte and discard - to affirm the move | 
 | 1041 |                 // operation. | 
 | 1042 |                 char ch; | 
 | 1043 |                 vpdFile.read(&ch, sizeof(ch)); | 
 | 1044 |                 break; | 
 | 1045 |             } | 
 | 1046 |         } | 
 | 1047 |     } | 
 | 1048 |  | 
 | 1049 |     return vpdVector; | 
 | 1050 | } | 
| Priyanga Ramasamy | 5629fbc | 2023-03-01 08:17:19 -0600 | [diff] [blame] | 1051 |  | 
 | 1052 | std::string getDbusNameForThisKw(const std::string& keyword) | 
 | 1053 | { | 
 | 1054 |     if (keyword[0] == constants::POUND_KW) | 
 | 1055 |     { | 
 | 1056 |         return (std::string(constants::POUND_KW_PREFIX) + keyword[1]); | 
 | 1057 |     } | 
 | 1058 |     else if (isdigit(keyword[0])) | 
 | 1059 |     { | 
 | 1060 |         return (std::string(constants::NUMERIC_KW_PREFIX) + keyword); | 
 | 1061 |     } | 
 | 1062 |     return keyword; | 
 | 1063 | } | 
 | 1064 |  | 
| Patrick Venture | c83c4dc | 2018-11-01 16:29:18 -0700 | [diff] [blame] | 1065 | } // namespace vpd | 
| Patrick Williams | c78d887 | 2023-05-10 07:50:56 -0500 | [diff] [blame] | 1066 | } // namespace openpower |