Add Location information for Fan

This commit is to add Location/PartLocation/ServiceLabel information
according to the Redfish Fan schema.
If the `xyz.openbmc_project.Inventory.Decorator.LocationCode`
interface does not exist, the ServiceLabel information property is
not displayed.

ref: https://redfish.dmtf.org/schemas/v1/Fan.v1_3_0.json

Tested: Validator passes
'''
1. doGet method to get Fan ServiceLabel information
curl -k https://${bmc}/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans/fan0
{
  "@odata.id": "/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans/fan0",
  "@odata.type": "#Fan.v1_3_0.Fan",
  "Id": "fan0",
  "Manufacturer": "Delta",
  "Model": "7B5F",
  "Name": "Fan",
  "PartNumber": "02YK323",
  "SerialNumber": "YL12JP1C1234",
  "Slot": {
    "Location": {
      "PartLocation": {
        "ServiceLabel": "U78DB.ND0.WZS002U-A0"
      }
    }
  },
  "SparePartNumber": "02YK323",
  "Status": {
    "Health": "OK",
    "State": "Enabled"
  }
}
'''

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I1c3357d6dde654c71c8384139b8e3f03cf671e4e
Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
diff --git a/Redfish.md b/Redfish.md
index d72a2f8..cd03a7c 100644
--- a/Redfish.md
+++ b/Redfish.md
@@ -324,6 +324,7 @@
 
 #### Fan
 
+- Location
 - Manufacturer
 - Model
 - PartNumber
diff --git a/redfish-core/lib/fan.hpp b/redfish-core/lib/fan.hpp
index 0acb762..7680531 100644
--- a/redfish-core/lib/fan.hpp
+++ b/redfish-core/lib/fan.hpp
@@ -335,6 +335,30 @@
         });
 }
 
+inline void getFanLocation(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
+                           const std::string& fanPath,
+                           const std::string& service)
+{
+    sdbusplus::asio::getProperty<std::string>(
+        *crow::connections::systemBus, service, fanPath,
+        "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
+        [aResp](const boost::system::error_code& ec,
+                const std::string& property) {
+        if (ec)
+        {
+            if (ec.value() != EBADR)
+            {
+                BMCWEB_LOG_ERROR << "DBUS response error for Location"
+                                 << ec.value();
+                messages::internalError(aResp->res);
+            }
+            return;
+        }
+        aResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
+            property;
+        });
+}
+
 inline void
     afterGetValidFanPath(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& chassisId, const std::string& fanId,
@@ -344,6 +368,7 @@
     getFanState(asyncResp, fanPath, service);
     getFanHealth(asyncResp, fanPath, service);
     getFanAsset(asyncResp, fanPath, service);
+    getFanLocation(asyncResp, fanPath, service);
 }
 
 inline void doFanGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,