blob: 2cac56e761fce839f83ef515bebb0336f4366cd0 [file] [log] [blame]
James Feist6714a252018-09-10 15:26:18 -07001#pragma once
2
James Feist58295ad2019-05-30 15:01:41 -07003#include "Utils.hpp"
4
James Feist6714a252018-09-10 15:26:18 -07005#include <Thresholds.hpp>
James Feist58295ad2019-05-30 15:01:41 -07006#include <boost/container/flat_map.hpp>
7#include <filesystem>
8#include <fstream>
9#include <gpiod.hpp>
James Feist6714a252018-09-10 15:26:18 -070010#include <sdbusplus/asio/object_server.hpp>
James Feist251c7822018-09-12 12:54:15 -070011#include <sensor.hpp>
James Feist6714a252018-09-10 15:26:18 -070012
James Feist251c7822018-09-12 12:54:15 -070013class CPUSensor : public Sensor
James Feist6714a252018-09-10 15:26:18 -070014{
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070015 public:
James Feistd8705872019-02-08 13:26:09 -080016 CPUSensor(const std::string& path, const std::string& objectType,
17 sdbusplus::asio::object_server& objectServer,
18 std::shared_ptr<sdbusplus::asio::connection>& conn,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080019 boost::asio::io_service& io, const std::string& sensorName,
James Feistd8705872019-02-08 13:26:09 -080020 std::vector<thresholds::Threshold>&& thresholds,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080021 const std::string& configuration, int cpuId, bool show);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070022 ~CPUSensor();
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070023 static constexpr unsigned int sensorScaleFactor = 1000;
24 static constexpr unsigned int sensorPollMs = 1000;
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080025 static constexpr size_t warnAfterErrorCount = 10;
26 static constexpr double maxReading = 127;
27 static constexpr double minReading = -128;
28 static constexpr const char* labelTcontrol = "Tcontrol";
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070029
James Feist6714a252018-09-10 15:26:18 -070030 private:
James Feistd8705872019-02-08 13:26:09 -080031 sdbusplus::asio::object_server& objServer;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070032 boost::asio::posix::stream_descriptor inputDev;
33 boost::asio::deadline_timer waitTimer;
34 boost::asio::streambuf readBuf;
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080035 std::string nameTcontrol;
James Feist930fcde2019-05-28 12:58:43 -070036 std::string path;
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080037 double privTcontrol;
38 bool show;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070039 int errCount;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070040 void setupRead(void);
James Feistd8705872019-02-08 13:26:09 -080041 void handleResponse(const boost::system::error_code& err);
James Feistce3fca42018-11-21 12:58:24 -080042 void checkThresholds(void) override;
James Feist6714a252018-09-10 15:26:18 -070043};
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080044
45extern boost::container::flat_map<std::string, std::unique_ptr<CPUSensor>>
46 gCpuSensors;
James Feist58295ad2019-05-30 15:01:41 -070047
48// this is added to cpusensor.hpp to avoid having every sensor have to link
49// against libgpiod, if another sensor needs it we may move it to utils
50inline bool hostIsPresent(size_t gpioNum)
51{
52 static boost::container::flat_map<size_t, bool> cpuPresence;
53
54 auto findIndex = cpuPresence.find(gpioNum);
55 if (findIndex != cpuPresence.end())
56 {
57 return findIndex->second;
58 }
59
60 constexpr size_t sgpioBase = 232;
61
62 // check if sysfs has device
63 bool sysfs = std::filesystem::exists(gpioPath + std::string("gpio") +
64 std::to_string(gpioNum));
65
66 // todo: delete this when we remove all sysfs code
67 if (sysfs)
68 {
69 // close it, we'll reopen it at the end
70 std::ofstream unexport(gpioPath + std::string("unexport"));
71 if (unexport.good())
72 {
73 unexport << gpioNum;
74 }
75 else
76 {
77 std::cerr << "Error cleaning up sysfs device\n";
78 }
79 }
80
81 size_t chipNum = (gpioNum - sgpioBase) / 8;
82 size_t index = (gpioNum - sgpioBase) % 8;
83 gpiod::chip chip("gpiochip" + std::to_string(chipNum));
84 auto line = chip.get_line(index);
85
86 if (!line)
87 {
88 std::cerr << "Error requesting gpio\n";
89 return true;
90 }
91
92 bool resp = true;
93 try
94 {
95 line.request({"adcsensor", gpiod::line_request::DIRECTION_INPUT});
96 resp = !line.get_value();
97 }
98 catch (std::system_error&)
99 {
100 std::cerr << "Error reading gpio\n";
101 return true;
102 }
103
104 // todo: delete this when we remove all sysfs code
105 if (sysfs)
106 {
107 // reopen it
108 std::ofstream populate(gpioPath + std::string("export"));
109 if (populate.good())
110 {
111 populate << gpioNum;
112 }
113 else
114 {
115 std::cerr << "Error cleaning up sysfs device\n";
116 }
117 }
118 cpuPresence[gpioNum] = resp;
119 return resp;
120}