fw update: common code

new daemons to implement the flow as described in
https://github.com/openbmc/docs/blob/master/designs/code-update.md

- common/
  common code folder
  - common update flow
  - base class for the device specific update daemons

The new daemons are all following the generic template of Code Updater
daemon as outlined in the design.

The idea is that they are separate daemons (per device, as outlined in
the design) but share all the code that's not device specific.

Tested: next patch in series

Change-Id: If2438b8506aceb8c5313ec13a0bf7cb68f3cc279
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/common/pldm/pldm_package_util.cpp b/common/pldm/pldm_package_util.cpp
index c3e92e5..2d348a0 100644
--- a/common/pldm/pldm_package_util.cpp
+++ b/common/pldm/pldm_package_util.cpp
@@ -17,6 +17,9 @@
 
 #include <cassert>
 #include <cstring>
+#include <functional>
+
+PHOSPHOR_LOG2_USING;
 
 using namespace pldm::fw_update;
 
@@ -33,19 +36,19 @@
         pkgData.push_back(buf[i]);
     }
 
-    lg2::debug("parsing package header");
+    debug("parsing package header");
 
     std::unique_ptr<PackageParser> packageParser =
         pldm::fw_update::parsePackageHeader(pkgData);
 
     if (packageParser == nullptr)
     {
-        lg2::error("could not parse package header");
+        error("could not parse package header");
         return packageParser;
     }
 
-    lg2::debug("parsing package, pkg header size: {N}", "N",
-               packageParser->pkgHeaderSize);
+    debug("parsing package, pkg header size: {N}", "N",
+          packageParser->pkgHeaderSize);
 
     std::vector<uint8_t> pkgHeaderOnly;
     pkgHeaderOnly.insert(
@@ -57,24 +60,23 @@
     return packageParser;
 }
 
