sensors: Align source structure away from anti-patterns

The anti-patterns document comments on source structure, specifically
on placing internal headers in a parallel subtree[1]. dbus-sensors is an
example of violating this anti-pattern, so fix it.

[1]: https://github.com/openbmc/docs/blob/master/anti-patterns.md#placing-internal-headers-in-a-parallel-subtree

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I50ecaddd53fa9c9b7a0441af9de5e60bd94e47c6
diff --git a/src/Thresholds.hpp b/src/Thresholds.hpp
new file mode 100644
index 0000000..cd89efc
--- /dev/null
+++ b/src/Thresholds.hpp
@@ -0,0 +1,155 @@
+#pragma once
+
+#include "Utils.hpp"
+
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <nlohmann/json.hpp>
+
+#include <list>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+struct Sensor;
+namespace thresholds
+{
+enum class Level
+{
+    WARNING,
+    CRITICAL,
+    PERFORMANCELOSS,
+    SOFTSHUTDOWN,
+    HARDSHUTDOWN,
+    ERROR
+};
+enum class Direction
+{
+    HIGH,
+    LOW,
+    ERROR
+};
+struct Threshold
+{
+    Threshold(
+        const Level& lev, const Direction& dir, const double& val,
+        const double hysteresis = std::numeric_limits<double>::quiet_NaN(),
+        bool write = true) :
+        level(lev),
+        direction(dir), value(val), hysteresis(hysteresis), writeable(write)
+    {}
+    Level level;
+    Direction direction;
+    double value;
+    double hysteresis;
+    bool writeable;
+
+    bool operator==(const Threshold& rhs) const
+    {
+        return (level == rhs.level && direction == rhs.direction &&
+                value == rhs.value);
+    }
+};
+
+void assertThresholds(Sensor* sensor, double assertValue,
+                      thresholds::Level level, thresholds::Direction direction,
+                      bool assert);
+
+struct TimerUsed
+{
+    bool used;
+    Level level;
+    Direction direction;
+    bool assert;
+};
+
+using TimerPair = std::pair<struct TimerUsed, boost::asio::steady_timer>;
+
+struct ThresholdTimer
+{
+
+    explicit ThresholdTimer(boost::asio::io_service& ioService) : io(ioService)
+    {}
+
+    bool hasActiveTimer(const Threshold& threshold, bool assert)
+    {
+        for (TimerPair& timer : timers)
+        {
+            if (timer.first.used)
+            {
+                if ((timer.first.level == threshold.level) &&
+                    (timer.first.direction == threshold.direction) &&
+                    (timer.first.assert == assert))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    void stopTimer(const Threshold& threshold, bool assert)
+    {
+        struct TimerUsed timerUsed = {};
+        for (TimerPair& timer : timers)
+        {
+            timerUsed = timer.first;
+            if (timerUsed.used)
+            {
+                if ((timerUsed.level == threshold.level) &&
+                    (timerUsed.direction == threshold.direction) &&
+                    (timerUsed.assert == assert))
+                {
+                    timer.second.cancel();
+                }
+            }
+        }
+    }
+
+    void startTimer(const std::weak_ptr<Sensor>& weakSensor,
+                    const Threshold& threshold, bool assert,
+                    double assertValue);
+
+    boost::asio::io_service& io;
+    std::list<TimerPair> timers;
+};
+
+bool parseThresholdsFromConfig(
+    const SensorData& sensorData,
+    std::vector<thresholds::Threshold>& thresholdVector,
+    const std::string* matchLabel = nullptr, const int* sensorIndex = nullptr);
+
+bool parseThresholdsFromAttr(
+    std::vector<thresholds::Threshold>& thresholdVector,
+    const std::string& inputPath, const double& scaleFactor,
+    const double& offset = 0);
+
+struct ThresholdDefinition
+{
+    Level level;
+    uint8_t sevOrder;
+    const char* levelName;
+};
+
+constexpr static std::array<thresholds::ThresholdDefinition, 5> thresProp = {
+    {{Level::WARNING, 0, "Warning"},
+     {Level::CRITICAL, 1, "Critical"},
+     {Level::PERFORMANCELOSS, 2, "PerformanceLoss"},
+     {Level::SOFTSHUTDOWN, 3, "SoftShutdown"},
+     {Level::HARDSHUTDOWN, 4, "HardShutdown"}}};
+
+std::string getInterface(Level level);
+
+void persistThreshold(const std::string& path, const std::string& baseInterface,
+                      const thresholds::Threshold& threshold,
+                      std::shared_ptr<sdbusplus::asio::connection>& conn,
+                      size_t thresholdCount, const std::string& label);
+
+void updateThresholds(Sensor* sensor);
+// returns false if a critical threshold has been crossed, true otherwise
+bool checkThresholds(Sensor* sensor);
+void checkThresholdsPowerDelay(const std::weak_ptr<Sensor>& weakSensor,
+                               ThresholdTimer& thresholdTimer);
+
+} // namespace thresholds