xref: /openbmc/bmcweb/features/redfish/lib/network_protocol.hpp (revision 432a890cfca335e565b770b1604ed4e547c5a732)
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"
1967a78d87STom Joseph #include "openbmc_dbus_rest.hpp"
2070141561SBorawski.Lukasz 
217e860f15SJohn Edward Broadbent #include <app.hpp>
2220e6ea5dSraviteja-b #include <utils/json_utils.hpp>
231214b7e7SGunnar Mills 
241214b7e7SGunnar Mills #include <optional>
25abf2add6SEd Tanous #include <variant>
261abe55efSEd Tanous namespace redfish
271abe55efSEd Tanous {
2870141561SBorawski.Lukasz 
297e860f15SJohn Edward Broadbent void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);
307e860f15SJohn Edward Broadbent std::string getHostName();
317e860f15SJohn Edward Broadbent 
321abe55efSEd Tanous enum NetworkProtocolUnitStructFields
331abe55efSEd Tanous {
343a8a0088SKowalski, Kamil     NET_PROTO_UNIT_NAME,
353a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DESC,
363a8a0088SKowalski, Kamil     NET_PROTO_UNIT_LOAD_STATE,
373a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ACTIVE_STATE,
383a8a0088SKowalski, Kamil     NET_PROTO_UNIT_SUB_STATE,
393a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DEVICE,
403a8a0088SKowalski, Kamil     NET_PROTO_UNIT_OBJ_PATH,
413a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_0,
423a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_EMPTY,
433a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_ROOT_PATH
443a8a0088SKowalski, Kamil };
453a8a0088SKowalski, Kamil 
461abe55efSEd Tanous enum NetworkProtocolListenResponseElements
471abe55efSEd Tanous {
483a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_TYPE,
493a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_STREAM
503a8a0088SKowalski, Kamil };
513a8a0088SKowalski, Kamil 
523a8a0088SKowalski, Kamil /**
533a8a0088SKowalski, Kamil  * @brief D-Bus Unit structure returned in array from ListUnits Method
543a8a0088SKowalski, Kamil  */
553a8a0088SKowalski, Kamil using UnitStruct =
563a8a0088SKowalski, Kamil     std::tuple<std::string, std::string, std::string, std::string, std::string,
573a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path, uint32_t,
583a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path>;
593a8a0088SKowalski, Kamil 
60b0972a63SEd Tanous const static std::array<std::pair<const char*, const char*>, 3> protocolToDBus{
61b0972a63SEd Tanous     {{"SSH", "dropbear"}, {"HTTPS", "bmcweb"}, {"IPMI", "phosphor-ipmi-net"}}};
623a8a0088SKowalski, Kamil 
63d24bfc7aSJennifer Lee inline void
6481ce609eSEd Tanous     extractNTPServersAndDomainNamesData(const GetManagedObjects& dbusData,
65d24bfc7aSJennifer Lee                                         std::vector<std::string>& ntpData,
66d24bfc7aSJennifer Lee                                         std::vector<std::string>& dnData)
6720e6ea5dSraviteja-b {
6881ce609eSEd Tanous     for (const auto& obj : dbusData)
6920e6ea5dSraviteja-b     {
7020e6ea5dSraviteja-b         for (const auto& ifacePair : obj.second)
7120e6ea5dSraviteja-b         {
7220e6ea5dSraviteja-b             if (obj.first == "/xyz/openbmc_project/network/eth0")
7320e6ea5dSraviteja-b             {
7420e6ea5dSraviteja-b                 if (ifacePair.first ==
7520e6ea5dSraviteja-b                     "xyz.openbmc_project.Network.EthernetInterface")
7620e6ea5dSraviteja-b                 {
7720e6ea5dSraviteja-b                     for (const auto& propertyPair : ifacePair.second)
7820e6ea5dSraviteja-b                     {
7920e6ea5dSraviteja-b                         if (propertyPair.first == "NTPServers")
8020e6ea5dSraviteja-b                         {
8120e6ea5dSraviteja-b                             const std::vector<std::string>* ntpServers =
828d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
8320e6ea5dSraviteja-b                                     &propertyPair.second);
8420e6ea5dSraviteja-b                             if (ntpServers != nullptr)
8520e6ea5dSraviteja-b                             {
86f23b7296SEd Tanous                                 ntpData = *ntpServers;
8720e6ea5dSraviteja-b                             }
8820e6ea5dSraviteja-b                         }
89d24bfc7aSJennifer Lee                         else if (propertyPair.first == "DomainName")
90d24bfc7aSJennifer Lee                         {
91d24bfc7aSJennifer Lee                             const std::vector<std::string>* domainNames =
928d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
93d24bfc7aSJennifer Lee                                     &propertyPair.second);
94d24bfc7aSJennifer Lee                             if (domainNames != nullptr)
95d24bfc7aSJennifer Lee                             {
96f23b7296SEd Tanous                                 dnData = *domainNames;
97d24bfc7aSJennifer Lee                             }
98d24bfc7aSJennifer Lee                         }
9920e6ea5dSraviteja-b                     }
10020e6ea5dSraviteja-b                 }
10120e6ea5dSraviteja-b             }
10220e6ea5dSraviteja-b         }
10320e6ea5dSraviteja-b     }
10420e6ea5dSraviteja-b }
10520e6ea5dSraviteja-b 
10620e6ea5dSraviteja-b template <typename CallbackFunc>
10720e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback)
10820e6ea5dSraviteja-b {
10920e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
11020e6ea5dSraviteja-b         [callback{std::move(callback)}](
11181ce609eSEd Tanous             const boost::system::error_code errorCode,
11281ce609eSEd Tanous             const GetManagedObjects& dbusData) {
11320e6ea5dSraviteja-b             std::vector<std::string> ntpServers;
114d24bfc7aSJennifer Lee             std::vector<std::string> domainNames;
11520e6ea5dSraviteja-b 
11681ce609eSEd Tanous             if (errorCode)
11720e6ea5dSraviteja-b             {
118d24bfc7aSJennifer Lee                 callback(false, ntpServers, domainNames);
11920e6ea5dSraviteja-b                 return;
12020e6ea5dSraviteja-b             }
12120e6ea5dSraviteja-b 
12281ce609eSEd Tanous             extractNTPServersAndDomainNamesData(dbusData, ntpServers,
123d24bfc7aSJennifer Lee                                                 domainNames);
12420e6ea5dSraviteja-b 
125d24bfc7aSJennifer Lee             callback(true, ntpServers, domainNames);
12620e6ea5dSraviteja-b         },
12720e6ea5dSraviteja-b         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
12820e6ea5dSraviteja-b         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
129271584abSEd Tanous }
13020e6ea5dSraviteja-b 
1317e860f15SJohn Edward Broadbent void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1321abe55efSEd Tanous {
1330f74e643SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
13461932318SXiaochao Ma         "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol";
1350f74e643SEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
1360f74e643SEd Tanous         "/redfish/v1/Managers/bmc/NetworkProtocol";
1370f74e643SEd Tanous     asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
1380f74e643SEd Tanous     asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
1390f74e643SEd Tanous     asyncResp->res.jsonValue["Description"] = "Manager Network Service";
1400f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
1410f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
1420f74e643SEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
1430f74e643SEd Tanous 
14461932318SXiaochao Ma     // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0,
145818ea7b8SJoshi-Mansi     // but from security perspective it is not recommended to use.
146818ea7b8SJoshi-Mansi     // Hence using protocolEnabled as false to make it OCP and security-wise
147818ea7b8SJoshi-Mansi     // compliant
148818ea7b8SJoshi-Mansi     asyncResp->res.jsonValue["HTTP"]["Port"] = 0;
149818ea7b8SJoshi-Mansi     asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false;
150818ea7b8SJoshi-Mansi 
1510f74e643SEd Tanous     for (auto& protocol : protocolToDBus)
1520f74e643SEd Tanous     {
1530870f8c7SJayaprakash Mutyala         asyncResp->res.jsonValue[protocol.first]["Port"] =
1540870f8c7SJayaprakash Mutyala             nlohmann::detail::value_t::null;
1550f74e643SEd Tanous         asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false;
1560f74e643SEd Tanous     }
1570f74e643SEd Tanous 
158d24bfc7aSJennifer Lee     std::string hostName = getHostName();
159d24bfc7aSJennifer Lee 
160d24bfc7aSJennifer Lee     asyncResp->res.jsonValue["HostName"] = hostName;
1613a8a0088SKowalski, Kamil 
16220e6ea5dSraviteja-b     getNTPProtocolEnabled(asyncResp);
16320e6ea5dSraviteja-b 
16420e6ea5dSraviteja-b     // TODO Get eth0 interface data, and call the below callback for JSON
16520e6ea5dSraviteja-b     // preparation
166271584abSEd Tanous     getEthernetIfaceData(
167271584abSEd Tanous         [hostName, asyncResp](const bool& success,
168d24bfc7aSJennifer Lee                               const std::vector<std::string>& ntpServers,
169d24bfc7aSJennifer Lee                               const std::vector<std::string>& domainNames) {
17020e6ea5dSraviteja-b             if (!success)
17120e6ea5dSraviteja-b             {
1727e860f15SJohn Edward Broadbent                 messages::resourceNotFound(asyncResp->res, "EthernetInterface",
1737e860f15SJohn Edward Broadbent                                            "eth0");
17420e6ea5dSraviteja-b                 return;
17520e6ea5dSraviteja-b             }
17620e6ea5dSraviteja-b             asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
177d24bfc7aSJennifer Lee             if (hostName.empty() == false)
178d24bfc7aSJennifer Lee             {
179f23b7296SEd Tanous                 std::string fqdn = hostName;
180d24bfc7aSJennifer Lee                 if (domainNames.empty() == false)
181d24bfc7aSJennifer Lee                 {
182f23b7296SEd Tanous                     fqdn += ".";
183f23b7296SEd Tanous                     fqdn += domainNames[0];
184d24bfc7aSJennifer Lee                 }
1852c70f800SEd Tanous                 asyncResp->res.jsonValue["FQDN"] = std::move(fqdn);
186d24bfc7aSJennifer Lee             }
18720e6ea5dSraviteja-b         });
18820e6ea5dSraviteja-b 
189865fbb75SEd Tanous     crow::connections::systemBus->async_method_call(
190271584abSEd Tanous         [asyncResp](const boost::system::error_code e,
191271584abSEd Tanous                     const std::vector<UnitStruct>& r) {
192271584abSEd Tanous             if (e)
1931abe55efSEd Tanous             {
1943a8a0088SKowalski, Kamil                 asyncResp->res.jsonValue = nlohmann::json::object();
195f12894f8SJason M. Bills                 messages::internalError(asyncResp->res);
196865fbb75SEd Tanous                 return;
1973a8a0088SKowalski, Kamil             }
1985968caeeSMarri Devender Rao             asyncResp->res.jsonValue["HTTPS"]["Certificates"] = {
1995968caeeSMarri Devender Rao                 {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/"
200659dd62eSJason M. Bills                               "HTTPS/Certificates"}};
2013a8a0088SKowalski, Kamil 
202271584abSEd Tanous             for (auto& unit : r)
2031abe55efSEd Tanous             {
204ec4974ddSAppaRao Puli                 /* Only traverse through <xyz>.socket units */
2053174e4dfSEd Tanous                 const std::string& unitName =
2063174e4dfSEd Tanous                     std::get<NET_PROTO_UNIT_NAME>(unit);
207ec4974ddSAppaRao Puli                 if (!boost::ends_with(unitName, ".socket"))
2081abe55efSEd Tanous                 {
209865fbb75SEd Tanous                     continue;
21070141561SBorawski.Lukasz                 }
21170141561SBorawski.Lukasz 
212ec4974ddSAppaRao Puli                 for (auto& kv : protocolToDBus)
213ec4974ddSAppaRao Puli                 {
214ec4974ddSAppaRao Puli                     // We are interested in services, which starts with
215ec4974ddSAppaRao Puli                     // mapped service name
216ec4974ddSAppaRao Puli                     if (!boost::starts_with(unitName, kv.second))
217ec4974ddSAppaRao Puli                     {
218ec4974ddSAppaRao Puli                         continue;
219ec4974ddSAppaRao Puli                     }
220ec4974ddSAppaRao Puli                     const char* rfServiceKey = kv.first;
2213174e4dfSEd Tanous                     const std::string& socketPath =
222ec4974ddSAppaRao Puli                         std::get<NET_PROTO_UNIT_OBJ_PATH>(unit);
2233174e4dfSEd Tanous                     const std::string& unitState =
224ec4974ddSAppaRao Puli                         std::get<NET_PROTO_UNIT_SUB_STATE>(unit);
225ec4974ddSAppaRao Puli 
2267e860f15SJohn Edward Broadbent                     asyncResp->res.jsonValue[rfServiceKey]["ProtocolEnabled"] =
2277e860f15SJohn Edward Broadbent                         (unitState == "running") || (unitState == "listening");
228ec4974ddSAppaRao Puli 
229865fbb75SEd Tanous                     crow::connections::systemBus->async_method_call(
2307e860f15SJohn Edward Broadbent                         [asyncResp, rfServiceKey{std::string(rfServiceKey)}](
231865fbb75SEd Tanous                             const boost::system::error_code ec,
2327e860f15SJohn Edward Broadbent                             const std::variant<std::vector<
2337e860f15SJohn Edward Broadbent                                 std::tuple<std::string, std::string>>>& resp) {
2341abe55efSEd Tanous                             if (ec)
2351abe55efSEd Tanous                             {
236a08b46ccSJason M. Bills                                 messages::internalError(asyncResp->res);
237865fbb75SEd Tanous                                 return;
2383a8a0088SKowalski, Kamil                             }
239abf2add6SEd Tanous                             const std::vector<
240abf2add6SEd Tanous                                 std::tuple<std::string, std::string>>*
241abf2add6SEd Tanous                                 responsePtr = std::get_if<std::vector<
242abf2add6SEd Tanous                                     std::tuple<std::string, std::string>>>(
2431b6b96c5SEd Tanous                                     &resp);
2441abe55efSEd Tanous                             if (responsePtr == nullptr ||
2451abe55efSEd Tanous                                 responsePtr->size() < 1)
2461abe55efSEd Tanous                             {
247865fbb75SEd Tanous                                 return;
24870141561SBorawski.Lukasz                             }
24970141561SBorawski.Lukasz 
250865fbb75SEd Tanous                             const std::string& listenStream =
2511abe55efSEd Tanous                                 std::get<NET_PROTO_LISTEN_STREAM>(
2521abe55efSEd Tanous                                     (*responsePtr)[0]);
2537e860f15SJohn Edward Broadbent                             std::size_t lastColonPos = listenStream.rfind(':');
2541abe55efSEd Tanous                             if (lastColonPos == std::string::npos)
2551abe55efSEd Tanous                             {
256865fbb75SEd Tanous                                 // Not a port
257865fbb75SEd Tanous                                 return;
258865fbb75SEd Tanous                             }
2591abe55efSEd Tanous                             std::string portStr =
2601abe55efSEd Tanous                                 listenStream.substr(lastColonPos + 1);
261ec4974ddSAppaRao Puli                             if (portStr.empty())
262ec4974ddSAppaRao Puli                             {
263ec4974ddSAppaRao Puli                                 return;
264ec4974ddSAppaRao Puli                             }
265865fbb75SEd Tanous                             char* endPtr = nullptr;
266ec4974ddSAppaRao Puli                             errno = 0;
2671abe55efSEd Tanous                             // Use strtol instead of stroi to avoid
2681abe55efSEd Tanous                             // exceptions
2691abe55efSEd Tanous                             long port =
2701abe55efSEd Tanous                                 std::strtol(portStr.c_str(), &endPtr, 10);
271ec4974ddSAppaRao Puli                             if ((errno == 0) && (*endPtr == '\0'))
2721abe55efSEd Tanous                             {
2737e860f15SJohn Edward Broadbent                                 asyncResp->res.jsonValue[rfServiceKey]["Port"] =
2747e860f15SJohn Edward Broadbent                                     port;
2751abe55efSEd Tanous                             }
276ec4974ddSAppaRao Puli                             return;
277865fbb75SEd Tanous                         },
278865fbb75SEd Tanous                         "org.freedesktop.systemd1", socketPath,
279865fbb75SEd Tanous                         "org.freedesktop.DBus.Properties", "Get",
280865fbb75SEd Tanous                         "org.freedesktop.systemd1.Socket", "Listen");
281ec4974ddSAppaRao Puli 
282ec4974ddSAppaRao Puli                     // We found service, break the inner loop.
283ec4974ddSAppaRao Puli                     break;
284865fbb75SEd Tanous                 }
285865fbb75SEd Tanous             }
286865fbb75SEd Tanous         },
287865fbb75SEd Tanous         "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
288865fbb75SEd Tanous         "org.freedesktop.systemd1.Manager", "ListUnits");
289865fbb75SEd Tanous }
290501be32bSraviteja-b 
2912db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
2927e860f15SJohn Edward Broadbent void handleHostnamePatch(const std::string& hostName,
2938d1b46d7Szhanghch05                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
294501be32bSraviteja-b {
295501be32bSraviteja-b     crow::connections::systemBus->async_method_call(
296501be32bSraviteja-b         [asyncResp](const boost::system::error_code ec) {
297501be32bSraviteja-b             if (ec)
298501be32bSraviteja-b             {
299501be32bSraviteja-b                 messages::internalError(asyncResp->res);
300501be32bSraviteja-b                 return;
301501be32bSraviteja-b             }
302501be32bSraviteja-b         },
3037e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/config",
304501be32bSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
305501be32bSraviteja-b         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
306501be32bSraviteja-b         std::variant<std::string>(hostName));
307501be32bSraviteja-b }
3082db77d34SJohnathan Mantey #endif
309501be32bSraviteja-b 
3108d1b46d7Szhanghch05 void handleNTPProtocolEnabled(
3117e860f15SJohn Edward Broadbent     const bool& ntpEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
31220e6ea5dSraviteja-b {
31320e6ea5dSraviteja-b     std::string timeSyncMethod;
31420e6ea5dSraviteja-b     if (ntpEnabled)
31520e6ea5dSraviteja-b     {
3167e860f15SJohn Edward Broadbent         timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP";
31720e6ea5dSraviteja-b     }
31820e6ea5dSraviteja-b     else
31920e6ea5dSraviteja-b     {
32020e6ea5dSraviteja-b         timeSyncMethod =
32120e6ea5dSraviteja-b             "xyz.openbmc_project.Time.Synchronization.Method.Manual";
32220e6ea5dSraviteja-b     }
32320e6ea5dSraviteja-b 
32420e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
32581ce609eSEd Tanous         [asyncResp](const boost::system::error_code errorCode) {
32681ce609eSEd Tanous             if (errorCode)
327cb13a392SEd Tanous             {
328cb13a392SEd Tanous                 messages::internalError(asyncResp->res);
329cb13a392SEd Tanous             }
330cb13a392SEd Tanous         },
3317e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
33220e6ea5dSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
33320e6ea5dSraviteja-b         "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
33420e6ea5dSraviteja-b         std::variant<std::string>{timeSyncMethod});
33520e6ea5dSraviteja-b }
33620e6ea5dSraviteja-b 
3377e860f15SJohn Edward Broadbent void handleNTPServersPatch(const std::vector<std::string>& ntpServers,
3388d1b46d7Szhanghch05                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
33920e6ea5dSraviteja-b {
34020e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
341cf05f9dcSJohnathan Mantey         [asyncResp](const boost::system::error_code ec) {
34220e6ea5dSraviteja-b             if (ec)
34320e6ea5dSraviteja-b             {
34420e6ea5dSraviteja-b                 messages::internalError(asyncResp->res);
34520e6ea5dSraviteja-b                 return;
34620e6ea5dSraviteja-b             }
34720e6ea5dSraviteja-b         },
34820e6ea5dSraviteja-b         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0",
34920e6ea5dSraviteja-b         "org.freedesktop.DBus.Properties", "Set",
35020e6ea5dSraviteja-b         "xyz.openbmc_project.Network.EthernetInterface", "NTPServers",
35120e6ea5dSraviteja-b         std::variant<std::vector<std::string>>{ntpServers});
35220e6ea5dSraviteja-b }
35320e6ea5dSraviteja-b 
3548d1b46d7Szhanghch05 void handleIpmiProtocolEnabled(
3558d1b46d7Szhanghch05     const bool ipmiProtocolEnabled,
3568d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
35767a78d87STom Joseph {
35867a78d87STom Joseph     crow::connections::systemBus->async_method_call(
35967a78d87STom Joseph         [ipmiProtocolEnabled,
36067a78d87STom Joseph          asyncResp](const boost::system::error_code ec,
36167a78d87STom Joseph                     const crow::openbmc_mapper::GetSubTreeType& subtree) {
36267a78d87STom Joseph             if (ec)
36367a78d87STom Joseph             {
36467a78d87STom Joseph                 messages::internalError(asyncResp->res);
36567a78d87STom Joseph                 return;
36667a78d87STom Joseph             }
36767a78d87STom Joseph 
36867a78d87STom Joseph             constexpr char const* netipmidBasePath =
36967a78d87STom Joseph                 "/xyz/openbmc_project/control/service/"
37067a78d87STom Joseph                 "phosphor_2dipmi_2dnet_40";
37167a78d87STom Joseph 
37267a78d87STom Joseph             for (const auto& entry : subtree)
37367a78d87STom Joseph             {
37467a78d87STom Joseph                 if (boost::algorithm::starts_with(entry.first,
37567a78d87STom Joseph                                                   netipmidBasePath))
37667a78d87STom Joseph                 {
37767a78d87STom Joseph                     crow::connections::systemBus->async_method_call(
37823a21a1cSEd Tanous                         [asyncResp](const boost::system::error_code ec2) {
37923a21a1cSEd Tanous                             if (ec2)
38067a78d87STom Joseph                             {
38167a78d87STom Joseph                                 messages::internalError(asyncResp->res);
38267a78d87STom Joseph                                 return;
38367a78d87STom Joseph                             }
38467a78d87STom Joseph                         },
38567a78d87STom Joseph                         entry.second.begin()->first, entry.first,
38667a78d87STom Joseph                         "org.freedesktop.DBus.Properties", "Set",
38767a78d87STom Joseph                         "xyz.openbmc_project.Control.Service.Attributes",
38867a78d87STom Joseph                         "Running", std::variant<bool>{ipmiProtocolEnabled});
38967a78d87STom Joseph 
39067a78d87STom Joseph                     crow::connections::systemBus->async_method_call(
39123a21a1cSEd Tanous                         [asyncResp](const boost::system::error_code ec2) {
39223a21a1cSEd Tanous                             if (ec2)
39367a78d87STom Joseph                             {
39467a78d87STom Joseph                                 messages::internalError(asyncResp->res);
39567a78d87STom Joseph                                 return;
39667a78d87STom Joseph                             }
39767a78d87STom Joseph                         },
39867a78d87STom Joseph                         entry.second.begin()->first, entry.first,
39967a78d87STom Joseph                         "org.freedesktop.DBus.Properties", "Set",
40067a78d87STom Joseph                         "xyz.openbmc_project.Control.Service.Attributes",
40167a78d87STom Joseph                         "Enabled", std::variant<bool>{ipmiProtocolEnabled});
40267a78d87STom Joseph                 }
40367a78d87STom Joseph             }
40467a78d87STom Joseph         },
40567a78d87STom Joseph         "xyz.openbmc_project.ObjectMapper",
40667a78d87STom Joseph         "/xyz/openbmc_project/object_mapper",
40767a78d87STom Joseph         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
40867a78d87STom Joseph         "/xyz/openbmc_project/control/service", 0,
40967a78d87STom Joseph         std::array<const char*, 1>{
41067a78d87STom Joseph             "xyz.openbmc_project.Control.Service.Attributes"});
41167a78d87STom Joseph }
41267a78d87STom Joseph 
4137e860f15SJohn Edward Broadbent std::string getHostName()
414501be32bSraviteja-b {
4157e860f15SJohn Edward Broadbent     std::string hostName;
4168d1b46d7Szhanghch05 
4177e860f15SJohn Edward Broadbent     std::array<char, HOST_NAME_MAX> hostNameCStr;
4187e860f15SJohn Edward Broadbent     if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
4197e860f15SJohn Edward Broadbent     {
4207e860f15SJohn Edward Broadbent         hostName = hostNameCStr.data();
4217e860f15SJohn Edward Broadbent     }
4227e860f15SJohn Edward Broadbent     return hostName;
4237e860f15SJohn Edward Broadbent }
4247e860f15SJohn Edward Broadbent 
4257e860f15SJohn Edward Broadbent void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
4267e860f15SJohn Edward Broadbent {
4277e860f15SJohn Edward Broadbent     crow::connections::systemBus->async_method_call(
4287e860f15SJohn Edward Broadbent         [asyncResp](const boost::system::error_code errorCode,
4297e860f15SJohn Edward Broadbent                     const std::variant<std::string>& timeSyncMethod) {
4307e860f15SJohn Edward Broadbent             if (errorCode)
4317e860f15SJohn Edward Broadbent             {
4327e860f15SJohn Edward Broadbent                 return;
4337e860f15SJohn Edward Broadbent             }
4347e860f15SJohn Edward Broadbent 
4357e860f15SJohn Edward Broadbent             const std::string* s = std::get_if<std::string>(&timeSyncMethod);
4367e860f15SJohn Edward Broadbent 
4377e860f15SJohn Edward Broadbent             if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP")
4387e860f15SJohn Edward Broadbent             {
4397e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true;
4407e860f15SJohn Edward Broadbent             }
4417e860f15SJohn Edward Broadbent             else if (*s == "xyz.openbmc_project.Time.Synchronization."
4427e860f15SJohn Edward Broadbent                            "Method.Manual")
4437e860f15SJohn Edward Broadbent             {
4447e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false;
4457e860f15SJohn Edward Broadbent             }
4467e860f15SJohn Edward Broadbent         },
4477e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
4487e860f15SJohn Edward Broadbent         "org.freedesktop.DBus.Properties", "Get",
4497e860f15SJohn Edward Broadbent         "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod");
4507e860f15SJohn Edward Broadbent }
4517e860f15SJohn Edward Broadbent 
4527e860f15SJohn Edward Broadbent inline void requestRoutesNetworkProtocol(App& app)
4537e860f15SJohn Edward Broadbent {
4547e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
455*432a890cSEd Tanous         .privileges({{"ConfigureManager"}})
4567e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::patch)(
4577e860f15SJohn Edward Broadbent             [](const crow::Request& req,
4587e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
459501be32bSraviteja-b                 std::optional<std::string> newHostName;
460cf05f9dcSJohnathan Mantey                 std::optional<nlohmann::json> ntp;
46167a78d87STom Joseph                 std::optional<nlohmann::json> ipmi;
462501be32bSraviteja-b 
4637e860f15SJohn Edward Broadbent                 if (!json_util::readJson(req, asyncResp->res, "NTP", ntp,
4647e860f15SJohn Edward Broadbent                                          "HostName", newHostName, "IPMI", ipmi))
465501be32bSraviteja-b                 {
466501be32bSraviteja-b                     return;
467501be32bSraviteja-b                 }
468cf05f9dcSJohnathan Mantey 
4698d1b46d7Szhanghch05                 asyncResp->res.result(boost::beast::http::status::no_content);
470501be32bSraviteja-b                 if (newHostName)
471501be32bSraviteja-b                 {
4722db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
473501be32bSraviteja-b                     handleHostnamePatch(*newHostName, asyncResp);
4742db77d34SJohnathan Mantey #else
4752db77d34SJohnathan Mantey                     messages::propertyNotWritable(asyncResp->res, "HostName");
4762db77d34SJohnathan Mantey #endif
477cf05f9dcSJohnathan Mantey                 }
478cf05f9dcSJohnathan Mantey 
479cf05f9dcSJohnathan Mantey                 if (ntp)
480cf05f9dcSJohnathan Mantey                 {
481cf05f9dcSJohnathan Mantey                     std::optional<std::vector<std::string>> ntpServers;
482cf05f9dcSJohnathan Mantey                     std::optional<bool> ntpEnabled;
4838d1b46d7Szhanghch05                     if (!json_util::readJson(*ntp, asyncResp->res, "NTPServers",
4847e860f15SJohn Edward Broadbent                                              ntpServers, "ProtocolEnabled",
4857e860f15SJohn Edward Broadbent                                              ntpEnabled))
486cf05f9dcSJohnathan Mantey                     {
487501be32bSraviteja-b                         return;
488501be32bSraviteja-b                     }
489cf05f9dcSJohnathan Mantey 
49020e6ea5dSraviteja-b                     if (ntpEnabled)
49120e6ea5dSraviteja-b                     {
49220e6ea5dSraviteja-b                         handleNTPProtocolEnabled(*ntpEnabled, asyncResp);
49320e6ea5dSraviteja-b                     }
494cf05f9dcSJohnathan Mantey 
49520e6ea5dSraviteja-b                     if (ntpServers)
49620e6ea5dSraviteja-b                     {
497dc3fbbd0STony Lee                         std::sort((*ntpServers).begin(), (*ntpServers).end());
498dc3fbbd0STony Lee                         (*ntpServers)
4997e860f15SJohn Edward Broadbent                             .erase(std::unique((*ntpServers).begin(),
5007e860f15SJohn Edward Broadbent                                                (*ntpServers).end()),
501dc3fbbd0STony Lee                                    (*ntpServers).end());
50220e6ea5dSraviteja-b                         handleNTPServersPatch(*ntpServers, asyncResp);
50320e6ea5dSraviteja-b                     }
504501be32bSraviteja-b                 }
50567a78d87STom Joseph 
50667a78d87STom Joseph                 if (ipmi)
50767a78d87STom Joseph                 {
50867a78d87STom Joseph                     std::optional<bool> ipmiProtocolEnabled;
5097e860f15SJohn Edward Broadbent                     if (!json_util::readJson(*ipmi, asyncResp->res,
5107e860f15SJohn Edward Broadbent                                              "ProtocolEnabled",
51167a78d87STom Joseph                                              ipmiProtocolEnabled))
51267a78d87STom Joseph                     {
51367a78d87STom Joseph                         return;
51467a78d87STom Joseph                     }
51567a78d87STom Joseph 
51667a78d87STom Joseph                     if (ipmiProtocolEnabled)
51767a78d87STom Joseph                     {
5187e860f15SJohn Edward Broadbent                         handleIpmiProtocolEnabled(*ipmiProtocolEnabled,
5197e860f15SJohn Edward Broadbent                                                   asyncResp);
52067a78d87STom Joseph                     }
52167a78d87STom Joseph                 }
5227e860f15SJohn Edward Broadbent             });
5237e860f15SJohn Edward Broadbent 
5247e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
525*432a890cSEd Tanous         .privileges({{"Login"}})
5267e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
5277e860f15SJohn Edward Broadbent             [](const crow::Request&,
5287e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
5297e860f15SJohn Edward Broadbent                 getNetworkData(asyncResp);
5307e860f15SJohn Edward Broadbent             });
531cf05f9dcSJohnathan Mantey }
53270141561SBorawski.Lukasz 
53370141561SBorawski.Lukasz } // namespace redfish
534