Verify the value of the tempX_label file

- The intent behind this commit is to verify the value of
  the tempX_label file.

- In the future, the value of this file will be changed to
  `D0000002` (OCC sensor ID).
  - OCC Sensor Ids(D0000002)
  - First byte is type                 - D0
  - Second byte is reserved            - 00
  - Third+Fourth bytes are instance id - 0002

Tested: built openpower-occ-control successfully and unit test worked

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I5e89ce9592898f79b9fe926dd7bbe5691bf535a5
diff --git a/test/utest.cpp b/test/utest.cpp
index 04fa492..ff75a60 100644
--- a/test/utest.cpp
+++ b/test/utest.cpp
@@ -1,4 +1,5 @@
 #include "powercap.hpp"
+#include "utils.hpp"
 
 #include <experimental/filesystem>
 #include <occ_events.hpp>
@@ -7,6 +8,7 @@
 #include <gtest/gtest.h>
 
 using namespace open_power::occ;
+using namespace open_power::occ::utils;
 
 class VerifyOccInput : public ::testing::Test
 {
@@ -66,3 +68,17 @@
 
     EXPECT_STREQ(parsed.c_str(), "bar");
 }
+
+TEST(VerifyLabelValue, checkLabelValue)
+{
+    const std::string value = "D0000002";
+
+    auto labelValue = checkLabelValue(value);
+    EXPECT_NE(labelValue, std::nullopt);
+
+    std::string reType = "D0";
+    uint16_t reID = 2;
+    auto& [type, instanceID] = *labelValue;
+    EXPECT_EQ(type, reType);
+    EXPECT_EQ(instanceID, reID);
+}
diff --git a/utils.cpp b/utils.cpp
index 9a412a3..b1fd8b6 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -75,6 +75,40 @@
     return value;
 }
 
+std::optional<LABELVALUE> checkLabelValue(const std::string& value)
+{
+    // The ID 0xD0000002 is only 4 bytes long, but when converted to a string it
+    // is 8 characters long
+    // eg: Dimm2, the lable file is `D0000002` so value
+    // length = 2 byte(type) + 2 byte(reserve) + 4 byte(instace ID)
+    size_t valueLen = value.length();
+    size_t typeLen = 2;
+    size_t reserveLen = 2;
+    size_t instanceIDLen = 4;
+    if (valueLen != typeLen + reserveLen + instanceIDLen)
+    {
+        return std::nullopt;
+    }
+
+    size_t offset = 0;
+    std::string type = value.substr(offset, typeLen);
+    offset += typeLen;
+    std::string reserve = value.substr(offset, reserveLen);
+    offset += reserveLen;
+
+    if ("00" != reserve)
+    {
+        return std::nullopt;
+    }
+
+    const char* start = value.data() + offset;
+    uint16_t instanceID = static_cast<uint16_t>(std::strtol(start, NULL, 16));
+
+    LABELVALUE labelValue{type, instanceID};
+
+    return std::make_optional(std::move(labelValue));
+}
+
 } // namespace utils
 } // namespace occ
 } // namespace open_power
diff --git a/utils.hpp b/utils.hpp
index 1d173a3..6254ed7 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -1,13 +1,19 @@
 #pragma once
 
+#include <optional>
 #include <sdbusplus/bus.hpp>
 #include <string>
+#include <tuple>
+
 namespace open_power
 {
 namespace occ
 {
 namespace utils
 {
+
+using LABELVALUE = std::tuple<std::string, uint16_t>;
+
 constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
 constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper";
 constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
@@ -49,6 +55,15 @@
                                 const std::string& interface,
                                 const std::string& propertyName);
 
+/**
+ * @brief Check the value of the `tempX_label` file
+ *
+ * @param[in] value  -  the value of the `tempX_label` file
+ *
+ * @return              Sensors type and Sensors ID
+ */
+std::optional<LABELVALUE> checkLabelValue(const std::string& value);
+
 } // namespace utils
 } // namespace occ
 } // namespace open_power