xref: /openbmc/google-misc/dhcp-done/subprojects/nemora-postd/src/host_manager.cpp (revision 14fe6698f5bb26245bb807eb041eaa7a3c29ac39)
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