1 #pragma once
2 
3 #include <filesystem>
4 #include <map>
5 #include <optional>
6 #include <set>
7 #include <string>
8 #include <tuple>
9 #include <vector>
10 
11 namespace pldm
12 {
13 
14 namespace responder
15 {
16 
17 namespace dbus
18 {
19 
20 using Service = std::string;
21 using RootPath = std::string;
22 using Interface = std::string;
23 using Interfaces = std::set<Interface>;
24 using Property = std::string;
25 using PropertyType = std::string;
26 using EntityType = uint16_t;
27 
28 } // namespace dbus
29 
30 namespace fru
31 {
32 
33 using RecordType = uint8_t;
34 using EncodingType = uint8_t;
35 using FieldType = uint8_t;
36 
37 } // namespace fru
38 
39 namespace fru_parser
40 {
41 
42 namespace fs = std::filesystem;
43 
44 // DBusLookupInfo contains info to lookup in the D-Bus inventory, D-Bus
45 // inventory service bus name, root path of the inventory D-Bus objects and list
46 //  of xyz.openbmc_project.Inventory.Item.* interface names.
47 using DBusLookupInfo =
48     std::tuple<pldm::responder::dbus::Service, pldm::responder::dbus::RootPath,
49                pldm::responder::dbus::Interfaces>;
50 using FieldInfo = std::tuple<
51     pldm::responder::dbus::Interface, pldm::responder::dbus::Property,
52     pldm::responder::dbus::PropertyType, pldm::responder::fru::FieldType>;
53 
54 using FruRecordInfo =
55     std::tuple<pldm::responder::fru::RecordType,
56                pldm::responder::fru::EncodingType, std::vector<FieldInfo>>;
57 using FruRecordInfos = std::vector<FruRecordInfo>;
58 
59 using ItemIntfName = std::string;
60 using FruRecordMap = std::map<ItemIntfName, FruRecordInfos>;
61 
62 /** @class FruParser
63  *
64  *  @brief Parses the PLDM FRU configuration files to populate the data
65  *         structure, containing the information needed to map the D-Bus
66  *         inventory information into PLDM FRU Record.
67  */
68 class FruParser
69 {
70 
71   public:
72     FruParser() = delete;
73     explicit FruParser(const std::string& dirPath,
74                        const std::filesystem::path& fruMasterJsonPath);
75     virtual ~FruParser() = default;
76     FruParser(const FruParser&) = default;
77     FruParser& operator=(const FruParser&) = default;
78     FruParser(FruParser&&) = default;
79     FruParser& operator=(FruParser&&) = default;
80 
81     /** @brief Provides the service, root D-Bus path and the interfaces that is
82      *         needed to build FRU record data table
83      *
84      *  @return service and inventory interfaces needed to build the FRU records
85      */
86     const DBusLookupInfo& inventoryLookup() const
87     {
88         return lookupInfo.value();
89     }
90 
91     /** @brief Get the information need to create PLDM FRU records for a
92      * inventory item type. The parameter to this API is the inventory item
93      * type, for example xyz.openbmc_project.Inventory.Item.Cpu for CPU's
94      *
95      *  @param[in] intf - name of the item interface
96      *
97      *  @return return the info create the PLDM FRU records from inventory D-Bus
98      *          objects
99      */
100     const FruRecordInfos&
101         getRecordInfo(const pldm::responder::dbus::Interface& intf) const
102     {
103         return recordMap.at(intf);
104     }
105 
106     pldm::responder::dbus::EntityType
107         getEntityType(const pldm::responder::dbus::Interface& intf) const
108     {
109         return intfToEntityType.at(intf);
110     }
111 
112   private:
113     /** @brief Parse the FRU_Master.json file and populate the D-Bus lookup
114      *         information which provides the service, root D-Bus path and the
115      *         item interfaces.
116      *
117      *  @param[in] filePath - file path to FRU_Master.json
118      */
119     void setupDBusLookup(const fs::path& filePath);
120 
121     /** @brief Parse the FRU Configuration JSON file in the directory path
122      *         except the FRU_Master.json and build the FRU record information
123      *
124      *  @param[in] dirPath - directory path where all the FRU configuration JSON
125      *                       files exist
126      */
127     void setupFruRecordMap(const std::string& dirPath);
128 
129     /** @brief Set the default service root D-Bus path and the item interfaces.
130      *
131      *  @param[in] fruMasterJsonPath - json file path that contains the FRU
132      * D-Bus lookup map
133      */
134     void setupDefaultDBusLookup(const std::filesystem::path& fruMasterJsonPath);
135 
136     /** @brief Build the default FRU record informations
137      */
138     void setupDefaultFruRecordMap();
139 
140     std::optional<DBusLookupInfo> lookupInfo;
141     FruRecordMap recordMap;
142     std::map<pldm::responder::dbus::Interface,
143              pldm::responder::dbus::EntityType>
144         intfToEntityType;
145 };
146 
147 } // namespace fru_parser
148 
149 } // namespace responder
150 
151 } // namespace pldm
152