1 #include "system_configuration.hpp"
2 
3 #include <phosphor-logging/elog-errors.hpp>
4 #include <phosphor-logging/log.hpp>
5 #include <stdplus/pinned.hpp>
6 #include <xyz/openbmc_project/Common/error.hpp>
7 
8 namespace phosphor
9 {
10 namespace network
11 {
12 
13 static constexpr char HOSTNAMED_SVC[] = "org.freedesktop.hostname1";
14 static constexpr char HOSTNAMED_OBJ[] = "/org/freedesktop/hostname1";
15 static constexpr char HOSTNAMED_INTF[] = "org.freedesktop.hostname1";
16 
17 using namespace phosphor::logging;
18 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
19 
20 static constexpr char propMatch[] =
21     "type='signal',sender='org.freedesktop.hostname1',"
22     "path='/org/freedesktop/hostname1',"
23     "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',"
24     "arg0='org.freedesktop.hostname1'";
25 
26 SystemConfiguration::SystemConfiguration(
27     stdplus::PinnedRef<sdbusplus::bus_t> bus, stdplus::const_zstring objPath) :
28     Iface(bus, objPath.c_str(), Iface::action::defer_emit),
29     bus(bus),
30     hostnamePropMatch(
31         bus, propMatch,
32         [sc = stdplus::PinnedRef(*this)](sdbusplus::message_t& m) {
33             std::string intf;
34             std::unordered_map<std::string, std::variant<std::string>> values;
35             try
36             {
37                 m.read(intf, values);
38                 auto it = values.find("Hostname");
39                 if (it == values.end())
40                 {
41                     return;
42                 }
43                 sc.get().Iface::hostName(std::get<std::string>(it->second));
44             }
45             catch (const std::exception& e)
46             {
47                 log<level::ERR>(
48                     fmt::format("Hostname match parsing failed: {}", e.what())
49                         .c_str(),
50                     entry("ERROR=%s", e.what()));
51             }
52         })
53 {
54     try
55     {
56         std::variant<std::string> name;
57         auto req =
58             bus.get().new_method_call(HOSTNAMED_SVC, HOSTNAMED_OBJ,
59                                       "org.freedesktop.DBus.Properties", "Get");
60 
61         req.append(HOSTNAMED_INTF, "Hostname");
62         auto reply = req.call();
63         reply.read(name);
64         SystemConfigIntf::hostName(std::get<std::string>(name), true);
65     }
66     catch (const std::exception& e)
67     {
68         auto msg = fmt::format("Failed to get hostname: {}", e.what());
69         log<level::ERR>(msg.c_str(), entry("ERROR=%s", e.what()));
70     }
71 
72     emit_object_added();
73 }
74 
75 std::string SystemConfiguration::hostName(std::string name)
76 {
77     if (SystemConfigIntf::hostName() == name)
78     {
79         return name;
80     }
81     try
82     {
83         auto method = bus.get().new_method_call(
84             HOSTNAMED_SVC, HOSTNAMED_OBJ, HOSTNAMED_INTF, "SetStaticHostname");
85         method.append(name, /*interactive=*/false);
86         bus.get().call_noreply(method);
87         return SystemConfigIntf::hostName(std::move(name));
88     }
89     catch (const std::exception& e)
90     {
91         auto msg = fmt::format("Failed to set hostname: {}", e.what());
92         log<level::ERR>(msg.c_str(), entry("ERROR=%s", e.what()));
93     }
94     return SystemConfigIntf::hostName();
95 }
96 
97 } // namespace network
98 } // namespace phosphor
99