blob: dcdc9e5e7365ef7f8f7a3cd1f59f4bc9ec0e57e5 [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 *
Matt Spinler3d0c3692024-12-12 13:01:56 -060036 * The metadata is stored in a JSON file, which looks like:
Matt Spinlere9d33b62021-11-09 13:27:26 -060037 * {
38 * "cards": [
39 * {
40 * "name": "TestCard",
41 * "device_id": "0x1",
42 * "vendor_id": "0x2",
43 * "subsystem_id": "0x3",
44 * "subsystem_vendor_id": "0x4",
45 * "floor_index": 3
46 * },
47 * ...
48 * ]
49 * }
50 *
51 * If the card has a temperature sensor on it, then it doesn't
52 * need a floor index and instead will have:
53 * "has_temp_sensor": true
54 */
55class PCIeCardMetadata
56{
57 public:
58 PCIeCardMetadata() = delete;
59 ~PCIeCardMetadata() = default;
60 PCIeCardMetadata(const PCIeCardMetadata&) = delete;
61 PCIeCardMetadata& operator=(const PCIeCardMetadata&) = delete;
62 PCIeCardMetadata(PCIeCardMetadata&&) = delete;
63 PCIeCardMetadata& operator=(PCIeCardMetadata&&) = delete;
64
65 /**
66 * @brief Constructor
67 *
68 * @param[in] systemNames - The system names values
69 */
Matt Spinler9b062432023-01-26 14:38:50 -060070 explicit PCIeCardMetadata(const std::vector<std::string>& systemNames);
Matt Spinlere9d33b62021-11-09 13:27:26 -060071
72 /**
73 * @brief Look up a floor index based on a card's metadata
74 *
75 * @param[in] deviceID - Function0DeviceId value
76 * @param[in] vendorID - Function0VendorId value
77 * @param[in] subsystemID - Function0SubsystemId value
78 * @param[in] subsystemVendorID - Function0SubsystemVendorId value
79 *
80 * @return optional<variant<int32, bool>> -
81 * Either the floor index for that entry, or true saying
82 * it has a temp sensor.
83 *
84 * If no entry is found, it will return std::nullopt.
85 */
86 std::optional<std::variant<int32_t, bool>>
87 lookup(uint16_t deviceID, uint16_t vendorID, uint16_t subsystemID,
88 uint16_t subsystemVendorID) const;
89
90 private:
91 /**
92 * Structure to hold card metadata.
93 */
94 struct Metadata
95 {
96 uint16_t vendorID;
97 uint16_t deviceID;
98 uint16_t subsystemVendorID;
99 uint16_t subsystemID;
100 int32_t floorIndex;
101 bool hasTempSensor;
102
103 bool operator==(const Metadata& other)
104 {
105 return (vendorID == other.vendorID) &&
106 (deviceID == other.deviceID) &&
107 (subsystemVendorID == other.subsystemVendorID) &&
108 (subsystemID == other.subsystemID);
109 }
110 };
111
112 /**
113 * @brief Loads the metadata from JSON files
114 *
115 * It will load a pcie_cards.json file in the default location if it
116 * is present.
117 *
Matt Spinler3d0c3692024-12-12 13:01:56 -0600118 * If systemNames isn't empty, it will load the first 'pcie_cards.json'
119 * files it finds in directories based on those names.
Matt Spinlere9d33b62021-11-09 13:27:26 -0600120 *
121 * If no valid config files are found it will throw an exception.
122 *
123 * @param[in] systemNames - The system names values
124 */
125 void loadCards(const std::vector<std::string>& systemNames);
126
127 /**
128 * @brief Loads in the card info from the JSON
129 *
130 * @param[in] json - The JSON containing a cards array
131 */
132 void load(const nlohmann::json& json);
133
134 /**
135 * @brief Dumps the cards vector for debug
136 */
137 void dump() const;
138
139 /**
140 * @brief The card metadata
141 */
142 std::vector<Metadata> _cards;
143};
144
145} // namespace phosphor::fan::control::json