Add the GetSubTree and GetSubTreePaths method to dbus_utility

There are currently many files that use the GetSubTree and
GetSubTreePaths methods. Since they are a general method, they are
defined in the dbus_utility.hpp file and will be further refactored
in subsequent patches.

Also, Updated the doPath method of NetworkProtocol synchronously.

Tested: Built bmcweb successfully and Validator passes
1. doGet NetworkProtocol
curl -k -H "X-Auth-Token: $token"
https://${bmc}/redfish/v1/Managers/bmc/NetworkProtocol
{
  "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol",
  "IPMI": {
    "Port": 623,
    "ProtocolEnabled": true
  },
  ...
}

2. change the ProtocolEnabled property to false
curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json"
-X PATCH -d '{"IPMI": {"ProtocolEnabled" :false}}'
https://${bmc}/redfish/v1/Managers/bmc/NetworkProtocol

3. doGet NetworkProtocol again
curl -k -H "X-Auth-Token: $token"
https://${bmc}/redfish/v1/Managers/bmc/NetworkProtocol
{
  "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol",
  "IPMI": {
    "Port": null,
    "ProtocolEnabled": false
  },
  ...
}

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I9ed3de74417d2662a7f433ea4a589f68f514a369
diff --git a/include/dbus_utility.hpp b/include/dbus_utility.hpp
index bd0d64b..393ffe3 100644
--- a/include/dbus_utility.hpp
+++ b/include/dbus_utility.hpp
@@ -24,7 +24,9 @@
 #include <cstddef>
 #include <cstdint>
 #include <filesystem>
+#include <functional>
 #include <regex>
+#include <span>
 #include <sstream>
 #include <string>
 #include <tuple>
@@ -140,5 +142,36 @@
         std::array<std::string, 0>());
 }
 
+inline void
+    getSubTree(const std::string& path, std::span<std::string> interfaces,
+               std::function<void(const boost::system::error_code&,
+                                  const MapperGetSubTreeResponse&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code ec,
+            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, 0, interfaces);
+}
+
+inline void getSubTreePaths(
+    const std::string& path, std::span<std::string> interfaces,
+    std::function<void(const boost::system::error_code&,
+                       const MapperGetSubTreePathsResponse&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code ec,
+            const MapperGetSubTreePathsResponse& subtreePaths) {
+        callback(ec, subtreePaths);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, 0,
+        interfaces);
+}
+
 } // namespace utility
 } // namespace dbus
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index 9d43bf4..5c473a6 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -320,9 +320,9 @@
     // Any remaining array elements should be removed
     currentNtpServers.erase(currentNtpServer, currentNtpServers.end());
 
-    crow::connections::systemBus->async_method_call(
+    auto respHandler =
         [asyncResp, currentNtpServers](
-            boost::system::error_code ec,
+            const boost::system::error_code& ec,
             const dbus::utility::MapperGetSubTreeResponse& subtree) {
         if (ec)
         {
@@ -357,13 +357,12 @@
                 }
             }
         }
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project", 0,
-        std::array<const char*, 1>{
-            "xyz.openbmc_project.Network.EthernetInterface"});
+    };
+
+    std::vector<std::string> interfaces = {
+        "xyz.openbmc_project.Network.EthernetInterface"};
+    dbus::utility::getSubTree("/xyz/openbmc_project", interfaces,
+                              std::move(respHandler));
 }
 
 inline void
@@ -371,9 +370,9 @@
                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& netBasePath)
 {
-    crow::connections::systemBus->async_method_call(
+    auto respHandler =
         [protocolEnabled, asyncResp,
-         netBasePath](const boost::system::error_code ec,
+         netBasePath](const boost::system::error_code& ec,
                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
         if (ec)
         {
@@ -412,13 +411,12 @@
                     dbus::utility::DbusVariantType{protocolEnabled});
             }
         }
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/control/service", 0,
-        std::array<const char*, 1>{
-            "xyz.openbmc_project.Control.Service.Attributes"});
+    };
+
+    std::vector<std::string> interfaces = {
+        "xyz.openbmc_project.Control.Service.Attributes"};
+    dbus::utility::getSubTree("/xyz/openbmc_project/control/service",
+                              interfaces, std::move(respHandler));
 }
 
 inline std::string getHostName()