blob: a879a51c1d64125142255e4c5fbd571d51157e43 [file] [log] [blame]
Matt Spinlere9d33b62021-11-09 13:27:26 -06001/**
2 * Copyright © 2022 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
18#include <nlohmann/json.hpp>
19
20#include <filesystem>
21#include <optional>
22#include <string>
23#include <variant>
24#include <vector>
25
26namespace phosphor::fan::control::json
27{
28
29/**
30 * @class PCIeCardMetadata
31 *
32 * This class provides the ability for an action to look up a PCIe card's
33 * fan floor index or temp sensor name based on its metadata, which
34 * consists of 4 properties from the PCIeDevice D-Bus interface.
35 *
36 * The metadata is stored in one or more (see loadCards) JSON files, which
37 * look like:
38 * {
39 * "cards": [
40 * {
41 * "name": "TestCard",
42 * "device_id": "0x1",
43 * "vendor_id": "0x2",
44 * "subsystem_id": "0x3",
45 * "subsystem_vendor_id": "0x4",
46 * "floor_index": 3
47 * },
48 * ...
49 * ]
50 * }
51 *
52 * If the card has a temperature sensor on it, then it doesn't
53 * need a floor index and instead will have:
54 * "has_temp_sensor": true
55 */
56class PCIeCardMetadata
57{
58 public:
59 PCIeCardMetadata() = delete;
60 ~PCIeCardMetadata() = default;
61 PCIeCardMetadata(const PCIeCardMetadata&) = delete;
62 PCIeCardMetadata& operator=(const PCIeCardMetadata&) = delete;
63 PCIeCardMetadata(PCIeCardMetadata&&) = delete;
64 PCIeCardMetadata& operator=(PCIeCardMetadata&&) = delete;
65
66 /**
67 * @brief Constructor
68 *
69 * @param[in] systemNames - The system names values
70 */
71 PCIeCardMetadata(const std::vector<std::string>& systemNames);
72
73 /**
74 * @brief Look up a floor index based on a card's metadata
75 *
76 * @param[in] deviceID - Function0DeviceId value
77 * @param[in] vendorID - Function0VendorId value
78 * @param[in] subsystemID - Function0SubsystemId value
79 * @param[in] subsystemVendorID - Function0SubsystemVendorId value
80 *
81 * @return optional<variant<int32, bool>> -
82 * Either the floor index for that entry, or true saying
83 * it has a temp sensor.
84 *
85 * If no entry is found, it will return std::nullopt.
86 */
87 std::optional<std::variant<int32_t, bool>>
88 lookup(uint16_t deviceID, uint16_t vendorID, uint16_t subsystemID,
89 uint16_t subsystemVendorID) const;
90
91 private:
92 /**
93 * Structure to hold card metadata.
94 */
95 struct Metadata
96 {
97 uint16_t vendorID;
98 uint16_t deviceID;
99 uint16_t subsystemVendorID;
100 uint16_t subsystemID;
101 int32_t floorIndex;
102 bool hasTempSensor;
103
104 bool operator==(const Metadata& other)
105 {
106 return (vendorID == other.vendorID) &&
107 (deviceID == other.deviceID) &&
108 (subsystemVendorID == other.subsystemVendorID) &&
109 (subsystemID == other.subsystemID);
110 }
111 };
112
113 /**
114 * @brief Loads the metadata from JSON files
115 *
116 * It will load a pcie_cards.json file in the default location if it
117 * is present.
118 *
119 * If systemNames isn't empty, it will load in any 'pcie_cards.json'
120 * files it finds in directories based on those names, overwriting any
121 * entries that were in any previous files. This allows different
122 * floor indexes for some cards for the different systems in a flash
123 * image without needing to specify every possible card in every
124 * system specific JSON file.
125 *
126 * If no valid config files are found it will throw an exception.
127 *
128 * @param[in] systemNames - The system names values
129 */
130 void loadCards(const std::vector<std::string>& systemNames);
131
132 /**
133 * @brief Loads in the card info from the JSON
134 *
135 * @param[in] json - The JSON containing a cards array
136 */
137 void load(const nlohmann::json& json);
138
139 /**
140 * @brief Dumps the cards vector for debug
141 */
142 void dump() const;
143
144 /**
145 * @brief The card metadata
146 */
147 std::vector<Metadata> _cards;
148};
149
150} // namespace phosphor::fan::control::json