Stop the timer when the deasserted events occur

A timer will be started if there is any threshold asserted event occurs,
but it is not stopped when the deasserted occurs.
This causes additional asserted events.
Connected the timer with different threshold, and stop it if deasserted.

Tested:
Adjust the threshold value with ipmitool raw 4 0x26 command, there is no duplicated asserted sel log:
8 | 04/21/20 | 08:00:24 UTC | Voltage P3VBAT | Upper Non-critical going high | Asserted | Reading 3.04 > Threshold 2.57 Volts
9 | 04/21/20 | 08:00:26 UTC | Voltage P3VBAT | Upper Non-critical going high | Deasserted | Reading 3.04 > Threshold 3.28 Volts
a | 04/21/20 | 08:00:45 UTC | Voltage P3VBAT | Upper Non-critical going high | Asserted | Reading 3.04 > Threshold 2.57 Volts
b | 04/21/20 | 08:00:48 UTC | Voltage P3VBAT | Upper Non-critical going high | Deasserted | Reading 3.04 > Threshold 3.28 Volts

Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Change-Id: Ia218320c29c34e0bf9ef0604934e04cf0a5701dd
diff --git a/include/Thresholds.hpp b/include/Thresholds.hpp
index 2205c5e..33c6f8f 100644
--- a/include/Thresholds.hpp
+++ b/include/Thresholds.hpp
@@ -45,7 +45,14 @@
 void assertThresholds(Sensor* sensor, thresholds::Level level,
                       thresholds::Direction direction, bool assert);
 
-using TimerPair = std::pair<bool, boost::asio::deadline_timer>;
+struct TimerUsed
+{
+    bool used;
+    Level level;
+    Direction direction;
+};
+
+using TimerPair = std::pair<struct TimerUsed, boost::asio::deadline_timer>;
 
 struct ThresholdTimer
 {
@@ -55,14 +62,32 @@
     {
     }
 
+    void stopTimer(const Threshold& threshold)
+    {
+        struct TimerUsed timerUsed = {};
+        for (TimerPair& timer : timers)
+        {
+            timerUsed = timer.first;
+            if (timerUsed.used)
+            {
+                if ((timerUsed.level == threshold.level) &&
+                    (timerUsed.direction == threshold.direction))
+                {
+                    timer.second.cancel();
+                }
+            }
+        }
+    }
+
     void startTimer(const Threshold& threshold)
     {
+        struct TimerUsed timerUsed = {};
         constexpr const size_t waitTime = 5;
         TimerPair* pair = nullptr;
 
         for (TimerPair& timer : timers)
         {
-            if (!timer.first)
+            if (!timer.first.used)
             {
                 pair = &timer;
                 break;
@@ -70,13 +95,16 @@
         }
         if (pair == nullptr)
         {
-            pair = &timers.emplace_back(false, boost::asio::deadline_timer(io));
+            pair = &timers.emplace_back(timerUsed,
+                                        boost::asio::deadline_timer(io));
         }
-        pair->first = true;
+        pair->first.used = true;
+        pair->first.level = threshold.level;
+        pair->first.direction = threshold.direction;
         pair->second.expires_from_now(boost::posix_time::seconds(waitTime));
         pair->second.async_wait(
             [this, pair, threshold](boost::system::error_code ec) {
-                pair->first = false;
+                pair->first.used = false;
 
                 if (ec == boost::asio::error::operation_aborted)
                 {