blob: 1b2551870c4e72487c906a905c41d9cbe25fb6e2 [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;
36 double privTcontrol;
37 bool show;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070038 int errCount;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -070039 void setupRead(void);
James Feistd8705872019-02-08 13:26:09 -080040 void handleResponse(const boost::system::error_code& err);
James Feistce3fca42018-11-21 12:58:24 -080041 void checkThresholds(void) override;
James Feist6714a252018-09-10 15:26:18 -070042};
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080043
44extern boost::container::flat_map<std::string, std::unique_ptr<CPUSensor>>
45 gCpuSensors;
James Feist58295ad2019-05-30 15:01:41 -070046
47// this is added to cpusensor.hpp to avoid having every sensor have to link
48// against libgpiod, if another sensor needs it we may move it to utils
49inline bool hostIsPresent(size_t gpioNum)
50{
51 static boost::container::flat_map<size_t, bool> cpuPresence;
52
53 auto findIndex = cpuPresence.find(gpioNum);
54 if (findIndex != cpuPresence.end())
55 {
56 return findIndex->second;
57 }
58
59 constexpr size_t sgpioBase = 232;
60
61 // check if sysfs has device
62 bool sysfs = std::filesystem::exists(gpioPath + std::string("gpio") +
63 std::to_string(gpioNum));
64
65 // todo: delete this when we remove all sysfs code
66 if (sysfs)
67 {
68 // close it, we'll reopen it at the end
69 std::ofstream unexport(gpioPath + std::string("unexport"));
70 if (unexport.good())
71 {
72 unexport << gpioNum;
73 }
74 else
75 {
76 std::cerr << "Error cleaning up sysfs device\n";
77 }
78 }
79
80 size_t chipNum = (gpioNum - sgpioBase) / 8;
81 size_t index = (gpioNum - sgpioBase) % 8;
82 gpiod::chip chip("gpiochip" + std::to_string(chipNum));
83 auto line = chip.get_line(index);
84
85 if (!line)
86 {
87 std::cerr << "Error requesting gpio\n";
88 return true;
89 }
90
91 bool resp = true;
92 try
93 {
94 line.request({"adcsensor", gpiod::line_request::DIRECTION_INPUT});
95 resp = !line.get_value();
96 }
97 catch (std::system_error&)
98 {
99 std::cerr << "Error reading gpio\n";
100 return true;
101 }
102
103 // todo: delete this when we remove all sysfs code
104 if (sysfs)
105 {
106 // reopen it
107 std::ofstream populate(gpioPath + std::string("export"));
108 if (populate.good())
109 {
110 populate << gpioNum;
111 }
112 else
113 {
114 std::cerr << "Error cleaning up sysfs device\n";
115 }
116 }
117 cpuPresence[gpioNum] = resp;
118 return resp;
119}