blob: b7711464cfb3e0c49060674cb97c8059f592eb46 [file] [log] [blame]
// 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 <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/message.hpp>
#include <format>
#include <functional>
#include <variant>
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<std::thread>(post_poller_thread, this);
}
int HostManager::DbusHandleSignal(sdbusplus::message_t& msg)
{
log<level::INFO>("Property Changed!");
std::string msgSensor, busName{POSTCODE_BUSNAME};
std::map<std::string,
std::variant<std::tuple<uint64_t, std::vector<uint8_t>>>>
msgData;
msg.read(msgSensor, msgData);
if (msgSensor == busName)
{
auto valPropMap = msgData.find("Value");
if (valPropMap != msgData.end())
{
uint64_t rawValue =
std::get<uint64_t>(std::get<0>(valPropMap->second));
PushPostcode(rawValue);
}
}
return 0;
}
void HostManager::PushPostcode(uint64_t postcode)
{
// Get lock
std::lock_guard<std::mutex> lock(postcodes_lock_);
// Add postcode to queue
postcodes_.push_back(postcode);
}
std::vector<uint64_t> HostManager::DrainPostcodes()
{
// Get lock
std::lock_guard<std::mutex> lock(postcodes_lock_);
auto count = postcodes_.size();
if (count > 0)
{
std::string msg = std::format("Draining Postcodes. Count: {}.", count);
log<level::ERR>(msg.c_str());
}
// Drain the queue into a list
// TODO: maximum # postcodes?
std::vector<uint64_t> 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();
}
}