// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "host_manager.hpp" #include #include #include #include #include using phosphor::logging::level; using phosphor::logging::log; HostManager::HostManager() : postcodes_(), bus_(sdbusplus::bus::new_default()), signal_(bus_, HostManager::GetMatch().c_str(), [this](auto& m) -> void { this->DbusHandleSignal(m); }), post_poller_enabled_(true) { // Spin off thread to listen on bus_ auto post_poller_thread = std::mem_fn(&HostManager::PostPollerThread); post_poller_ = std::make_unique(post_poller_thread, this); } int HostManager::DbusHandleSignal(sdbusplus::message_t& msg) { log("Property Changed!"); std::string msgSensor, busName{POSTCODE_BUSNAME}; std::map>>> msgData; msg.read(msgSensor, msgData); if (msgSensor == busName) { auto valPropMap = msgData.find("Value"); if (valPropMap != msgData.end()) { uint64_t rawValue = std::get(std::get<0>(valPropMap->second)); PushPostcode(rawValue); } } return 0; } void HostManager::PushPostcode(uint64_t postcode) { // Get lock std::lock_guard lock(postcodes_lock_); // Add postcode to queue postcodes_.push_back(postcode); } std::vector HostManager::DrainPostcodes() { // Get lock std::lock_guard lock(postcodes_lock_); auto count = postcodes_.size(); if (count > 0) { std::string msg = std::format("Draining Postcodes. Count: {}.", count); log(msg.c_str()); } // Drain the queue into a list // TODO: maximum # postcodes? std::vector result(postcodes_); postcodes_.clear(); return result; } std::string HostManager::GetMatch() { std::string obj{POSTCODE_OBJECTPATH}; return std::string("type='signal'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'," "path='" + obj + "'"); } void HostManager::PostPollerThread() { while (post_poller_enabled_) { bus_.process_discard(); bus_.wait(); } }