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 a JSON file, which looks like: 37 * { 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 */ 55 class 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 */ 70 explicit PCIeCardMetadata(const std::vector<std::string>& systemNames); 71 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>> lookup( 87 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 operator ==phosphor::fan::control::json::PCIeCardMetadata::Metadata103 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 * 118 * If systemNames isn't empty, it will load the first 'pcie_cards.json' 119 * files it finds in directories based on those names. 120 * 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 146