1*14fe6698SNan Zhou // Copyright 2021 Google LLC 2*14fe6698SNan Zhou // 3*14fe6698SNan Zhou // Licensed under the Apache License, Version 2.0 (the "License"); 4*14fe6698SNan Zhou // you may not use this file except in compliance with the License. 5*14fe6698SNan Zhou // You may obtain a copy of the License at 6*14fe6698SNan Zhou // 7*14fe6698SNan Zhou // http://www.apache.org/licenses/LICENSE-2.0 8*14fe6698SNan Zhou // 9*14fe6698SNan Zhou // Unless required by applicable law or agreed to in writing, software 10*14fe6698SNan Zhou // distributed under the License is distributed on an "AS IS" BASIS, 11*14fe6698SNan Zhou // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*14fe6698SNan Zhou // See the License for the specific language governing permissions and 13*14fe6698SNan Zhou // limitations under the License. 14*14fe6698SNan Zhou 15*14fe6698SNan Zhou #include "host_manager.hpp" 16*14fe6698SNan Zhou 17*14fe6698SNan Zhou #include <fmt/format.h> 18*14fe6698SNan Zhou 19*14fe6698SNan Zhou #include <phosphor-logging/log.hpp> 20*14fe6698SNan Zhou #include <sdbusplus/bus.hpp> 21*14fe6698SNan Zhou #include <sdbusplus/message.hpp> 22*14fe6698SNan Zhou 23*14fe6698SNan Zhou #include <functional> 24*14fe6698SNan Zhou #include <iostream> 25*14fe6698SNan Zhou #include <variant> 26*14fe6698SNan Zhou 27*14fe6698SNan Zhou using fmt::format; 28*14fe6698SNan Zhou using phosphor::logging::level; 29*14fe6698SNan Zhou using phosphor::logging::log; 30*14fe6698SNan Zhou 31*14fe6698SNan Zhou HostManager::HostManager() : 32*14fe6698SNan Zhou postcodes_(), bus_(sdbusplus::bus::new_default()), 33*14fe6698SNan Zhou signal_(bus_, HostManager::GetMatch().c_str(), 34*14fe6698SNan Zhou [this](auto& m) -> void { this->DbusHandleSignal(m); }), 35*14fe6698SNan Zhou post_poller_enabled_(true) 36*14fe6698SNan Zhou { 37*14fe6698SNan Zhou // Spin off thread to listen on bus_ 38*14fe6698SNan Zhou auto post_poller_thread = std::mem_fn(&HostManager::PostPollerThread); 39*14fe6698SNan Zhou post_poller_ = std::make_unique<std::thread>(post_poller_thread, this); 40*14fe6698SNan Zhou } 41*14fe6698SNan Zhou 42*14fe6698SNan Zhou int HostManager::DbusHandleSignal(sdbusplus::message::message& msg) 43*14fe6698SNan Zhou { 44*14fe6698SNan Zhou log<level::INFO>("Property Changed!"); 45*14fe6698SNan Zhou std::string msgSensor, busName{POSTCODE_BUSNAME}; 46*14fe6698SNan Zhou std::map<std::string, 47*14fe6698SNan Zhou std::variant<std::tuple<uint64_t, std::vector<uint8_t>>>> 48*14fe6698SNan Zhou msgData; 49*14fe6698SNan Zhou msg.read(msgSensor, msgData); 50*14fe6698SNan Zhou 51*14fe6698SNan Zhou if (msgSensor == busName) 52*14fe6698SNan Zhou { 53*14fe6698SNan Zhou auto valPropMap = msgData.find("Value"); 54*14fe6698SNan Zhou if (valPropMap != msgData.end()) 55*14fe6698SNan Zhou { 56*14fe6698SNan Zhou uint64_t rawValue = 57*14fe6698SNan Zhou std::get<uint64_t>(std::get<0>(valPropMap->second)); 58*14fe6698SNan Zhou 59*14fe6698SNan Zhou PushPostcode(rawValue); 60*14fe6698SNan Zhou } 61*14fe6698SNan Zhou } 62*14fe6698SNan Zhou 63*14fe6698SNan Zhou return 0; 64*14fe6698SNan Zhou } 65*14fe6698SNan Zhou 66*14fe6698SNan Zhou void HostManager::PushPostcode(uint64_t postcode) 67*14fe6698SNan Zhou { 68*14fe6698SNan Zhou // Get lock 69*14fe6698SNan Zhou std::lock_guard<std::mutex> lock(postcodes_lock_); 70*14fe6698SNan Zhou // Add postcode to queue 71*14fe6698SNan Zhou postcodes_.push_back(postcode); 72*14fe6698SNan Zhou } 73*14fe6698SNan Zhou 74*14fe6698SNan Zhou std::vector<uint64_t> HostManager::DrainPostcodes() 75*14fe6698SNan Zhou { 76*14fe6698SNan Zhou // Get lock 77*14fe6698SNan Zhou std::lock_guard<std::mutex> lock(postcodes_lock_); 78*14fe6698SNan Zhou 79*14fe6698SNan Zhou auto count = postcodes_.size(); 80*14fe6698SNan Zhou if (count > 0) 81*14fe6698SNan Zhou { 82*14fe6698SNan Zhou std::string msg = format("Draining Postcodes. Count: {}.", count); 83*14fe6698SNan Zhou log<level::ERR>(msg.c_str()); 84*14fe6698SNan Zhou } 85*14fe6698SNan Zhou 86*14fe6698SNan Zhou // Drain the queue into a list 87*14fe6698SNan Zhou // TODO: maximum # postcodes? 88*14fe6698SNan Zhou std::vector<uint64_t> result(postcodes_); 89*14fe6698SNan Zhou postcodes_.clear(); 90*14fe6698SNan Zhou 91*14fe6698SNan Zhou return result; 92*14fe6698SNan Zhou } 93*14fe6698SNan Zhou 94*14fe6698SNan Zhou std::string HostManager::GetMatch() 95*14fe6698SNan Zhou { 96*14fe6698SNan Zhou std::string obj{POSTCODE_OBJECTPATH}; 97*14fe6698SNan Zhou return std::string("type='signal'," 98*14fe6698SNan Zhou "interface='org.freedesktop.DBus.Properties'," 99*14fe6698SNan Zhou "member='PropertiesChanged'," 100*14fe6698SNan Zhou "path='" + 101*14fe6698SNan Zhou obj + "'"); 102*14fe6698SNan Zhou } 103*14fe6698SNan Zhou 104*14fe6698SNan Zhou void HostManager::PostPollerThread() 105*14fe6698SNan Zhou { 106*14fe6698SNan Zhou while (post_poller_enabled_) 107*14fe6698SNan Zhou { 108*14fe6698SNan Zhou bus_.process_discard(); 109*14fe6698SNan Zhou bus_.wait(); 110*14fe6698SNan Zhou } 111*14fe6698SNan Zhou } 112