system: implement firmware status in czechlight-system

This patch implements filling the data in the
czechlight-system:firmware/firmware-slot list. The list is supposed to
hold the basic information about the current firmware slot OS version
and boot status. All the data are provided by RAUC.

Because RAUC provides the slot data vis D-Bus only when explicitly asked
by GetSlotStatus function over and there are no signals (or signals about
property changes), we have to actually call the function to retrieve the
data.

However, there is one catch. RAUC will not provide us with the data when
there is another operation in progress (i.e., when somebody invoked
installation). Therefore, we cache the data and we provide the caller
with the cached data whenever we can't fetch fresh data.

There is, however, another catch. The data can change any time, not only
after installation of new bundle. They can also change whenever somebody
marks a slot bad/good. We can't capture that change unless we are
querying the RAUC periodically, which we do not want to.

Let's say, somebody marks the slot bad and then run an installation.
During the installation he/she asks for the slot data. However, RAUC
won't let us fetch the data (because it is fully devoted to the
installation process), so we would return the old data, where the slot
is still good.

So, at least, we update the cache also before and after any installation,
because that is the only long-running operation in RAUC.

Change-Id: I890bf6813f15f9629a0c6acd516216e88d6cd986
diff --git a/src/system/Firmware.h b/src/system/Firmware.h
index 5ff6723..0d81b02 100644
--- a/src/system/Firmware.h
+++ b/src/system/Firmware.h
@@ -20,12 +20,19 @@
     Firmware(std::shared_ptr<::sysrepo::Connection> srConn, sdbus::IConnection& dbusConnectionSignals, sdbus::IConnection& dbusConnectionMethods);
 
 private:
-    std::shared_ptr<::sysrepo::Connection> m_srConn;
-    std::shared_ptr<::sysrepo::Session> m_srSessionOps, m_srSessionRPC;
-    std::shared_ptr<::sysrepo::Subscribe> m_srSubscribeOps, m_srSubscribeRPC;
     std::shared_ptr<RAUC> m_rauc;
     std::mutex m_mtx; //! @brief locks access to cached elements that are shared from multiple threads
     std::string m_installStatus, m_installMessage;
+    std::map<std::string, std::string> m_slotStatusCache;
     velia::Log m_log;
+    std::shared_ptr<::sysrepo::Connection> m_srConn;
+    std::shared_ptr<::sysrepo::Session> m_srSessionOps, m_srSessionRPC;
+    /* Subscribe objects must be destroyed before shared_ptr<RAUC> and other objects that are used in the callbacks
+     * (m_slotStatusCache, m_installStatus, m_installMessage). If they're not, the objects might be already destroyed
+     * while executing the callback.
+     */
+    std::shared_ptr<::sysrepo::Subscribe> m_srSubscribeOps, m_srSubscribeRPC;
+
+    std::unique_lock<std::mutex> updateSlotStatus();
 };
 }