Populate Memory attributes

Add support to populate MemoryMedia, Slot and Socket attribute values
to dbus attributes.

Tested:
Memory attributes MemoryMedia,Slot and Socket are populated in dbus
through busctl command
Command:
busctl introspect xyz.openbmc_project.Smbios.MDR_V2
   /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm0
Response:
NAME                                                   TYPE      SIGNATURE RESULT/VALUE                             FLAGS
....

xyz.openbmc_project.Inventory.Decorator.LocationCode   interface -         -                                        -
.LocationCode                                          property  s         "BANK 0 CPU0_DIMM_A"                     emits-change writable
xyz.openbmc_project.Inventory.Item                     interface -         -                                        -
.Present                                               property  b         true                                     emits-change writable
.PrettyName                                            property  s         ""                                       emits-change writable
xyz.openbmc_project.Inventory.Item.Dimm                interface -         -                                        -

.MemoryAttributes                                      property  u         8388610                                  emits-change writable
.MemoryConfiguredSpeedInMhz                            property  q         19460                                    emits-change writable
.MemoryDataWidth                                       property  q         64                                       emits-change writable
.MemoryDeviceLocator                                   property  s         "BANK 0 CPU0_DIMM_A"                     emits-change writable
.MemoryMedia                                           property  s         "xyz.openbmc_project.Inventory.Item.D... emits-change writable
.MemorySizeInKB                                        property  u         1468006400                               emits-change writable
.MemoryTotalWidth                                      property  q         0                                        emits-change writable
.MemoryType                                            property  s         "xyz.openbmc_project.Inventory.Item.D... emits-change writable
.MemoryTypeDetail                                      property  s         "SynchronousRegistered"                  emits-change writable
.RevisionCode                                          property  q         0                                        emits-change writable
xyz.openbmc_project.Inventory.Item.Dimm.MemoryLocation interface -         -                                        -
.Channel                                               property  y         0                                        emits-change writable
.MemoryController                                      property  y         0                                        emits-change writable
.Slot                                                  property  y         65                                       emits-change writable
.Socket                                                property  y         1                                        emits-change writable
.....

Signed-off-by: poram srinivasa rao <poramx.srinivasa.rao@intel.com>
Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
Change-Id: Iabc2a58642167344711550b669ed4f207fb39d45
diff --git a/include/dimm.hpp b/include/dimm.hpp
index 72885ff..26ba3d8 100644
--- a/include/dimm.hpp
+++ b/include/dimm.hpp
@@ -21,6 +21,7 @@
 #include <xyz/openbmc_project/Inventory/Connector/Slot/server.hpp>
 #include <xyz/openbmc_project/Inventory/Decorator/Asset/server.hpp>
 #include <xyz/openbmc_project/Inventory/Decorator/LocationCode/server.hpp>
+#include <xyz/openbmc_project/Inventory/Item/Dimm/MemoryLocation/server.hpp>
 #include <xyz/openbmc_project/Inventory/Item/Dimm/server.hpp>
 #include <xyz/openbmc_project/Inventory/Item/server.hpp>
 #include <xyz/openbmc_project/State/Decorator/OperationalStatus/server.hpp>
@@ -37,9 +38,14 @@
 using EccType =
     sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::Ecc;
 
+using MemoryTechType =
+    sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::MemoryTech;
+
 class Dimm :
     sdbusplus::server::object_t<
         sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm>,
+    sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project::
+                                    inventory::item::dimm::MemoryLocation>,
     sdbusplus::server::object_t<
         sdbusplus::server::xyz::openbmc_project::inventory::decorator::Asset>,
     sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project::
@@ -69,6 +75,9 @@
             sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm>(
             bus, objPath.c_str()),
         sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project::
+                                        inventory::item::dimm::MemoryLocation>(
+            bus, objPath.c_str()),
+        sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project::
                                         inventory::decorator::Asset>(
             bus, objPath.c_str()),
         sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project::
@@ -106,6 +115,9 @@
     std::string partNumber(std::string value) override;
     std::string locationCode(std::string value) override;
     size_t memoryAttributes(size_t value) override;
+    MemoryTechType memoryMedia(MemoryTechType value) override;
+    uint8_t slot(uint8_t value) override;
+    uint8_t socket(uint8_t value) override;
     uint16_t memoryConfiguredSpeedInMhz(uint16_t value) override;
     bool functional(bool value) override;
     EccType ecc(EccType value) override;
@@ -126,6 +138,7 @@
     void dimmTypeDetail(const uint16_t detail);
     void dimmManufacturer(const uint8_t positionNum, const uint8_t structLen,
                           uint8_t* dataIn);
