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 <fmt/format.h> 1814fe6698SNan Zhou 1914fe6698SNan Zhou #include <phosphor-logging/log.hpp> 2014fe6698SNan Zhou #include <sdbusplus/bus.hpp> 2114fe6698SNan Zhou #include <sdbusplus/message.hpp> 2214fe6698SNan Zhou 2314fe6698SNan Zhou #include <functional> 2414fe6698SNan Zhou #include <iostream> 2514fe6698SNan Zhou #include <variant> 2614fe6698SNan Zhou 2714fe6698SNan Zhou using fmt::format; 2814fe6698SNan Zhou using phosphor::logging::level; 2914fe6698SNan Zhou using phosphor::logging::log; 3014fe6698SNan Zhou 3114fe6698SNan Zhou HostManager::HostManager() : 3214fe6698SNan Zhou postcodes_(), bus_(sdbusplus::bus::new_default()), 3314fe6698SNan Zhou signal_(bus_, HostManager::GetMatch().c_str(), 3414fe6698SNan Zhou [this](auto& m) -> void { this->DbusHandleSignal(m); }), 3514fe6698SNan Zhou post_poller_enabled_(true) 3614fe6698SNan Zhou { 3714fe6698SNan Zhou // Spin off thread to listen on bus_ 3814fe6698SNan Zhou auto post_poller_thread = std::mem_fn(&HostManager::PostPollerThread); 3914fe6698SNan Zhou post_poller_ = std::make_unique<std::thread>(post_poller_thread, this); 4014fe6698SNan Zhou } 4114fe6698SNan Zhou 42*59ac2c2dSPatrick Williams int HostManager::DbusHandleSignal(sdbusplus::message_t& msg) 4314fe6698SNan Zhou { 4414fe6698SNan Zhou log<level::INFO>("Property Changed!"); 4514fe6698SNan Zhou std::string msgSensor, busName{POSTCODE_BUSNAME}; 4614fe6698SNan Zhou std::map<std::string, 4714fe6698SNan Zhou std::variant<std::tuple<uint64_t, std::vector<uint8_t>>>> 4814fe6698SNan Zhou msgData; 4914fe6698SNan Zhou msg.read(msgSensor, msgData); 5014fe6698SNan Zhou 5114fe6698SNan Zhou if (msgSensor == busName) 5214fe6698SNan Zhou { 5314fe6698SNan Zhou auto valPropMap = msgData.find("Value"); 5414fe6698SNan Zhou if (valPropMap != msgData.end()) 5514fe6698SNan Zhou { 5614fe6698SNan Zhou uint64_t rawValue = 5714fe6698SNan Zhou std::get<uint64_t>(std::get<0>(valPropMap->second)); 5814fe6698SNan Zhou 5914fe6698SNan Zhou PushPostcode(rawValue); 6014fe6698SNan Zhou } 6114fe6698SNan Zhou } 6214fe6698SNan Zhou 6314fe6698SNan Zhou return 0; 6414fe6698SNan Zhou } 6514fe6698SNan Zhou 6614fe6698SNan Zhou void HostManager::PushPostcode(uint64_t postcode) 6714fe6698SNan Zhou { 6814fe6698SNan Zhou // Get lock 6914fe6698SNan Zhou std::lock_guard<std::mutex> lock(postcodes_lock_); 7014fe6698SNan Zhou // Add postcode to queue 7114fe6698SNan Zhou postcodes_.push_back(postcode); 7214fe6698SNan Zhou } 7314fe6698SNan Zhou 7414fe6698SNan Zhou std::vector<uint64_t> HostManager::DrainPostcodes() 7514fe6698SNan Zhou { 7614fe6698SNan Zhou // Get lock 7714fe6698SNan Zhou std::lock_guard<std::mutex> lock(postcodes_lock_); 7814fe6698SNan Zhou 7914fe6698SNan Zhou auto count = postcodes_.size(); 8014fe6698SNan Zhou if (count > 0) 8114fe6698SNan Zhou { 8214fe6698SNan Zhou std::string msg = format("Draining Postcodes. Count: {}.", count); 8314fe6698SNan Zhou log<level::ERR>(msg.c_str()); 8414fe6698SNan Zhou } 8514fe6698SNan Zhou 8614fe6698SNan Zhou // Drain the queue into a list 8714fe6698SNan Zhou // TODO: maximum # postcodes? 8814fe6698SNan Zhou std::vector<uint64_t> result(postcodes_); 8914fe6698SNan Zhou postcodes_.clear(); 9014fe6698SNan Zhou 9114fe6698SNan Zhou return result; 9214fe6698SNan Zhou } 9314fe6698SNan Zhou 9414fe6698SNan Zhou std::string HostManager::GetMatch() 9514fe6698SNan Zhou { 9614fe6698SNan Zhou std::string obj{POSTCODE_OBJECTPATH}; 9714fe6698SNan Zhou return std::string("type='signal'," 9814fe6698SNan Zhou "interface='org.freedesktop.DBus.Properties'," 9914fe6698SNan Zhou "member='PropertiesChanged'," 10014fe6698SNan Zhou "path='" + 10114fe6698SNan Zhou obj + "'"); 10214fe6698SNan Zhou } 10314fe6698SNan Zhou 10414fe6698SNan Zhou void HostManager::PostPollerThread() 10514fe6698SNan Zhou { 10614fe6698SNan Zhou while (post_poller_enabled_) 10714fe6698SNan Zhou { 10814fe6698SNan Zhou bus_.process_discard(); 10914fe6698SNan Zhou bus_.wait(); 11014fe6698SNan Zhou } 11114fe6698SNan Zhou } 112