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