Refactor: Move serialize to ubi

Functions in serialize are specific to UBI, move it to ubi dir.

Tested: On the last commit of the patch series, run code update and
        factory reset on Witherspoon and all work fine.

Change-Id: I9176e638d9f3bfe0d424b57f8da4667a751cb5bd
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/ubi/Makefile.am.include b/ubi/Makefile.am.include
index c75293d..decf1e9 100644
--- a/ubi/Makefile.am.include
+++ b/ubi/Makefile.am.include
@@ -1,4 +1,5 @@
 openpower_update_manager_SOURCES += \
 	%reldir%/activation_ubi.cpp \
 	%reldir%/item_updater_ubi.cpp \
+	%reldir%/serialize.cpp \
 	%reldir%/watch.cpp
diff --git a/ubi/serialize.cpp b/ubi/serialize.cpp
new file mode 100644
index 0000000..7250a00
--- /dev/null
+++ b/ubi/serialize.cpp
@@ -0,0 +1,141 @@
+#include "config.h"
+
+#include "serialize.hpp"
+
+#include <cereal/archives/json.hpp>
+#include <experimental/filesystem>
+#include <fstream>
+#include <sdbusplus/server.hpp>
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+
+namespace fs = std::experimental::filesystem;
+
+void storeToFile(std::string versionId, uint8_t priority)
+{
+    auto bus = sdbusplus::bus::new_default();
+
+    if (!fs::is_directory(PERSIST_DIR))
+    {
+        fs::create_directories(PERSIST_DIR);
+    }
+
+    // store one copy in /var/lib/obmc/openpower-pnor-code-mgmt/[versionId]
+    auto varPath = PERSIST_DIR + versionId;
+    std::ofstream varOutput(varPath.c_str());
+    cereal::JSONOutputArchive varArchive(varOutput);
+    varArchive(cereal::make_nvp("priority", priority));
+
+    if (fs::is_directory(PNOR_RW_PREFIX + versionId))
+    {
+        // store another copy in /media/pnor-rw-[versionId]/[versionId]
+        auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
+        std::ofstream rwOutput(rwPath.c_str());
+        cereal::JSONOutputArchive rwArchive(rwOutput);
+        rwArchive(cereal::make_nvp("priority", priority));
+    }
+
+    // lastly, store the priority as an environment variable pnor-[versionId]
+    std::string serviceFile = "obmc-flash-bmc-setenv@pnor\\x2d" + versionId +
+                              "\\x3d" + std::to_string(priority) + ".service";
+    auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                      SYSTEMD_INTERFACE, "StartUnit");
+    method.append(serviceFile, "replace");
+    bus.call_noreply(method);
+}
+
+bool restoreFromFile(std::string versionId, uint8_t& priority)
+{
+    auto varPath = PERSIST_DIR + versionId;
+    if (fs::exists(varPath))
+    {
+        std::ifstream varInput(varPath.c_str(), std::ios::in);
+        try
+        {
+            cereal::JSONInputArchive varArchive(varInput);
+            varArchive(cereal::make_nvp("priority", priority));
+            return true;
+        }
+        catch (cereal::RapidJSONException& e)
+        {
+            fs::remove(varPath);
+        }
+    }
+
+    auto rwPath = PNOR_RW_PREFIX + versionId + "/" + versionId;
+    if (fs::exists(rwPath))
+    {
+        std::ifstream rwInput(rwPath.c_str(), std::ios::in);
+        try
+        {
+            cereal::JSONInputArchive rwArchive(rwInput);
+            rwArchive(cereal::make_nvp("priority", priority));
+            return true;
+        }
+        catch (cereal::RapidJSONException& e)
+        {
+            fs::remove(rwPath);
+        }
+    }
+
+    try
+    {
+        std::string devicePath = "/dev/mtd/u-boot-env";
+
+        if (fs::exists(devicePath) && !devicePath.empty())
+        {
+            std::ifstream input(devicePath.c_str());
+            std::string envVars;
+            std::getline(input, envVars);
+
+            std::string versionVar = "pnor-" + versionId + "=";
+            auto varPosition = envVars.find(versionVar);
+
+            if (varPosition != std::string::npos)
+            {
+                // Grab the environment variable for this versionId. These
+                // variables follow the format "pnor-[versionId]=[priority]\0"
+                auto var = envVars.substr(varPosition);
+                priority = std::stoi(var.substr(versionVar.length()));
+                return true;
+            }
+        }
+    }
+    catch (const std::exception& e)
+    {
+    }
+
+    return false;
+}
+
+void removeFile(std::string versionId)
+{
+    auto bus = sdbusplus::bus::new_default();
+
+    // Clear the environment variable pnor-[versionId].
+    std::string serviceFile =
+        "obmc-flash-bmc-setenv@pnor\\x2d" + versionId + ".service";
+    auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                      SYSTEMD_INTERFACE, "StartUnit");
+    method.append(serviceFile, "replace");
+    bus.call_noreply(method);
+
+    // Delete the file /var/lib/obmc/openpower-pnor-code-mgmt/[versionId].
+    // Note that removeFile() is called in the case of a version being deleted,
+    // so the file /media/pnor-rw-[versionId]/[versionId] will also be deleted
+    // along with its surrounding directory.
+    std::string path = PERSIST_DIR + versionId;
+    if (fs::exists(path))
+    {
+        fs::remove(path);
+    }
+}
+
+} // namespace updater
+} // namespace software
+} // namespace openpower
diff --git a/ubi/serialize.hpp b/ubi/serialize.hpp
new file mode 100644
index 0000000..e8860f3
--- /dev/null
+++ b/ubi/serialize.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <string>
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+
+/** @brief Serialization function - stores activation information to file
+ *  @param[in] versionId - The version for which to store information.
+ *  @param[in] priority - RedundancyPriority value for that version.
+ */
+void storeToFile(std::string versionId, uint8_t priority);
+
+/** @brief Serialization function - restores activation information from file
+ *  @param[in] versionId - The version for which to retrieve information.
+ *  @param[in] priority - RedundancyPriority pointer for that version.
+ *  @return true if restore was successful, false if not
+ */
+bool restoreFromFile(std::string versionId, uint8_t& priority);
+
+/** @brief Removes the serial file for a given version.
+ *  @param[in] versionId - The version for which to remove a file, if it exists.
+ */
+void removeFile(std::string versionId);
+
+} // namespace updater
+} // namespace software
+} // namespace openpower