xref: /openbmc/google-ipmi-sys/util.cpp (revision 8d6185322d2631b9ecceeb0ceb95c03d1f98f27f)
1a2056e9cSWilly Tu // Copyright 2021 Google LLC
2a2056e9cSWilly Tu //
3a2056e9cSWilly Tu // Licensed under the Apache License, Version 2.0 (the "License");
4a2056e9cSWilly Tu // you may not use this file except in compliance with the License.
5a2056e9cSWilly Tu // You may obtain a copy of the License at
6a2056e9cSWilly Tu //
7a2056e9cSWilly Tu //      http://www.apache.org/licenses/LICENSE-2.0
8a2056e9cSWilly Tu //
9a2056e9cSWilly Tu // Unless required by applicable law or agreed to in writing, software
10a2056e9cSWilly Tu // distributed under the License is distributed on an "AS IS" BASIS,
11a2056e9cSWilly Tu // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a2056e9cSWilly Tu // See the License for the specific language governing permissions and
13a2056e9cSWilly Tu // limitations under the License.
14a2056e9cSWilly Tu 
15ab650004SPatrick Venture #include "util.hpp"
16ab650004SPatrick Venture 
17444b5ea4SPatrick Williams #include <nlohmann/json.hpp>
18444b5ea4SPatrick Williams #include <phosphor-logging/elog-errors.hpp>
19*8d618532SMichael Shen #include <stdplus/print.hpp>
20444b5ea4SPatrick Williams #include <xyz/openbmc_project/Common/error.hpp>
21444b5ea4SPatrick Williams 
223fb74294SPatrick Venture #include <cstdint>
238d5c9cecSPatrick Venture #include <cstdio>
243fb74294SPatrick Venture #include <filesystem>
25ab650004SPatrick Venture #include <fstream>
263fb74294SPatrick Venture #include <regex>
27ab650004SPatrick Venture #include <string>
283fb74294SPatrick Venture #include <tuple>
293fb74294SPatrick Venture #include <vector>
30ab650004SPatrick Venture 
31ab650004SPatrick Venture namespace google
32ab650004SPatrick Venture {
33ab650004SPatrick Venture namespace ipmi
34ab650004SPatrick Venture {
353fb74294SPatrick Venture namespace fs = std::filesystem;
36ab650004SPatrick Venture using namespace phosphor::logging;
37ab650004SPatrick Venture using InternalFailure =
38ab650004SPatrick Venture     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
39ab650004SPatrick Venture 
parseConfig(const std::string & file)40ab650004SPatrick Venture nlohmann::json parseConfig(const std::string& file)
41ab650004SPatrick Venture {
42ab650004SPatrick Venture     std::ifstream jsonFile(file);
43ab650004SPatrick Venture     if (!jsonFile.is_open())
44ab650004SPatrick Venture     {
45ab650004SPatrick Venture         log<level::ERR>("Entity association JSON file not found");
46ab650004SPatrick Venture         elog<InternalFailure>();
47ab650004SPatrick Venture     }
48ab650004SPatrick Venture 
49ab650004SPatrick Venture     auto data = nlohmann::json::parse(jsonFile, nullptr, false);
50ab650004SPatrick Venture     if (data.is_discarded())
51ab650004SPatrick Venture     {
52ab650004SPatrick Venture         log<level::ERR>("Entity association JSON parser failure");
53ab650004SPatrick Venture         elog<InternalFailure>();
54ab650004SPatrick Venture     }
55ab650004SPatrick Venture 
56ab650004SPatrick Venture     return data;
57ab650004SPatrick Venture }
58ab650004SPatrick Venture 
readPropertyFile(const std::string & fileName)598d5c9cecSPatrick Venture std::string readPropertyFile(const std::string& fileName)
608d5c9cecSPatrick Venture {
618d5c9cecSPatrick Venture     std::ifstream ifs(fileName);
628d5c9cecSPatrick Venture     std::string contents;
638d5c9cecSPatrick Venture 
648d5c9cecSPatrick Venture     if (!ifs.is_open())
658d5c9cecSPatrick Venture     {
668659851cSYunyun Lin         auto msg = std::string("Unable to open file ") + fileName.c_str();
678659851cSYunyun Lin         log<level::DEBUG>(msg.c_str());
688d5c9cecSPatrick Venture     }
698d5c9cecSPatrick Venture     else
708d5c9cecSPatrick Venture     {
718d5c9cecSPatrick Venture         if (ifs >> contents)
728d5c9cecSPatrick Venture         {
738d5c9cecSPatrick Venture             // If the last character is a null terminator; remove it.
748d5c9cecSPatrick Venture             if (!contents.empty())
758d5c9cecSPatrick Venture             {
76444b5ea4SPatrick Williams                 const char& back = contents.back();
778d5c9cecSPatrick Venture                 if (back == '\0')
788d5c9cecSPatrick Venture                     contents.pop_back();
798d5c9cecSPatrick Venture             }
808d5c9cecSPatrick Venture 
818d5c9cecSPatrick Venture             return contents;
828d5c9cecSPatrick Venture         }
838d5c9cecSPatrick Venture         else
848d5c9cecSPatrick Venture         {
85*8d618532SMichael Shen             stdplus::print(stderr, "Unable to read file {}.\n", fileName);
868d5c9cecSPatrick Venture         }
878d5c9cecSPatrick Venture     }
888d5c9cecSPatrick Venture 
898d5c9cecSPatrick Venture     return "";
908d5c9cecSPatrick Venture }
918d5c9cecSPatrick Venture 
buildPcieMap()923fb74294SPatrick Venture std::vector<std::tuple<std::uint32_t, std::string>> buildPcieMap()
933fb74294SPatrick Venture {
943fb74294SPatrick Venture     std::vector<std::tuple<std::uint32_t, std::string>> pcie_i2c_map;
953fb74294SPatrick Venture 
963fb74294SPatrick Venture     // Build a vector with i2c bus to pcie slot mapping.
973fb74294SPatrick Venture     // Iterate through all the devices under "/sys/bus/i2c/devices".
983fb74294SPatrick Venture     for (const auto& i2c_dev : fs::directory_iterator("/sys/bus/i2c/devices"))
993fb74294SPatrick Venture     {
1003fb74294SPatrick Venture         std::string i2c_dev_path = i2c_dev.path();
1013fb74294SPatrick Venture         std::smatch i2c_dev_string_number;
1023fb74294SPatrick Venture         std::regex e("(i2c-)(\\d+)");
1033fb74294SPatrick Venture 
1043fb74294SPatrick Venture         // Check if the device has "i2c-" in its path.
1053fb74294SPatrick Venture         if (std::regex_search(i2c_dev_path, i2c_dev_string_number, e))
1063fb74294SPatrick Venture         {
1073fb74294SPatrick Venture             // Check if the i2c device has "pcie-slot" file under "of-node" dir.
1083fb74294SPatrick Venture             std::string pcie_slot_path = i2c_dev_path + "/of_node/pcie-slot";
1093fb74294SPatrick Venture             std::string pcie_slot;
1103fb74294SPatrick Venture 
1113fb74294SPatrick Venture             // Read the "pcie-slot" name from the "pcie-slot" file.
1123fb74294SPatrick Venture             pcie_slot = readPropertyFile(pcie_slot_path);
1133fb74294SPatrick Venture             if (pcie_slot.empty())
1143fb74294SPatrick Venture             {
1153fb74294SPatrick Venture                 continue;
1163fb74294SPatrick Venture             }
1173fb74294SPatrick Venture             std::string pcie_slot_name;
1183fb74294SPatrick Venture             std::string pcie_slot_full_path;
1193fb74294SPatrick Venture 
1203fb74294SPatrick Venture             // Append the "pcie-slot" name to dts base.
1213fb74294SPatrick Venture             pcie_slot_full_path.append("/proc/device-tree");
1223fb74294SPatrick Venture             pcie_slot_full_path.append(pcie_slot);
1233fb74294SPatrick Venture 
1243fb74294SPatrick Venture             // Read the "label" which contains the pcie slot name.
1253fb74294SPatrick Venture             pcie_slot_full_path.append("/label");
1263fb74294SPatrick Venture             pcie_slot_name = readPropertyFile(pcie_slot_full_path);
1273fb74294SPatrick Venture 
1283fb74294SPatrick Venture             if (pcie_slot_name.empty())
1293fb74294SPatrick Venture             {
1303fb74294SPatrick Venture                 continue;
1313fb74294SPatrick Venture             }
1323fb74294SPatrick Venture 
1333fb74294SPatrick Venture             // Get the i2c bus number from the i2c device path.
1343fb74294SPatrick Venture             std::uint32_t i2c_bus_number =
1353fb74294SPatrick Venture                 i2c_dev_string_number[2].matched
1363fb74294SPatrick Venture                     ? std::stoi(i2c_dev_string_number[2])
1373fb74294SPatrick Venture                     : 0;
1383fb74294SPatrick Venture             // Store the i2c bus number and the pcie slot name in the vector.
1393fb74294SPatrick Venture             pcie_i2c_map.push_back(
1403fb74294SPatrick Venture                 std::make_tuple(i2c_bus_number, pcie_slot_name));
1413fb74294SPatrick Venture         }
1423fb74294SPatrick Venture     }
1433fb74294SPatrick Venture 
1443fb74294SPatrick Venture     return pcie_i2c_map;
1453fb74294SPatrick Venture }
1463fb74294SPatrick Venture 
147ab650004SPatrick Venture } // namespace ipmi
148ab650004SPatrick Venture } // namespace google
149