1 #include "listener.hpp" 2 3 #include "event_logger.hpp" 4 #include "utility/dbus_utility.hpp" 5 6 namespace vpd 7 { 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 14 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 35 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 95 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 116 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