+    void dimmMedia(const uint8_t type);
     void dimmSerialNum(const uint8_t positionNum, const uint8_t structLen,
                        uint8_t* dataIn);
     void dimmPartNum(const uint8_t positionNum, const uint8_t structLen,
@@ -230,6 +243,12 @@
     {0x5, EccType::SingleBitECC}, {0x6, EccType::MultiBitECC},
     {0x7, EccType::NoECC}};
 
+const std::map<uint8_t, MemoryTechType> dimmMemoryTechTypeMap = {
+    {0x1, MemoryTechType::Other},      {0x2, MemoryTechType::Unknown},
+    {0x3, MemoryTechType::DRAM},       {0x4, MemoryTechType::NVDIMM_N},
+    {0x5, MemoryTechType::NVDIMM_F},   {0x6, MemoryTechType::NVDIMM_P},
+    {0x7, MemoryTechType::IntelOptane}};
+
 } // namespace smbios
 
 } // namespace phosphor
diff --git a/src/dimm.cpp b/src/dimm.cpp
index 72f5ed3..2138886 100644
--- a/src/dimm.cpp
+++ b/src/dimm.cpp
@@ -21,6 +21,8 @@
 #include <boost/algorithm/string.hpp>
 #include <phosphor-logging/elog-errors.hpp>
 
+#include <regex>
+
 namespace phosphor
 {
 namespace smbios
@@ -93,6 +95,7 @@
     dimmSerialNum(memoryInfo->serialNum, memoryInfo->length, dataIn);
     dimmPartNum(memoryInfo->partNum, memoryInfo->length, dataIn);
     memoryAttributes(memoryInfo->attributes);
+    dimmMedia(memoryInfo->memoryTechnology);
     memoryConfiguredSpeedInMhz(memoryInfo->confClockSpeed);
 
     updateEccType(memoryInfo->phyArrayHandle);
@@ -202,6 +205,43 @@
     memoryDeviceLocator(result);
 
     locationCode(result);
+    const std::string substrCpu = "CPU";
+    auto cpuPos = deviceLocator.find(substrCpu);
+
+    if (cpuPos != std::string::npos)
+    {
+        std::string socketString =
+            deviceLocator.substr(cpuPos + substrCpu.length(), 1);
+        try
+        {
+            uint8_t socketNum =
+                static_cast<uint8_t>(std::stoi(socketString) + 1);
+            socket(socketNum);
+        }
+        catch (const sdbusplus::exception_t& ex)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "std::stoi operation failed ",
+                phosphor::logging::entry("ERROR=%s", ex.what()));
+        }
+    }
+
+    const std::string substrDimm = "DIMM";
+    auto dimmPos = deviceLocator.find(substrDimm);
+
+    if (dimmPos != std::string::npos)
+    {
+        std::string slotString =
+            deviceLocator.substr(dimmPos + substrDimm.length() + 1);
+        /* slotString is extracted from substrDimm (DIMM_A) if slotString is
+         * single alphabet like A, B , C.. then assign ASCII value of slotString
+         * to slot */
+        if ((std::regex_match(slotString, std::regex("^[A-Za-z]+$"))) &&
+            (slotString.length() == 1))
+        {
+            slot(static_cast<uint8_t>(toupper(slotString[0])));
+        }
+    }
 }
 
 std::string Dimm::memoryDeviceLocator(std::string value)
@@ -229,6 +269,26 @@
         memoryType(value);
 }
 
+void Dimm::dimmMedia(const uint8_t type)
+{
+    std::map<uint8_t, MemoryTechType>::const_iterator it =
+        dimmMemoryTechTypeMap.find(type);
+    if (it == dimmMemoryTechTypeMap.end())
+    {
+        memoryMedia(MemoryTechType::Unknown);
+    }
+    else
+    {
+        memoryMedia(it->second);
+    }
+}
+
+MemoryTechType Dimm::memoryMedia(MemoryTechType value)
+{
+    return sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::
+        memoryMedia(value);
+}
+
 void Dimm::dimmTypeDetail(uint16_t detail)
 {
     std::string result;
@@ -325,6 +385,18 @@
         memoryAttributes(value);
 }
 
+uint8_t Dimm::slot(uint8_t value)
+{
+    return sdbusplus::server::xyz::openbmc_project::inventory::item::dimm::
+        MemoryLocation::slot(value);
+}
+
+uint8_t Dimm::socket(uint8_t value)
+{
+    return sdbusplus::server::xyz::openbmc_project::inventory::item::dimm::
+        MemoryLocation::socket(value);
+}
+
 uint16_t Dimm::memoryConfiguredSpeedInMhz(uint16_t value)
 {
     return sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::