blob: dcdc9e5e7365ef7f8f7a3cd1f59f4bc9ec0e57e5 [file] [log] [blame]
/**
* Copyright © 2022 IBM Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <nlohmann/json.hpp>
#include <filesystem>
#include <optional>
#include <string>
#include <variant>
#include <vector>
namespace phosphor::fan::control::json
{
/**
* @class PCIeCardMetadata
*
* This class provides the ability for an action to look up a PCIe card's
* fan floor index or temp sensor name based on its metadata, which
* consists of 4 properties from the PCIeDevice D-Bus interface.
*
* The metadata is stored in a JSON file, which looks like:
* {
* "cards": [
* {
* "name": "TestCard",
* "device_id": "0x1",
* "vendor_id": "0x2",
* "subsystem_id": "0x3",
* "subsystem_vendor_id": "0x4",
* "floor_index": 3
* },
* ...
* ]
* }
*
* If the card has a temperature sensor on it, then it doesn't
* need a floor index and instead will have:
* "has_temp_sensor": true
*/
class PCIeCardMetadata
{
public:
PCIeCardMetadata() = delete;
~PCIeCardMetadata() = default;
PCIeCardMetadata(const PCIeCardMetadata&) = delete;
PCIeCardMetadata& operator=(const PCIeCardMetadata&) = delete;
PCIeCardMetadata(PCIeCardMetadata&&) = delete;
PCIeCardMetadata& operator=(PCIeCardMetadata&&) = delete;
/**
* @brief Constructor
*
* @param[in] systemNames - The system names values
*/
explicit PCIeCardMetadata(const std::vector<std::string>& systemNames);
/**
* @brief Look up a floor index based on a card's metadata
*
* @param[in] deviceID - Function0DeviceId value
* @param[in] vendorID - Function0VendorId value
* @param[in] subsystemID - Function0SubsystemId value
* @param[in] subsystemVendorID - Function0SubsystemVendorId value
*
* @return optional<variant<int32, bool>> -
* Either the floor index for that entry, or true saying
* it has a temp sensor.
*
* If no entry is found, it will return std::nullopt.
*/
std::optional<std::variant<int32_t, bool>>
lookup(uint16_t deviceID, uint16_t vendorID, uint16_t subsystemID,
uint16_t subsystemVendorID) const;
private:
/**
* Structure to hold card metadata.
*/
struct Metadata
{
uint16_t vendorID;
uint16_t deviceID;
uint16_t subsystemVendorID;
uint16_t subsystemID;
int32_t floorIndex;
bool hasTempSensor;
bool operator==(const Metadata& other)
{
return (vendorID == other.vendorID) &&
(deviceID == other.deviceID) &&
(subsystemVendorID == other.subsystemVendorID) &&
(subsystemID == other.subsystemID);
}
};
/**
* @brief Loads the metadata from JSON files
*
* It will load a pcie_cards.json file in the default location if it
* is present.
*
* If systemNames isn't empty, it will load the first 'pcie_cards.json'
* files it finds in directories based on those names.
*
* If no valid config files are found it will throw an exception.
*
* @param[in] systemNames - The system names values
*/
void loadCards(const std::vector<std::string>& systemNames);
/**
* @brief Loads in the card info from the JSON
*
* @param[in] json - The JSON containing a cards array
*/
void load(const nlohmann::json& json);
/**
* @brief Dumps the cards vector for debug
*/
void dump() const;
/**
* @brief The card metadata
*/
std::vector<Metadata> _cards;
};
} // namespace phosphor::fan::control::json