1 #include "system_configuration.hpp"
2 
3 #include <phosphor-logging/elog-errors.hpp>
4 #include <phosphor-logging/lg2.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 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(
26     stdplus::PinnedRef<sdbusplus::bus_t> bus, stdplus::const_zstring objPath) :
27     Iface(bus, objPath.c_str(), Iface::action::defer_emit),
28     bus(bus), hostnamePropMatch(
29                   bus, propMatch,
30                   [sc = stdplus::PinnedRef(*this)](sdbusplus::message_t& m) {
31     std::string intf;
32     std::unordered_map<std::string, std::variant<std::string>> values;
33     try
34     {
35         m.read(intf, values);
36         auto it = values.find("Hostname");
37         if (it == values.end())
38         {
39             return;
40         }
41         sc.get().Iface::hostName(std::get<std::string>(it->second));
42     }
43     catch (const std::exception& e)
44     {
45         lg2::error("Hostname match parsing failed: {ERROR}", "ERROR", e);
46     }
47                   })
48 {
49     try
50     {
51         std::variant<std::string> name;
52         auto req = bus.get().new_method_call(HOSTNAMED_SVC, HOSTNAMED_OBJ,
53                                              "org.freedesktop.DBus.Properties",
54                                              "Get");
55 
56         req.append(HOSTNAMED_INTF, "Hostname");
57         auto reply = req.call();
58         reply.read(name);
59         SystemConfigIntf::hostName(std::get<std::string>(name), true);
60     }
61     catch (const std::exception& e)
62     {
63         lg2::error("Failed to get hostname: {ERROR}", "ERROR", e);
64     }
65 
66     emit_object_added();
67 }
68 
69 std::string SystemConfiguration::hostName(std::string name)
70 {
71     if (SystemConfigIntf::hostName() == name)
72     {
73         return name;
74     }
75     try
76     {
77         auto method = bus.get().new_method_call(
78             HOSTNAMED_SVC, HOSTNAMED_OBJ, HOSTNAMED_INTF, "SetStaticHostname");
79         method.append(name, /*interactive=*/false);
80         bus.get().call_noreply(method);
81         return SystemConfigIntf::hostName(std::move(name));
82     }
83     catch (const std::exception& e)
84     {
85         lg2::error("Failed to set hostname: {ERROR}", "ERROR", e);
86     }
87     return SystemConfigIntf::hostName();
88 }
89 
90 } // namespace network
91 } // namespace phosphor
92