Fix ProcessorSummary Count and Status

ProcessorSummary State is always Disabled and Count shows 0.
Fixed it by using correct interface to get these values.

Doing GET on Interface xyz.openbmc_project.State.Decorator.OperationalStatus
instead of xyz.openbmc_project.Inventory.Item.Cpu to get the State of CPU

Tested:
-- Ran GET request on the ComputerSystem node

--when 2 CPUs are present and functional

 "ProcessorSummary": {
    "Count": 2,
    "Status": {
      "State": "Enabled"
    }
  },

--when 2 CPUs are present but only 1 is functional
 "ProcessorSummary": {
    "Count": 2,
    "Status": {
      "State": "Enabled"
    }
  },

--when only 1 CPU present and functional
"ProcessorSummary": {
    "Count": 1,
    "Status": {
      "State": "Enabled"
    }
  },

--when only 1 CPU present and Not Functional
"ProcessorSummary": {
    "Count": 1,
    "Status": {
      "State": "Disabled"
    }
  },

--Ran Redfish-Service-Validator
ComputerSystem.v1_0_0.ProcessorSummary:Count
    value: 2 <class 'int'>
    has Type: Edm.Int64 Edm.Int64
    is Optional
    permission OData.Permission/Read
    Success
ComputerSystem.v1_0_0.ProcessorSummary:Status
    value: OrderedDict([('State', 'Enabled')]) <class 'collections.OrderedDict'>
    has Type: Resource.Status complex
    is Optional
    ***going into Complex
Resource.Status:State
    value: Enabled <class 'str'>
    has Type: Resource.State enum
    is Optional
    permission OData.Permission/Read
    Success
ProcessorSummary.Count                                  PASS
ProcessorSummary.Model                              Optional
ProcessorSummary.Status                              complex
ProcessorSummary.Status.State                           PASS

Change-Id: I953db79da965b4493d7bd0005820945383b1377c

