blob: b27ac21edf9901e16a4274b9fa5389a9214a6b0a [file] [log] [blame]
Nan Zhou14fe6692021-06-08 16:35:44 -07001// Copyright 2021 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "host_manager.hpp"
16
17#include <fmt/format.h>
18
19#include <phosphor-logging/log.hpp>
20#include <sdbusplus/bus.hpp>
21#include <sdbusplus/message.hpp>
22
23#include <functional>
24#include <iostream>
25#include <variant>
26
27using fmt::format;
28using phosphor::logging::level;
29using phosphor::logging::log;
30
31HostManager::HostManager() :
32 postcodes_(), bus_(sdbusplus::bus::new_default()),
33 signal_(bus_, HostManager::GetMatch().c_str(),
34 [this](auto& m) -> void { this->DbusHandleSignal(m); }),
35 post_poller_enabled_(true)
36{
37 // Spin off thread to listen on bus_
38 auto post_poller_thread = std::mem_fn(&HostManager::PostPollerThread);
39 post_poller_ = std::make_unique<std::thread>(post_poller_thread, this);
40}
41
42int HostManager::DbusHandleSignal(sdbusplus::message::message& msg)
43{
44 log<level::INFO>("Property Changed!");
45 std::string msgSensor, busName{POSTCODE_BUSNAME};
46 std::map<std::string,
47 std::variant<std::tuple<uint64_t, std::vector<uint8_t>>>>
48 msgData;
49 msg.read(msgSensor, msgData);
50
51 if (msgSensor == busName)
52 {
53 auto valPropMap = msgData.find("Value");
54 if (valPropMap != msgData.end())
55 {
56 uint64_t rawValue =
57 std::get<uint64_t>(std::get<0>(valPropMap->second));
58
59 PushPostcode(rawValue);
60 }
61 }
62
63 return 0;
64}
65
66void HostManager::PushPostcode(uint64_t postcode)
67{
68 // Get lock
69 std::lock_guard<std::mutex> lock(postcodes_lock_);
70 // Add postcode to queue
71 postcodes_.push_back(postcode);
72}
73
74std::vector<uint64_t> HostManager::DrainPostcodes()
75{
76 // Get lock
77 std::lock_guard<std::mutex> lock(postcodes_lock_);
78
79 auto count = postcodes_.size();
80 if (count > 0)
81 {
82 std::string msg = format("Draining Postcodes. Count: {}.", count);
83 log<level::ERR>(msg.c_str());
84 }
85
86 // Drain the queue into a list
87 // TODO: maximum # postcodes?
88 std::vector<uint64_t> result(postcodes_);
89 postcodes_.clear();
90
91 return result;
92}
93
94std::string HostManager::GetMatch()
95{
96 std::string obj{POSTCODE_OBJECTPATH};
97 return std::string("type='signal',"
98 "interface='org.freedesktop.DBus.Properties',"
99 "member='PropertiesChanged',"
100 "path='" +
101 obj + "'");
102}
103
104void HostManager::PostPollerThread()
105{
106 while (post_poller_enabled_)
107 {
108 bus_.process_discard();
109 bus_.wait();
110 }
111}