114fe6698SNan Zhou // Copyright 2021 Google LLC 214fe6698SNan Zhou // 314fe6698SNan Zhou // Licensed under the Apache License, Version 2.0 (the "License"); 414fe6698SNan Zhou // you may not use this file except in compliance with the License. 514fe6698SNan Zhou // You may obtain a copy of the License at 614fe6698SNan Zhou // 714fe6698SNan Zhou // http://www.apache.org/licenses/LICENSE-2.0 814fe6698SNan Zhou // 914fe6698SNan Zhou // Unless required by applicable law or agreed to in writing, software 1014fe6698SNan Zhou // distributed under the License is distributed on an "AS IS" BASIS, 1114fe6698SNan Zhou // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1214fe6698SNan Zhou // See the License for the specific language governing permissions and 1314fe6698SNan Zhou // limitations under the License. 1414fe6698SNan Zhou 1514fe6698SNan Zhou #include "host_manager.hpp" 1614fe6698SNan Zhou 1714fe6698SNan Zhou #include <phosphor-logging/log.hpp> 1814fe6698SNan Zhou #include <sdbusplus/bus.hpp> 1914fe6698SNan Zhou #include <sdbusplus/message.hpp> 2014fe6698SNan Zhou 21*bb53161dSWilly Tu #include <format> 2214fe6698SNan Zhou #include <variant> 2314fe6698SNan Zhou 2414fe6698SNan Zhou using phosphor::logging::level; 2514fe6698SNan Zhou using phosphor::logging::log; 2614fe6698SNan Zhou 2714fe6698SNan Zhou HostManager::HostManager() : 2814fe6698SNan Zhou postcodes_(), bus_(sdbusplus::bus::new_default()), 2914fe6698SNan Zhou signal_(bus_, HostManager::GetMatch().c_str(), 3014fe6698SNan Zhou [this](auto& m) -> void { this->DbusHandleSignal(m); }), 3114fe6698SNan Zhou post_poller_enabled_(true) 3214fe6698SNan Zhou { 3314fe6698SNan Zhou // Spin off thread to listen on bus_ 3414fe6698SNan Zhou auto post_poller_thread = std::mem_fn(&HostManager::PostPollerThread); 3514fe6698SNan Zhou post_poller_ = std::make_unique<std::thread>(post_poller_thread, this); 3614fe6698SNan Zhou } 3714fe6698SNan Zhou 3859ac2c2dSPatrick Williams int HostManager::DbusHandleSignal(sdbusplus::message_t& msg) 3914fe6698SNan Zhou { 4014fe6698SNan Zhou log<level::INFO>("Property Changed!"); 4114fe6698SNan Zhou std::string msgSensor, busName{POSTCODE_BUSNAME}; 4214fe6698SNan Zhou std::map<std::string, 4314fe6698SNan Zhou std::variant<std::tuple<uint64_t, std::vector<uint8_t>>>> 4414fe6698SNan Zhou msgData; 4514fe6698SNan Zhou msg.read(msgSensor, msgData); 4614fe6698SNan Zhou 4714fe6698SNan Zhou if (msgSensor == busName) 4814fe6698SNan Zhou { 4914fe6698SNan Zhou auto valPropMap = msgData.find("Value"); 5014fe6698SNan Zhou if (valPropMap != msgData.end()) 5114fe6698SNan Zhou { 5214fe6698SNan Zhou uint64_t rawValue = 5314fe6698SNan Zhou std::get<uint64_t>(std::get<0>(valPropMap->second)); 5414fe6698SNan Zhou 5514fe6698SNan Zhou PushPostcode(rawValue); 5614fe6698SNan Zhou } 5714fe6698SNan Zhou } 5814fe6698SNan Zhou 5914fe6698SNan Zhou return 0; 6014fe6698SNan Zhou } 6114fe6698SNan Zhou 6214fe6698SNan Zhou void HostManager::PushPostcode(uint64_t postcode) 6314fe6698SNan Zhou { 6414fe6698SNan Zhou // Get lock 6514fe6698SNan Zhou std::lock_guard<std::mutex> lock(postcodes_lock_); 6614fe6698SNan Zhou // Add postcode to queue 6714fe6698SNan Zhou postcodes_.push_back(postcode); 6814fe6698SNan Zhou } 6914fe6698SNan Zhou 7014fe6698SNan Zhou std::vector<uint64_t> HostManager::DrainPostcodes() 7114fe6698SNan Zhou { 7214fe6698SNan Zhou // Get lock 7314fe6698SNan Zhou std::lock_guard<std::mutex> lock(postcodes_lock_); 7414fe6698SNan Zhou 7514fe6698SNan Zhou auto count = postcodes_.size(); 7614fe6698SNan Zhou if (count > 0) 7714fe6698SNan Zhou { 78*bb53161dSWilly Tu std::string msg = std::format("Draining Postcodes. Count: {}.", count); 7914fe6698SNan Zhou log<level::ERR>(msg.c_str()); 8014fe6698SNan Zhou } 8114fe6698SNan Zhou 8214fe6698SNan Zhou // Drain the queue into a list 8314fe6698SNan Zhou // TODO: maximum # postcodes? 8414fe6698SNan Zhou std::vector<uint64_t> result(postcodes_); 8514fe6698SNan Zhou postcodes_.clear(); 8614fe6698SNan Zhou 8714fe6698SNan Zhou return result; 8814fe6698SNan Zhou } 8914fe6698SNan Zhou 9014fe6698SNan Zhou std::string HostManager::GetMatch() 9114fe6698SNan Zhou { 9214fe6698SNan Zhou std::string obj{POSTCODE_OBJECTPATH}; 9314fe6698SNan Zhou return std::string("type='signal'," 9414fe6698SNan Zhou "interface='org.freedesktop.DBus.Properties'," 9514fe6698SNan Zhou "member='PropertiesChanged'," 9614fe6698SNan Zhou "path='" + 9714fe6698SNan Zhou obj + "'"); 9814fe6698SNan Zhou } 9914fe6698SNan Zhou 10014fe6698SNan Zhou void HostManager::PostPollerThread() 10114fe6698SNan Zhou { 10214fe6698SNan Zhou while (post_poller_enabled_) 10314fe6698SNan Zhou { 10414fe6698SNan Zhou bus_.process_discard(); 10514fe6698SNan Zhou bus_.wait(); 10614fe6698SNan Zhou } 10714fe6698SNan Zhou } 108