xref: /openbmc/openpower-vpd-parser/vpd-manager/src/listener.cpp (revision 56e4537c80d009d1d072d141b2d96f4368203a95)
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