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