xref: /openbmc/bmcweb/features/redfish/lib/network_protocol.hpp (revision 20e6ea5dbfaa04f4298116281ddfb997847189ce)
170141561SBorawski.Lukasz /*
270141561SBorawski.Lukasz // Copyright (c) 2018 Intel Corporation
370141561SBorawski.Lukasz //
470141561SBorawski.Lukasz // Licensed under the Apache License, Version 2.0 (the "License");
570141561SBorawski.Lukasz // you may not use this file except in compliance with the License.
670141561SBorawski.Lukasz // You may obtain a copy of the License at
770141561SBorawski.Lukasz //
870141561SBorawski.Lukasz //      http://www.apache.org/licenses/LICENSE-2.0
970141561SBorawski.Lukasz //
1070141561SBorawski.Lukasz // Unless required by applicable law or agreed to in writing, software
1170141561SBorawski.Lukasz // distributed under the License is distributed on an "AS IS" BASIS,
1270141561SBorawski.Lukasz // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1370141561SBorawski.Lukasz // See the License for the specific language governing permissions and
1470141561SBorawski.Lukasz // limitations under the License.
1570141561SBorawski.Lukasz */
1670141561SBorawski.Lukasz #pragma once
1770141561SBorawski.Lukasz 
183a8a0088SKowalski, Kamil #include "error_messages.hpp"
1970141561SBorawski.Lukasz #include "node.hpp"
2070141561SBorawski.Lukasz 
21*20e6ea5dSraviteja-b #include <optional>
22*20e6ea5dSraviteja-b #include <utils/json_utils.hpp>
23abf2add6SEd Tanous #include <variant>
241abe55efSEd Tanous namespace redfish
251abe55efSEd Tanous {
2670141561SBorawski.Lukasz 
271abe55efSEd Tanous enum NetworkProtocolUnitStructFields
281abe55efSEd Tanous {
293a8a0088SKowalski, Kamil     NET_PROTO_UNIT_NAME,
303a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DESC,
313a8a0088SKowalski, Kamil     NET_PROTO_UNIT_LOAD_STATE,
323a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ACTIVE_STATE,
333a8a0088SKowalski, Kamil     NET_PROTO_UNIT_SUB_STATE,
343a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DEVICE,
353a8a0088SKowalski, Kamil     NET_PROTO_UNIT_OBJ_PATH,
363a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_0,
373a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_EMPTY,
383a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_ROOT_PATH
393a8a0088SKowalski, Kamil };
403a8a0088SKowalski, Kamil 
411abe55efSEd Tanous enum NetworkProtocolListenResponseElements
421abe55efSEd Tanous {
433a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_TYPE,
443a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_STREAM
453a8a0088SKowalski, Kamil };
463a8a0088SKowalski, Kamil 
473a8a0088SKowalski, Kamil /**
483a8a0088SKowalski, Kamil  * @brief D-Bus Unit structure returned in array from ListUnits Method
493a8a0088SKowalski, Kamil  */
503a8a0088SKowalski, Kamil using UnitStruct =
513a8a0088SKowalski, Kamil     std::tuple<std::string, std::string, std::string, std::string, std::string,
523a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path, uint32_t,
533a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path>;
543a8a0088SKowalski, Kamil 
551abe55efSEd Tanous struct ServiceConfiguration
561abe55efSEd Tanous {
57865fbb75SEd Tanous     const char* serviceName;
58865fbb75SEd Tanous     const char* socketPath;
593a8a0088SKowalski, Kamil };
603a8a0088SKowalski, Kamil 
61865fbb75SEd Tanous const static boost::container::flat_map<const char*, ServiceConfiguration>
62865fbb75SEd Tanous     protocolToDBus{
63865fbb75SEd Tanous         {"SSH",
645ded8c79SJennifer Lee          {"dropbear.socket",
65865fbb75SEd Tanous           "/org/freedesktop/systemd1/unit/dropbear_2esocket"}},
66865fbb75SEd Tanous         {"HTTPS",
675ded8c79SJennifer Lee          {"bmcweb.service",
685ded8c79SJennifer Lee           "/org/freedesktop/systemd1/unit/"
695ded8c79SJennifer Lee           "bmcweb_2esocket"}}, //"/org/freedesktop/systemd1/unit/phosphor_2dgevent_2esocket"}},
70865fbb75SEd Tanous         {"IPMI",
715ded8c79SJennifer Lee          {"phosphor-ipmi-net.socket", "/org/freedesktop/systemd1/unit/"
725ded8c79SJennifer Lee                                       "phosphor_2dipmi_2dnet_2esocket"}}};
733a8a0088SKowalski, Kamil 
74*20e6ea5dSraviteja-b inline void extractNTPServersData(const GetManagedObjects& dbus_data,
75*20e6ea5dSraviteja-b                                   std::vector<std::string>& ntpData)
76*20e6ea5dSraviteja-b {
77*20e6ea5dSraviteja-b     for (const auto& obj : dbus_data)
78*20e6ea5dSraviteja-b     {
79*20e6ea5dSraviteja-b         for (const auto& ifacePair : obj.second)
80*20e6ea5dSraviteja-b         {
81*20e6ea5dSraviteja-b             if (obj.first == "/xyz/openbmc_project/network/eth0")
82*20e6ea5dSraviteja-b             {
83*20e6ea5dSraviteja-b                 if (ifacePair.first ==
84*20e6ea5dSraviteja-b                     "xyz.openbmc_project.Network.EthernetInterface")
85*20e6ea5dSraviteja-b                 {
86*20e6ea5dSraviteja-b                     for (const auto& propertyPair : ifacePair.second)
87*20e6ea5dSraviteja-b                     {
88*20e6ea5dSraviteja-b                         if (propertyPair.first == "NTPServers")
89*20e6ea5dSraviteja-b                         {
90*20e6ea5dSraviteja-b                             const std::vector<std::string>* ntpServers =
91*20e6ea5dSraviteja-b                                 sdbusplus::message::variant_ns::get_if<
92*20e6ea5dSraviteja-b                                     std::vector<std::string>>(
93*20e6ea5dSraviteja-b                                     &propertyPair.second);
94*20e6ea5dSraviteja-b                             if (ntpServers != nullptr)
95*20e6ea5dSraviteja-b                             {
96*20e6ea5dSraviteja-b                                 ntpData = std::move(*ntpServers);
97*20e6ea5dSraviteja-b                             }
98*20e6ea5dSraviteja-b                         }
99*20e6ea5dSraviteja-b                     }
100*20e6ea5dSraviteja-b                 }
101*20e6ea5dSraviteja-b             }
102*20e6ea5dSraviteja-b         }
103*20e6ea5dSraviteja-b     }
104*20e6ea5dSraviteja-b }
105*20e6ea5dSraviteja-b 
106*20e6ea5dSraviteja-b template <typename CallbackFunc>
107*20e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback)
108*20e6ea5dSraviteja-b {
109*20e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
110*20e6ea5dSraviteja-b         [callback{std::move(callback)}](
111*20e6ea5dSraviteja-b             const boost::system::error_code error_code,
112*20e6ea5dSraviteja-b             const GetManagedObjects& dbus_data) {
113*20e6ea5dSraviteja-b             std::vector<std::string> ntpServers;
114*20e6ea5dSraviteja-b 
115*20e6ea5dSraviteja-b             if (error_code)
116*20e6ea5dSraviteja-b             {
117*20e6ea5dSraviteja-b                 callback(false, ntpServers);
118*20e6ea5dSraviteja-b                 return;
119*20e6ea5dSraviteja-b             }
120*20e6ea5dSraviteja-b 
121*20e6ea5dSraviteja-b             extractNTPServersData(dbus_data, ntpServers);
122*20e6ea5dSraviteja-b 
123*20e6ea5dSraviteja-b             callback(true, ntpServers);
124*20e6ea5dSraviteja-b         },
125*20e6ea5dSraviteja-b         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
126*20e6ea5dSraviteja-b         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
127*20e6ea5dSraviteja-b };
128*20e6ea5dSraviteja-b 
1291abe55efSEd Tanous class NetworkProtocol : public Node
1301abe55efSEd Tanous {
13170141561SBorawski.Lukasz   public:
1321abe55efSEd Tanous     NetworkProtocol(CrowApp& app) :
13397b7ccf3SEd Tanous         Node(app, "/redfish/v1/Managers/bmc/NetworkProtocol")
1341abe55efSEd Tanous     {
1354b1b8683SBorawski.Lukasz         entityPrivileges = {
1364b1b8683SBorawski.Lukasz             {boost::beast::http::verb::get, {{"Login"}}},
137e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
138e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
139e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
140e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
141e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
14270141561SBorawski.Lukasz     }
14370141561SBorawski.Lukasz 
14470141561SBorawski.Lukasz   private:
14555c7b7a2SEd Tanous     void doGet(crow::Response& res, const crow::Request& req,
1461abe55efSEd Tanous                const std::vector<std::string>& params) override
1471abe55efSEd Tanous     {
1483a8a0088SKowalski, Kamil         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
1493a8a0088SKowalski, Kamil 
1503a8a0088SKowalski, Kamil         getData(asyncResp);
15170141561SBorawski.Lukasz     }
15270141561SBorawski.Lukasz 
1531abe55efSEd Tanous     std::string getHostName() const
1541abe55efSEd Tanous     {
15570141561SBorawski.Lukasz         std::string hostName;
15670141561SBorawski.Lukasz 
15770141561SBorawski.Lukasz         std::array<char, HOST_NAME_MAX> hostNameCStr;
1581abe55efSEd Tanous         if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
1591abe55efSEd Tanous         {
16070141561SBorawski.Lukasz             hostName = hostNameCStr.data();
16170141561SBorawski.Lukasz         }
16270141561SBorawski.Lukasz         return hostName;
16370141561SBorawski.Lukasz     }
16470141561SBorawski.Lukasz 
165*20e6ea5dSraviteja-b     void getNTPProtocolEnabled(const std::shared_ptr<AsyncResp>& asyncResp)
166*20e6ea5dSraviteja-b     {
167*20e6ea5dSraviteja-b         crow::connections::systemBus->async_method_call(
168*20e6ea5dSraviteja-b             [asyncResp](const boost::system::error_code error_code,
169*20e6ea5dSraviteja-b                         const std::variant<std::string>& timeSyncMethod) {
170*20e6ea5dSraviteja-b                 const std::string* s =
171*20e6ea5dSraviteja-b                     std::get_if<std::string>(&timeSyncMethod);
172*20e6ea5dSraviteja-b 
173*20e6ea5dSraviteja-b                 if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP")
174*20e6ea5dSraviteja-b                 {
175*20e6ea5dSraviteja-b                     asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true;
176*20e6ea5dSraviteja-b                 }
177*20e6ea5dSraviteja-b                 else if (*s == "xyz.openbmc_project.Time.Synchronization."
178*20e6ea5dSraviteja-b                                "Method.Manual")
179*20e6ea5dSraviteja-b                 {
180*20e6ea5dSraviteja-b                     asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false;
181*20e6ea5dSraviteja-b                 }
182*20e6ea5dSraviteja-b             },
183*20e6ea5dSraviteja-b             "xyz.openbmc_project.Settings",
184*20e6ea5dSraviteja-b             "/xyz/openbmc_project/time/sync_method",
185*20e6ea5dSraviteja-b             "org.freedesktop.DBus.Properties", "Get",
186*20e6ea5dSraviteja-b             "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod");
187*20e6ea5dSraviteja-b     }
188*20e6ea5dSraviteja-b 
1891abe55efSEd Tanous     void getData(const std::shared_ptr<AsyncResp>& asyncResp)
1901abe55efSEd Tanous     {
1910f74e643SEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
1920f74e643SEd Tanous             "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol";
1930f74e643SEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
1940f74e643SEd Tanous             "/redfish/v1/Managers/bmc/NetworkProtocol";
1950f74e643SEd Tanous         asyncResp->res.jsonValue["@odata.context"] =
1960f74e643SEd Tanous             "/redfish/v1/"
1970f74e643SEd Tanous             "$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol";
1980f74e643SEd Tanous         asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
1990f74e643SEd Tanous         asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
2000f74e643SEd Tanous         asyncResp->res.jsonValue["Description"] = "Manager Network Service";
2010f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
2020f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
2030f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
2040f74e643SEd Tanous 
2050f74e643SEd Tanous         for (auto& protocol : protocolToDBus)
2060f74e643SEd Tanous         {
2070f74e643SEd Tanous             asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false;
2080f74e643SEd Tanous         }
2090f74e643SEd Tanous 
2100f74e643SEd Tanous         asyncResp->res.jsonValue["HostName"] = getHostName();
2113a8a0088SKowalski, Kamil 
212*20e6ea5dSraviteja-b         getNTPProtocolEnabled(asyncResp);
213*20e6ea5dSraviteja-b 
214*20e6ea5dSraviteja-b         // TODO Get eth0 interface data, and call the below callback for JSON
215*20e6ea5dSraviteja-b         // preparation
216*20e6ea5dSraviteja-b         getEthernetIfaceData(
217*20e6ea5dSraviteja-b             [this, asyncResp](const bool& success,
218*20e6ea5dSraviteja-b                               const std::vector<std::string>& ntpServers) {
219*20e6ea5dSraviteja-b                 if (!success)
220*20e6ea5dSraviteja-b                 {
221*20e6ea5dSraviteja-b                     messages::resourceNotFound(asyncResp->res,
222*20e6ea5dSraviteja-b                                                "EthernetInterface", "eth0");
223*20e6ea5dSraviteja-b                     return;
224*20e6ea5dSraviteja-b                 }
225*20e6ea5dSraviteja-b                 asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
226*20e6ea5dSraviteja-b             });
227*20e6ea5dSraviteja-b 
228865fbb75SEd Tanous         crow::connections::systemBus->async_method_call(
229865fbb75SEd Tanous             [asyncResp](const boost::system::error_code ec,
2303a8a0088SKowalski, Kamil                         const std::vector<UnitStruct>& resp) {
2311abe55efSEd Tanous                 if (ec)
2321abe55efSEd Tanous                 {
2333a8a0088SKowalski, Kamil                     asyncResp->res.jsonValue = nlohmann::json::object();
234f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
235865fbb75SEd Tanous                     return;
2363a8a0088SKowalski, Kamil                 }
2373a8a0088SKowalski, Kamil 
2381abe55efSEd Tanous                 for (auto& unit : resp)
2391abe55efSEd Tanous                 {
2401abe55efSEd Tanous                     for (auto& kv : protocolToDBus)
2411abe55efSEd Tanous                     {
2425ded8c79SJennifer Lee                         if (kv.second.serviceName !=
2431abe55efSEd Tanous                             std::get<NET_PROTO_UNIT_NAME>(unit))
2441abe55efSEd Tanous                         {
245865fbb75SEd Tanous                             continue;
24670141561SBorawski.Lukasz                         }
247865fbb75SEd Tanous                         const char* service = kv.first;
248865fbb75SEd Tanous                         const char* socketPath = kv.second.socketPath;
24970141561SBorawski.Lukasz 
250865fbb75SEd Tanous                         asyncResp->res.jsonValue[service]["ProtocolEnabled"] =
2515ded8c79SJennifer Lee                             (std::get<NET_PROTO_UNIT_SUB_STATE>(unit) ==
2525ded8c79SJennifer Lee                              "running") ||
2535ded8c79SJennifer Lee                             (std::get<NET_PROTO_UNIT_SUB_STATE>(unit) ==
2545ded8c79SJennifer Lee                              "listening");
255865fbb75SEd Tanous 
256865fbb75SEd Tanous                         crow::connections::systemBus->async_method_call(
25743b761d0SEd Tanous                             [asyncResp, service{std::string(service)}](
258865fbb75SEd Tanous                                 const boost::system::error_code ec,
259abf2add6SEd Tanous                                 const std::variant<std::vector<std::tuple<
260abf2add6SEd Tanous                                     std::string, std::string>>>& resp) {
2611abe55efSEd Tanous                                 if (ec)
2621abe55efSEd Tanous                                 {
263a08b46ccSJason M. Bills                                     messages::internalError(asyncResp->res);
264865fbb75SEd Tanous                                     return;
2653a8a0088SKowalski, Kamil                                 }
266abf2add6SEd Tanous                                 const std::vector<
267abf2add6SEd Tanous                                     std::tuple<std::string, std::string>>*
268abf2add6SEd Tanous                                     responsePtr = std::get_if<std::vector<
269abf2add6SEd Tanous                                         std::tuple<std::string, std::string>>>(
2701b6b96c5SEd Tanous                                         &resp);
2711abe55efSEd Tanous                                 if (responsePtr == nullptr ||
2721abe55efSEd Tanous                                     responsePtr->size() < 1)
2731abe55efSEd Tanous                                 {
274865fbb75SEd Tanous                                     return;
27570141561SBorawski.Lukasz                                 }
27670141561SBorawski.Lukasz 
277865fbb75SEd Tanous                                 const std::string& listenStream =
2781abe55efSEd Tanous                                     std::get<NET_PROTO_LISTEN_STREAM>(
2791abe55efSEd Tanous                                         (*responsePtr)[0]);
2801abe55efSEd Tanous                                 std::size_t lastColonPos =
2811abe55efSEd Tanous                                     listenStream.rfind(":");
2821abe55efSEd Tanous                                 if (lastColonPos == std::string::npos)
2831abe55efSEd Tanous                                 {
284865fbb75SEd Tanous                                     // Not a port
285865fbb75SEd Tanous                                     return;
286865fbb75SEd Tanous                                 }
2871abe55efSEd Tanous                                 std::string portStr =
2881abe55efSEd Tanous                                     listenStream.substr(lastColonPos + 1);
289865fbb75SEd Tanous                                 char* endPtr = nullptr;
2901abe55efSEd Tanous                                 // Use strtol instead of stroi to avoid
2911abe55efSEd Tanous                                 // exceptions
2921abe55efSEd Tanous                                 long port =
2931abe55efSEd Tanous                                     std::strtol(portStr.c_str(), &endPtr, 10);
294865fbb75SEd Tanous 
2951abe55efSEd Tanous                                 if (*endPtr != '\0' || portStr.empty())
2961abe55efSEd Tanous                                 {
297865fbb75SEd Tanous                                     // Invalid value
2981abe55efSEd Tanous                                     asyncResp->res.jsonValue[service]["Port"] =
2991abe55efSEd Tanous                                         nullptr;
3001abe55efSEd Tanous                                 }
3011abe55efSEd Tanous                                 else
3021abe55efSEd Tanous                                 {
303865fbb75SEd Tanous                                     // Everything OK
3041abe55efSEd Tanous                                     asyncResp->res.jsonValue[service]["Port"] =
3051abe55efSEd Tanous                                         port;
306865fbb75SEd Tanous                                 }
307865fbb75SEd Tanous                             },
308865fbb75SEd Tanous                             "org.freedesktop.systemd1", socketPath,
309865fbb75SEd Tanous                             "org.freedesktop.DBus.Properties", "Get",
310865fbb75SEd Tanous                             "org.freedesktop.systemd1.Socket", "Listen");
311865fbb75SEd Tanous                     }
312865fbb75SEd Tanous                 }
313865fbb75SEd Tanous             },
314865fbb75SEd Tanous             "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
315865fbb75SEd Tanous             "org.freedesktop.systemd1.Manager", "ListUnits");
316865fbb75SEd Tanous     }
317501be32bSraviteja-b 
318501be32bSraviteja-b     void handleHostnamePatch(const std::string& hostName,
319501be32bSraviteja-b                              const std::shared_ptr<AsyncResp>& asyncResp)
320501be32bSraviteja-b     {
321501be32bSraviteja-b         crow::connections::systemBus->async_method_call(
322501be32bSraviteja-b             [asyncResp](const boost::system::error_code ec) {
323501be32bSraviteja-b                 if (ec)
324501be32bSraviteja-b                 {
325501be32bSraviteja-b                     messages::internalError(asyncResp->res);
326501be32bSraviteja-b                     return;
327501be32bSraviteja-b                 }
328501be32bSraviteja-b                 messages::success(asyncResp->res);
329501be32bSraviteja-b             },
330501be32bSraviteja-b             "xyz.openbmc_project.Network",
331501be32bSraviteja-b             "/xyz/openbmc_project/network/config",
332501be32bSraviteja-b             "org.freedesktop.DBus.Properties", "Set",
333501be32bSraviteja-b             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
334501be32bSraviteja-b             std::variant<std::string>(hostName));
335501be32bSraviteja-b     }
336501be32bSraviteja-b 
337*20e6ea5dSraviteja-b     void handleNTPProtocolEnabled(const bool& ntpEnabled,
338*20e6ea5dSraviteja-b                                   const std::shared_ptr<AsyncResp>& asyncResp)
339*20e6ea5dSraviteja-b     {
340*20e6ea5dSraviteja-b         std::string timeSyncMethod;
341*20e6ea5dSraviteja-b         if (ntpEnabled)
342*20e6ea5dSraviteja-b         {
343*20e6ea5dSraviteja-b             timeSyncMethod =
344*20e6ea5dSraviteja-b                 "xyz.openbmc_project.Time.Synchronization.Method.NTP";
345*20e6ea5dSraviteja-b         }
346*20e6ea5dSraviteja-b         else
347*20e6ea5dSraviteja-b         {
348*20e6ea5dSraviteja-b             timeSyncMethod =
349*20e6ea5dSraviteja-b                 "xyz.openbmc_project.Time.Synchronization.Method.Manual";
350*20e6ea5dSraviteja-b         }
351*20e6ea5dSraviteja-b 
352*20e6ea5dSraviteja-b         crow::connections::systemBus->async_method_call(
353*20e6ea5dSraviteja-b             [asyncResp,
354*20e6ea5dSraviteja-b              ntpEnabled](const boost::system::error_code error_code) {
355*20e6ea5dSraviteja-b                 asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = ntpEnabled;
356*20e6ea5dSraviteja-b             },
357*20e6ea5dSraviteja-b             "xyz.openbmc_project.Settings",
358*20e6ea5dSraviteja-b             "/xyz/openbmc_project/time/sync_method",
359*20e6ea5dSraviteja-b             "org.freedesktop.DBus.Properties", "Set",
360*20e6ea5dSraviteja-b             "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
361*20e6ea5dSraviteja-b             std::variant<std::string>{timeSyncMethod});
362*20e6ea5dSraviteja-b     }
363*20e6ea5dSraviteja-b 
364*20e6ea5dSraviteja-b     void handleNTPServersPatch(const std::vector<std::string>& ntpServers,
365*20e6ea5dSraviteja-b                                const std::shared_ptr<AsyncResp>& asyncResp)
366*20e6ea5dSraviteja-b     {
367*20e6ea5dSraviteja-b         crow::connections::systemBus->async_method_call(
368*20e6ea5dSraviteja-b             [asyncResp, ntpServers](const boost::system::error_code ec) {
369*20e6ea5dSraviteja-b                 if (ec)
370*20e6ea5dSraviteja-b                 {
371*20e6ea5dSraviteja-b                     messages::internalError(asyncResp->res);
372*20e6ea5dSraviteja-b                     return;
373*20e6ea5dSraviteja-b                 }
374*20e6ea5dSraviteja-b                 asyncResp->res.jsonValue["NTP"]["NTPServers"] =
375*20e6ea5dSraviteja-b                     std::move(ntpServers);
376*20e6ea5dSraviteja-b             },
377*20e6ea5dSraviteja-b             "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0",
378*20e6ea5dSraviteja-b             "org.freedesktop.DBus.Properties", "Set",
379*20e6ea5dSraviteja-b             "xyz.openbmc_project.Network.EthernetInterface", "NTPServers",
380*20e6ea5dSraviteja-b             std::variant<std::vector<std::string>>{ntpServers});
381*20e6ea5dSraviteja-b     }
382*20e6ea5dSraviteja-b 
383501be32bSraviteja-b     void doPatch(crow::Response& res, const crow::Request& req,
384501be32bSraviteja-b                  const std::vector<std::string>& params) override
385501be32bSraviteja-b     {
386501be32bSraviteja-b         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
387501be32bSraviteja-b         std::optional<std::string> newHostName;
388*20e6ea5dSraviteja-b         std::optional<std::vector<std::string>> ntpServers;
389*20e6ea5dSraviteja-b         std::optional<bool> ntpEnabled;
390501be32bSraviteja-b 
391*20e6ea5dSraviteja-b         if (!json_util::readJson(req, res, "HostName", newHostName,
392*20e6ea5dSraviteja-b                                  "NTPServers", ntpServers, "NTPEnabled",
393*20e6ea5dSraviteja-b                                  ntpEnabled))
394501be32bSraviteja-b         {
395501be32bSraviteja-b             return;
396501be32bSraviteja-b         }
397501be32bSraviteja-b         if (newHostName)
398501be32bSraviteja-b         {
399501be32bSraviteja-b             handleHostnamePatch(*newHostName, asyncResp);
400501be32bSraviteja-b             return;
401501be32bSraviteja-b         }
402*20e6ea5dSraviteja-b         if (ntpEnabled)
403*20e6ea5dSraviteja-b         {
404*20e6ea5dSraviteja-b             handleNTPProtocolEnabled(*ntpEnabled, asyncResp);
405*20e6ea5dSraviteja-b         }
406*20e6ea5dSraviteja-b         if (ntpServers)
407*20e6ea5dSraviteja-b         {
408*20e6ea5dSraviteja-b             handleNTPServersPatch(*ntpServers, asyncResp);
409*20e6ea5dSraviteja-b         }
410501be32bSraviteja-b     }
41170141561SBorawski.Lukasz };
41270141561SBorawski.Lukasz 
41370141561SBorawski.Lukasz } // namespace redfish
414