1 /** 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 26 namespace 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 */ 56 class 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 151