-int readImagePackage(FILE* file, uint8_t* package_data,
-                     const size_t package_size)
+int readImagePackage(FILE* file, uint8_t* packageData, const size_t packageSize)
 {
-    if (file == NULL || package_data == NULL)
+    if (file == NULL || packageData == NULL)
     {
         return 1;
     }
 
-    if (package_size == 0)
+    if (packageSize == 0)
     {
-        lg2::error("Package size is 0");
+        error("Package size is 0");
         return 1;
     }
 
-    lg2::debug("reading {NBYTES} bytes from file", "NBYTES", package_size);
+    debug("reading {NBYTES} bytes from file", "NBYTES", packageSize);
 
     // Read the package into memory
-    if (fread(package_data, 1, package_size, file) != package_size)
+    if (fread(packageData, 1, packageSize, file) != packageSize)
     {
         perror("Failed to read package data");
         fclose(file);
@@ -84,32 +86,42 @@
     return 0;
 }
 
-void* mmapImagePackage(sdbusplus::message::unix_fd image, size_t* size_out)
+std::unique_ptr<void, std::function<void(void*)>> mmapImagePackage(
+    sdbusplus::message::unix_fd image, size_t* sizeOut)
 {
-    lg2::debug("open fd {FD}", "FD", int(image));
+    debug("open fd {FD}", "FD", int(image));
 
     off_t size = lseek(image.fd, 0, SEEK_END);
 
     if (size < 0)
     {
-        lg2::error("failed to determine file size");
+        error("failed to determine file size");
         perror("error:");
-        return NULL;
+        return nullptr;
     }
 
-    *size_out = size;
+    *sizeOut = size;
 
-    lg2::debug("file size: {SIZE}", "SIZE", (uint64_t)size);
+    debug("file size: {SIZE}", "SIZE", (uint64_t)size);
 
     void* data = mmap(nullptr, size, PROT_READ, MAP_SHARED, image.fd, 0);
 
     if (data == MAP_FAILED)
     {
-        lg2::error("could not mmap the image");
-        return NULL;
+        error("could not mmap the image");
+        return nullptr;
     }
 
-    return data;
+    using mmapUniquePtr = std::unique_ptr<void, std::function<void(void*)>>;
+
+    mmapUniquePtr dataUnique(data, [size](void* arg) {
+        if (munmap(arg, size) != 0)
+        {
+            error("Failed to un map the PLDM package");
+        }
+    });
+
+    return dataUnique;
 }
 
 bool fwDeviceIDRecordMatchesCompatible(const FirmwareDeviceIDRecord& record,
@@ -130,8 +142,7 @@
 
     if (!std::holds_alternative<VendorDefinedDescriptorInfo>(v))
     {
-        lg2::debug(
-            "descriptor does not have the vendor defined descriptor info");
+        debug("descriptor does not have the vendor defined descriptor info");
         return false;
     }
 
@@ -154,7 +165,7 @@
 
     if (!desc.contains(0x1))
     {
-        lg2::error("did not find iana enterprise id");
+        error("did not find iana enterprise id");
         return false;
     }
 
@@ -162,7 +173,7 @@
 
     if (!std::holds_alternative<DescriptorData>(viana))
     {
-        lg2::error("did not find iana enterprise id");
+        error("did not find iana enterprise id");
         return false;
     }
 
@@ -170,7 +181,7 @@
 
     if (dd.size() != 4)
     {
-        lg2::error("descriptor data wrong size ( != 4) for vendor iana");
+        error("descriptor data wrong size ( != 4) for vendor iana");
         return false;
     }
 
@@ -204,7 +215,8 @@
 int extractMatchingComponentImage(
     const std::shared_ptr<PackageParser>& packageParser,
     const std::string& compatible, uint32_t vendorIANA,
-    uint32_t* component_offset_out, size_t* component_size_out)
+    uint32_t* componentOffsetOut, size_t* componentSizeOut,
+    std::string& componentVersionOut)
 {
     const FirmwareDeviceIDRecords& fwDeviceIdRecords =
         packageParser->getFwDeviceIDRecords();
@@ -215,7 +227,7 @@
 
     if (deviceDescriptorIndex < 0)
     {
-        lg2::error(
+        error(
             "did not find a matching device descriptor for {IANA}, {COMPATIBLE}",
             "IANA", lg2::hex, vendorIANA, "COMPATIBLE", compatible);
         return EXIT_FAILURE;
@@ -230,7 +242,7 @@
 
     if (ac.empty())
     {
-        lg2::error("did not find an applicable component image for the device");
+        error("did not find an applicable component image for the device");
         return EXIT_FAILURE;
     }
 
@@ -241,7 +253,7 @@
 
     if (component >= cs.size())
     {
-        lg2::error("applicable component out of bounds");
+        error("applicable component out of bounds");
         return EXIT_FAILURE;
     }
 
@@ -250,8 +262,9 @@
     CompLocationOffset off = std::get<5>(c);
     CompSize size = std::get<6>(c);
 
-    *component_offset_out = off;
-    *component_size_out = size;
+    *componentOffsetOut = off;
+    *componentSizeOut = size;
+    componentVersionOut = std::get<7>(c);
 
     return EXIT_SUCCESS;
 }
diff --git a/common/pldm/pldm_package_util.hpp b/common/pldm/pldm_package_util.hpp
index e510be1..4b544c2 100644
--- a/common/pldm/pldm_package_util.hpp
+++ b/common/pldm/pldm_package_util.hpp
@@ -4,6 +4,7 @@
 #include "sdbusplus/message/native_types.hpp"
 
 #include <cstdint>
+#include <functional>
 #include <memory>
 
 using namespace pldm::fw_update;
@@ -19,24 +20,27 @@
 
 // reads into a buffer, from file
 // @param file            the file to read from
-// @param package_data    the pre-allocated buffer for the package data
-// @param package_size    how many bytes to read from the file
-int readImagePackage(FILE* file, uint8_t* package_data, size_t package_size);
+// @param packageData     the pre-allocated buffer for the package data
+// @param packageSize     how many bytes to read from the file
+int readImagePackage(FILE* file, uint8_t* packageData, size_t packageSize);
 
 // @param image        file descriptor to the package
-// @param size_out     function will write the size of the package here
-// @returns            a pointer to the mmapped pldm package
-void* mmapImagePackage(sdbusplus::message::unix_fd image, size_t* size_out);
+// @param sizeOut      function will write the size of the package here
+// @returns            a unique pointer to the mmapped pldm package
+std::unique_ptr<void, std::function<void(void*)>> mmapImagePackage(
+    sdbusplus::message::unix_fd image, size_t* sizeOut);
 
 // @param packageParser          PackageParser instance
 // @param compatible             'compatible' string of device
 // @param vendorIANA             vendor iana of device
-// @param component_offset_out   function returns offset of component image
-// @param component_size_out     function returns size of component image
+// @param componentOffsetOut     function returns offset of component image
+// @param componentSizeOut       function returns size of component image
+// @param componentVersionOut    function returns version of component image
 // @returns                      0 on success
 int extractMatchingComponentImage(
     const std::shared_ptr<PackageParser>& packageParser,
     const std::string& compatible, uint32_t vendorIANA,
-    uint32_t* component_offset_out, size_t* size_out);
+    uint32_t* componentOffsetOut, size_t* componentSizeOut,
+    std::string& componentVersionOut);
 
 } // namespace pldm_package_util