blob: 2956b665372abf4d6e65dbd74e6de82c45e9660a [file] [log] [blame]
Matt Spinlerf60ac272019-12-11 13:47:50 -06001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "host_notifier.hpp"
17
18#include <phosphor-logging/log.hpp>
19
20namespace openpower::pels
21{
22
23const auto subscriptionName = "PELHostNotifier";
24
25using namespace phosphor::logging;
26
27HostNotifier::HostNotifier(Repository& repo, DataInterfaceBase& dataIface,
28 std::unique_ptr<HostInterface> hostIface) :
29 _repo(repo),
30 _dataIface(dataIface), _hostIface(std::move(hostIface))
31{
32 // Subscribe to be told about new PELs.
33 _repo.subscribeToAdds(subscriptionName,
34 std::bind(std::mem_fn(&HostNotifier::newLogCallback),
35 this, std::placeholders::_1));
36
37 // Add any existing PELs to the queue to send them if necessary.
38 _repo.for_each(std::bind(std::mem_fn(&HostNotifier::addPELToQueue), this,
39 std::placeholders::_1));
40
41 // Subscribe to be told about host state changes.
42 _dataIface.subscribeToHostStateChange(
43 subscriptionName,
44 std::bind(std::mem_fun(&HostNotifier::hostStateChange), this,
45 std::placeholders::_1));
46
47 // Set the function to call when the async reponse is received.
48 _hostIface->setResponseFunction(
49 std::bind(std::mem_fn(&HostNotifier::commandResponse), this,
50 std::placeholders::_1));
51
52 // Start sending logs if the host is running
53 if (!_pelQueue.empty() && _dataIface.isHostUp())
54 {
55 doNewLogNotify();
56 }
57}
58
59HostNotifier::~HostNotifier()
60{
61 _repo.unsubscribeFromAdds(subscriptionName);
62 _dataIface.unsubscribeFromHostStateChange(subscriptionName);
63}
64
65bool HostNotifier::addPELToQueue(const PEL& pel)
66{
67 if (enqueueRequired(pel.id()))
68 {
69 _pelQueue.push_back(pel.id());
70 }
71
72 // Return false so that Repo::for_each keeps going.
73 return false;
74}
75
76bool HostNotifier::enqueueRequired(uint32_t id) const
77{
78 bool required = true;
Matt Spinlera943b152019-12-11 14:44:50 -060079 Repository::LogID i{Repository::LogID::Pel{id}};
80
81 if (auto attributes = _repo.getPELAttributes(i); attributes)
82 {
83 auto a = attributes.value().get();
84
85 if ((a.hostState == TransmissionState::acked) ||
86 (a.hostState == TransmissionState::badPEL))
87 {
88 required = false;
89 }
90 else if (a.actionFlags.test(hiddenFlagBit) &&
91 (a.hmcState == TransmissionState::acked))
92 {
93 required = false;
94 }
95 else if (a.actionFlags.test(dontReportToHostFlagBit))
96 {
97 required = false;
98 }
99 }
100 else
101 {
102 using namespace phosphor::logging;
103 log<level::ERR>("Host Enqueue: Unable to find PEL ID in repository",
104 entry("PEL_ID=0x%X", id));
105 required = false;
106 }
Matt Spinlerf60ac272019-12-11 13:47:50 -0600107
108 return required;
109}
110
111void HostNotifier::newLogCallback(const PEL& pel)
112{
113 if (!enqueueRequired(pel.id()))
114 {
115 return;
116 }
117
118 _pelQueue.push_back(pel.id());
119
120 // TODO: Check if a send is needed now
121}
122
123void HostNotifier::doNewLogNotify()
124{
125}
126
127void HostNotifier::hostStateChange(bool hostUp)
128{
129}
130
131void HostNotifier::commandResponse(ResponseStatus status)
132{
133}
134
135} // namespace openpower::pels