1 #include "listener.hpp"
2
3 #include "event_logger.hpp"
4 #include "utility/dbus_utility.hpp"
5
6 namespace vpd
7 {
Listener(const std::shared_ptr<Worker> & i_worker,const std::shared_ptr<sdbusplus::asio::connection> & i_asioConnection)8 Listener::Listener(
9 const std::shared_ptr<Worker>& i_worker,
10 const std::shared_ptr<sdbusplus::asio::connection>& i_asioConnection) :
11 m_worker(i_worker), m_asioConnection(i_asioConnection)
12 {}
13
registerHostStateChangeCallback() const14 void Listener::registerHostStateChangeCallback() const noexcept
15 {
16 try
17 {
18 static std::shared_ptr<sdbusplus::bus::match_t> l_hostState =
19 std::make_shared<sdbusplus::bus::match_t>(
20 *m_asioConnection,
21 sdbusplus::bus::match::rules::propertiesChanged(
22 constants::hostObjectPath, constants::hostInterface),
23 [this](sdbusplus::message_t& i_msg) {
24 hostStateChangeCallBack(i_msg);
25 });
26 }
27 catch (const std::exception& l_ex)
28 {
29 logging::logMessage(
30 "Register Host state change callback failed, reason: " +
31 std::string(l_ex.what()));
32 }
33 }
34
hostStateChangeCallBack(sdbusplus::message_t & i_msg) const35 void Listener::hostStateChangeCallBack(
36 sdbusplus::message_t& i_msg) const noexcept
37 {
38 try
39 {
40 if (i_msg.is_method_error())
41 {
42 throw std::runtime_error(
43 "Error reading callback message for host state");
44 }
45
46 std::string l_objectPath;
47 types::PropertyMap l_propMap;
48 i_msg.read(l_objectPath, l_propMap);
49
50 const auto l_itr = l_propMap.find("CurrentHostState");
51
52 if (l_itr == l_propMap.end())
53 {
54 // CurrentHostState is not found in the callback message
55 return;
56 }
57
58 if (auto l_hostState = std::get_if<std::string>(&(l_itr->second)))
59 {
60 // implies system is moving from standby to power on state
61 if (*l_hostState == "xyz.openbmc_project.State.Host.HostState."
62 "TransitioningToRunning")
63 {
64 // TODO: check for all the essential FRUs in the system.
65
66 if (m_worker.get() != nullptr)
67 {
68 // Perform recollection.
69 m_worker->performVpdRecollection();
70 }
71 else
72 {
73 logging::logMessage(
74 "Failed to get worker object, Abort re-collection");
75 }
76 }
77 }
78 else
79 {
80 throw std::runtime_error(
81 "Invalid type recieved in variant for host state.");
82 }
83 }
84 catch (const std::exception& l_ex)
85 {
86 EventLogger::createSyncPel(
87 EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
88 __FILE__, __FUNCTION__, 0,
89 "Host state change callback failed, reason: " +
90 std::string(l_ex.what()),
91 std::nullopt, std::nullopt, std::nullopt, std::nullopt);
92 }
93 }
94
registerAssetTagChangeCallback() const95 void Listener::registerAssetTagChangeCallback() const noexcept
96 {
97 try
98 {
99 static std::shared_ptr<sdbusplus::bus::match_t> l_assetMatch =
100 std::make_shared<sdbusplus::bus::match_t>(
101 *m_asioConnection,
102 sdbusplus::bus::match::rules::propertiesChanged(
103 constants::systemInvPath, constants::assetTagInf),
104 [this](sdbusplus::message_t& l_msg) {
105 assetTagChangeCallback(l_msg);
106 });
107 }
108 catch (const std::exception& l_ex)
109 {
110 logging::logMessage(
111 "Register AssetTag change callback failed, reason: " +
112 std::string(l_ex.what()));
113 }
114 }
115
assetTagChangeCallback(sdbusplus::message_t & i_msg) const116 void Listener::assetTagChangeCallback(
117 sdbusplus::message_t& i_msg) const noexcept
118 {
119 try
120 {
121 if (i_msg.is_method_error())
122 {
123 throw std::runtime_error(
124 "Error reading callback msg for asset tag.");
125 }
126
127 std::string l_objectPath;
128 types::PropertyMap l_propMap;
129 i_msg.read(l_objectPath, l_propMap);
130
131 const auto& l_itrToAssetTag = l_propMap.find("AssetTag");
132 if (l_itrToAssetTag != l_propMap.end())
133 {
134 if (auto l_assetTag =
135 std::get_if<std::string>(&(l_itrToAssetTag->second)))
136 {
137 // Call Notify to persist the AssetTag
138 types::ObjectMap l_objectMap = {
139 {sdbusplus::message::object_path(constants::systemInvPath),
140 {{constants::assetTagInf, {{"AssetTag", *l_assetTag}}}}}};
141
142 // Notify PIM
143 if (!dbusUtility::callPIM(move(l_objectMap)))
144 {
145 throw std::runtime_error(
146 "Call to PIM failed for asset tag update.");
147 }
148 }
149 }
150 else
151 {
152 throw std::runtime_error(
153 "Could not find asset tag in callback message.");
154 }
155 }
156 catch (const std::exception& l_ex)
157 {
158 EventLogger::createSyncPel(
159 EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
160 __FILE__, __FUNCTION__, 0,
161 "AssetTag update failed, reason: " + std::string(l_ex.what()),
162 std::nullopt, std::nullopt, std::nullopt, std::nullopt);
163 }
164 }
165
166 } // namespace vpd
167