blob: 9c932b49f4ef1b386d333b555a8f8b906ccf777d [file] [log] [blame]
Tomáš Pecka339bc672020-11-11 15:59:03 +01001/*
2 * Copyright (C) 2016-2020 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Tomáš Pecka <tomas.pecka@fit.cvut.cz>
5 *
6 */
7
8#pragma once
9
10#include <functional>
11#include <map>
Jan Kundrát1c3b8812021-05-17 13:06:03 +020012#include <optional>
Tomáš Pecka339bc672020-11-11 15:59:03 +010013#include <utility>
14#include "ietf-hardware/sysfs/EMMC.h"
15#include "ietf-hardware/sysfs/HWMon.h"
16#include "utils/log-fwd.h"
17
18using namespace std::literals;
19
20namespace velia::ietf_hardware {
21
22using DataTree = std::map<std::string, std::string>;
23
24/**
25 * @brief Readout of hardware-state related data according to RFC 8348 (App. A)
26 *
27 * IETFHardware implements readout of various hardware component data and provides them as a mapping
28 * nodePath -> value, where nodePath is an XPath conforming to ietf-hardware-state module (RFC 8348, App. A).
29 *
30 * The class is designed to be modular. IETFHardware does not do much, its only capabilities are:
31 * - Register data readers responsible for readout of data for individual hardware, and
32 * - ask registered data readers to provide the data.
33 *
34 * The data readers (IETFHardware::DataReader) are simple functors with signature DataTree() (i.e., std::map<std::string, std::string>())
35 * returning parts of the tree in the form described above (i.e., mapping nodePath -> value).
36 *
37 * The IETFHardware is *not aware* of Sysrepo.
38 * However, the data readers are aware of the tree structure of the YANG module ietf-hardware-state.
39 * That is because they also create the specified parts of the resulting tree.
40 *
41 * @see IETFHardware::DataReader The data reader.
42 * @see velia::ietf_hardware::data_reader Namespace containing several predefined components.
43 */
44class IETFHardware {
45
46public:
47 /** @brief The component */
48 using DataReader = std::function<DataTree()>;
49
50 IETFHardware();
51 ~IETFHardware();
52 void registerDataReader(const DataReader& callable);
53
54 DataTree process();
55
56private:
57 /** @brief registered components for individual modules */
58 std::vector<DataReader> m_callbacks;
59};
60
61/**
62 * This namespace contains several predefined data readers for IETFHardware.
63 * They are implemented as functors and fulfill the required interface -- std::function<DataTree()>
64 *
65 * The philosophy here is to initialize Component::m_staticData DataTree when constructing the object so the tree does not have to be completely reconstructed every time.
66 * When IETFHardwareState fetches the data from the data reader, an operator() is invoked.
67 * The dynamic data are fetched by IETFHardware class by the use of the operator().
68 * The result of call to operator() will be merged into the static data and returned to caller (IETFHardwareState).
69 *
70 * Note that a data reader can return any number of nodes and even multiple compoments.
71 * For example, Fans data reader will create multiple components in the tree, one for each fan.
72 */
73namespace data_reader {
74
75struct DataReader {
76 /** @brief name of the module component in the tree, e.g. ne:fans:fan1 */
77 std::string m_componentName;
78
79 /** @brief name of the parent module */
80 std::optional<std::string> m_parent;
81
82 /** @brief static hw-state related data */
83 DataTree m_staticData;
84
85 DataReader(std::string propertyPrefix, std::optional<std::string> parent);
86};
87
88/** @brief Manages any component composing of static data only. The static data are provided as a DataTree in construction time. */
89struct StaticData : private DataReader {
90 StaticData(std::string propertyPrefix, std::optional<std::string> parent, DataTree tree);
91 DataTree operator()() const;
92};
93
94/** @brief Manages fans component. Data is provided by a sysfs::HWMon object. */
95struct Fans : private DataReader {
96private:
97 std::shared_ptr<sysfs::HWMon> m_hwmon;
98 unsigned m_fanChannelsCount;
99
100public:
101 Fans(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::HWMon> hwmon, unsigned fanChannelsCount);
102 DataTree operator()() const;
103};
104
Václav Kubernát6c17d0a2021-03-29 04:55:31 +0200105enum class SensorType {
Václav Kubernát97e5ea12021-03-24 00:36:57 +0100106 Temperature,
107 Current,
108 VoltageDC,
109 VoltageAC,
110 Power
111
Václav Kubernát6c17d0a2021-03-29 04:55:31 +0200112};
113
114/** @brief Manages a single value from sysfs, data is provided by a sysfs::HWMon object. */
115template<SensorType TYPE>
116struct SysfsValue : private DataReader {
Tomáš Pecka339bc672020-11-11 15:59:03 +0100117private:
118 std::shared_ptr<sysfs::HWMon> m_hwmon;
Václav Kubernát6c17d0a2021-03-29 04:55:31 +0200119 std::string m_sysfsFile;
Tomáš Pecka339bc672020-11-11 15:59:03 +0100120
121public:
Václav Kubernát6c17d0a2021-03-29 04:55:31 +0200122 SysfsValue(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::HWMon> hwmon, int sysfsChannelNr);
Tomáš Pecka339bc672020-11-11 15:59:03 +0100123 DataTree operator()() const;
124};
125
126/** @brief Manages a single eMMC block device hardware component. Data is provided by a sysfs::EMMC object. */
127struct EMMC : private DataReader {
128private:
129 std::shared_ptr<sysfs::EMMC> m_emmc;
130
131public:
132 EMMC(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::EMMC> emmc);
133 DataTree operator()() const;
134};
135}
136}