1 // 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 #pragma once
16 #include "nemora_types.hpp"
17 
18 #include <sdbusplus/bus.hpp>
19 #include <sdbusplus/message.hpp>
20 #include <sdbusplus/server.hpp>
21 
22 #include <mutex>
23 #include <queue>
24 #include <string>
25 #include <thread>
26 #include <unordered_map>
27 #include <vector>
28 
29 #define POSTCODE_OBJECTPATH "/xyz/openbmc_project/state/boot/raw0"
30 #define POSTCODE_BUSNAME "xyz.openbmc_project.State.Boot.Raw"
31 
32 class HostManager
33 {
34   public:
35     HostManager();
36     ~HostManager() = default;
37 
38     /**
39      * Callback for POST code DBus listener
40      * - msg: out-parameter for message received over DBus from callback
41      *
42      * - returns: error code or 0 for success
43      */
44     int DbusHandleSignal(sdbusplus::message::message& msg);
45 
46     /**
47      * Helper to construct match string for callback registration for POST
48      * listener
49      * - returns: match string for use in registering callback
50      */
51     static std::string GetMatch();
52 
53     /**
54      * Copies contents of POSTcode vector away to allow for sending via UDP
55      * - returns: vector filled with current state of postcodes_
56      */
57     std::vector<uint64_t> DrainPostcodes();
58 
59     /**
60      * Add POST code to vector, thread-safely
61      * - postcode: POST code to add, typically only 8 or 16 bits wide
62      */
63     void PushPostcode(uint64_t postcode);
64 
65   private:
66     /**
67      * Business logic of thread listening to DBus for POST codes
68      */
69     void PostPollerThread();
70 
71     // It's important that postcodes_ be initialized before post_poller_!
72     std::vector<uint64_t> postcodes_;
73     std::mutex postcodes_lock_;
74 
75     sdbusplus::bus::bus bus_;
76     sdbusplus::server::match::match signal_;
77     std::unique_ptr<std::thread> post_poller_;
78     bool post_poller_enabled_;
79 };
80