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
HostManager()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
DbusHandleSignal(sdbusplus::message_t & msg)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
PushPostcode(uint64_t postcode)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
DrainPostcodes()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
GetMatch()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
PostPollerThread()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