Signed-off-by: Alpana Kumari <alpankum@in.ibm.com>
Change-Id: I1d5f76adf2ed8a66d8b27aeca59e0d1a5730e6a8
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 1a94139..6da9fc6 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -28,7 +28,73 @@
 namespace redfish
 {
 
-/**
+/*
+ * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
+ *
+ * @param[in] aResp Shared pointer for completing asynchronous calls
+ * @param[in] cpuPresenceState CPU present or not
+ *
+ * @return None.
+ */
+void modifyCpuPresenceState(std::shared_ptr<AsyncResp> aResp,
+                            const std::variant<bool> &cpuPresenceState)
+{
+    const bool *isCpuPresent = std::get_if<bool>(&cpuPresenceState);
+
+    if (isCpuPresent == nullptr)
+    {
+        messages::internalError(aResp->res);
+        return;
+    }
+    BMCWEB_LOG_DEBUG << "Cpu Present:" << *isCpuPresent;
+
+    nlohmann::json &procCount =
+        aResp->res.jsonValue["ProcessorSummary"]["Count"];
+    if (*isCpuPresent == true)
+    {
+        procCount = procCount.get<int>() + 1;
+    }
+    aResp->res.jsonValue["ProcessorSummary"]["Count"] = procCount;
+}
+
+/*
+ * @brief Update "ProcessorSummary" "Status" "State" based on
+ *        CPU Functional State
+ *
+ * @param[in] aResp Shared pointer for completing asynchronous calls
+ * @param[in] cpuFunctionalState is CPU functional true/false
+ *
+ * @return None.
+ */
+void modifyCpuFunctionalState(std::shared_ptr<AsyncResp> aResp,
+                              const std::variant<bool> &cpuFunctionalState)
+{
+    const bool *isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
+
+    if (isCpuFunctional == nullptr)
+    {
+        messages::internalError(aResp->res);
+        return;
+    }
+    BMCWEB_LOG_DEBUG << "Cpu Functional:" << *isCpuFunctional;
+
+    nlohmann::json &prevProcState =
+        aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
+
+    // Set it as Enabled if atleast one CPU is functional
+    // Update STATE only if previous State was Non_Functional and current CPU is
+    // Functional.
+    if (prevProcState == "Disabled")
+    {
+        if (*isCpuFunctional == true)
+        {
+            aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
+                "Enabled";
+        }
+    }
+}
+
+/*
  * @brief Retrieves computer system properties over dbus
  *
  * @param[in] aResp Shared pointer for completing asynchronous calls
@@ -128,11 +194,14 @@
                         {
                             BMCWEB_LOG_DEBUG
                                 << "Found Cpu, now get its properties.";
+
                             crow::connections::systemBus->async_method_call(
-                                [aResp](const boost::system::error_code ec,
-                                        const std::vector<
-                                            std::pair<std::string, VariantType>>
-                                            &properties) {
+                                [aResp, service{connection.first},
+                                 path(std::move(path))](
+                                    const boost::system::error_code ec,
+                                    const std::vector<
+                                        std::pair<std::string, VariantType>>
+                                        &properties) {
                                     if (ec)
                                     {
                                         BMCWEB_LOG_ERROR
@@ -143,31 +212,108 @@
                                     BMCWEB_LOG_DEBUG << "Got "
                                                      << properties.size()
                                                      << "Cpu properties.";
-                                    for (const auto &property : properties)
-                                    {
-                                        if (property.first == "ProcessorFamily")
-                                        {
-                                            const std::string *value =
-                                                sdbusplus::message::variant_ns::
-                                                    get_if<std::string>(
-                                                        &property.second);
-                                            if (value != nullptr)
-                                            {
-                                                nlohmann::json &procSummary =
-                                                    aResp->res.jsonValue
-                                                        ["ProcessorSumm"
-                                                         "ary"];
-                                                nlohmann::json &procCount =
-                                                    procSummary["Count"];
 
-                                                procCount =
-                                                    procCount.get<int>() + 1;
-                                                procSummary["Status"]["State"] =
-                                                    "Enabled";
-                                                procSummary["Model"] = *value;
+                                    if (properties.size() > 0)
+                                    {
+                                        for (const auto &property : properties)
+                                        {
+                                            if (property.first ==
+                                                "ProcessorFamily")
+                                            {
+                                                const std::string *value =
+                                                    sdbusplus::message::
+                                                        variant_ns::get_if<
+                                                            std::string>(
+                                                            &property.second);
+                                                if (value != nullptr)
+                                                {
+                                                    nlohmann::json
+                                                        &procSummary =
+                                                            aResp->res.jsonValue
+                                                                ["ProcessorSumm"
+                                                                 "ary"];
+                                                    nlohmann::json &procCount =
+                                                        procSummary["Count"];
+                                                    procCount =
+                                                        procCount.get<int>() +
+                                                        1;
+                                                    procSummary["Status"]
+                                                               ["State"] =
+                                                                   "Enabled";
+                                                    procSummary["Model"] =
+                                                        *value;
+                                                }
                                             }
                                         }
                                     }
+                                    else
+                                    {
+                                        auto getCpuPresenceState =
+                                            [aResp](
+                                                const boost::system::error_code
+                                                    ec,
+                                                const std::variant<bool>
+                                                    &cpuPresenceCheck) {
+                                                if (ec)
+                                                {
+                                                    BMCWEB_LOG_ERROR
+                                                        << "DBUS response "
+                                                           "error "
+                                                        << ec;
+                                                    return;
+                                                }
+                                                modifyCpuPresenceState(
+                                                    aResp, cpuPresenceCheck);
+                                            };
+
+                                        auto getCpuFunctionalState =
+                                            [aResp](
+                                                const boost::system::error_code
+                                                    ec,
+                                                const std::variant<bool>
+                                                    &cpuFunctionalCheck) {
+                                                if (ec)
+                                                {
+                                                    BMCWEB_LOG_ERROR
+                                                        << "DBUS response "
+                                                           "error "
+                                                        << ec;
+                                                    return;
+                                                }
+                                                modifyCpuFunctionalState(
+                                                    aResp, cpuFunctionalCheck);
+                                            };
+                                        // Get the Presence of CPU
+                                        crow::connections::systemBus
+                                            ->async_method_call(
+                                                std::move(getCpuPresenceState),
+                                                service, path,
+                                                "org.freedesktop.DBus."
+                                                "Properties",
+                                                "Get",
+                                                "xyz.openbmc_project.Inventory."
+                                                "Item",
+                                                "Present");
+
+                                        // Get the Functional State
+                                        crow::connections::systemBus
+                                            ->async_method_call(
+                                                std::move(
+                                                    getCpuFunctionalState),
+                                                service, path,
+                                                "org.freedesktop.DBus."
+                                                "Properties",
+                                                "Get",
+                                                "xyz.openbmc_project.State."
+                                                "Decorator."
+                                                "OperationalStatus",
+                                                "Functional");
+
+                                        // Get the MODEL from
+                                        // xyz.openbmc_project.Inventory.Decorator.Asset
+                                        // support it later as Model  is Empty
+                                        // currently.
+                                    }
                                 },
                                 connection.first, path,
                                 "org.freedesktop.DBus.Properties", "GetAll",