1a5d25dccSAndrew Jeffery /*
2a5d25dccSAndrew Jeffery // Copyright (c) 2018 Intel Corporation
3a5d25dccSAndrew Jeffery //
4a5d25dccSAndrew Jeffery // Licensed under the Apache License, Version 2.0 (the "License");
5a5d25dccSAndrew Jeffery // you may not use this file except in compliance with the License.
6a5d25dccSAndrew Jeffery // You may obtain a copy of the License at
7a5d25dccSAndrew Jeffery //
8a5d25dccSAndrew Jeffery // http://www.apache.org/licenses/LICENSE-2.0
9a5d25dccSAndrew Jeffery //
10a5d25dccSAndrew Jeffery // Unless required by applicable law or agreed to in writing, software
11a5d25dccSAndrew Jeffery // distributed under the License is distributed on an "AS IS" BASIS,
12a5d25dccSAndrew Jeffery // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a5d25dccSAndrew Jeffery // See the License for the specific language governing permissions and
14a5d25dccSAndrew Jeffery // limitations under the License.
15a5d25dccSAndrew Jeffery */
16a5d25dccSAndrew Jeffery /// \file entity_manager.hpp
17a5d25dccSAndrew Jeffery
18a5d25dccSAndrew Jeffery #pragma once
19a5d25dccSAndrew Jeffery
20a5d25dccSAndrew Jeffery #include "utils.hpp"
21a5d25dccSAndrew Jeffery
22a5d25dccSAndrew Jeffery #include <systemd/sd-journal.h>
23a5d25dccSAndrew Jeffery
24a5d25dccSAndrew Jeffery #include <boost/container/flat_map.hpp>
25a5d25dccSAndrew Jeffery #include <nlohmann/json.hpp>
26a5d25dccSAndrew Jeffery #include <sdbusplus/asio/object_server.hpp>
27a5d25dccSAndrew Jeffery
28a5d25dccSAndrew Jeffery #include <iostream>
29a5d25dccSAndrew Jeffery #include <list>
30a5d25dccSAndrew Jeffery #include <optional>
31a5d25dccSAndrew Jeffery #include <string>
32a5d25dccSAndrew Jeffery
33a5d25dccSAndrew Jeffery struct DBusDeviceDescriptor
34a5d25dccSAndrew Jeffery {
35a5d25dccSAndrew Jeffery DBusInterface interface;
36a5d25dccSAndrew Jeffery std::string path;
37a5d25dccSAndrew Jeffery };
38a5d25dccSAndrew Jeffery
39a5d25dccSAndrew Jeffery using FoundDevices = std::vector<DBusDeviceDescriptor>;
40a5d25dccSAndrew Jeffery
41a5d25dccSAndrew Jeffery struct CmpStr
42a5d25dccSAndrew Jeffery {
operator ()CmpStr43a5d25dccSAndrew Jeffery bool operator()(const char* a, const char* b) const
44a5d25dccSAndrew Jeffery {
45a5d25dccSAndrew Jeffery return std::strcmp(a, b) < 0;
46a5d25dccSAndrew Jeffery }
47a5d25dccSAndrew Jeffery };
48a5d25dccSAndrew Jeffery
49a5d25dccSAndrew Jeffery // underscore T for collison with dbus c api
50a5d25dccSAndrew Jeffery enum class probe_type_codes
51a5d25dccSAndrew Jeffery {
52a5d25dccSAndrew Jeffery FALSE_T,
53a5d25dccSAndrew Jeffery TRUE_T,
54a5d25dccSAndrew Jeffery AND,
55a5d25dccSAndrew Jeffery OR,
56a5d25dccSAndrew Jeffery FOUND,
57a5d25dccSAndrew Jeffery MATCH_ONE
58a5d25dccSAndrew Jeffery };
59a5d25dccSAndrew Jeffery
60*b7077437SPatrick Williams using FoundProbeTypeT = std::optional<boost::container::flat_map<
61*b7077437SPatrick Williams const char*, probe_type_codes, CmpStr>::const_iterator>;
62a5d25dccSAndrew Jeffery FoundProbeTypeT findProbeType(const std::string& probe);
63a5d25dccSAndrew Jeffery
64a5d25dccSAndrew Jeffery struct PerformScan : std::enable_shared_from_this<PerformScan>
65a5d25dccSAndrew Jeffery {
66a5d25dccSAndrew Jeffery PerformScan(nlohmann::json& systemConfiguration,
67a5d25dccSAndrew Jeffery nlohmann::json& missingConfigurations,
68a5d25dccSAndrew Jeffery std::list<nlohmann::json>& configurations,
69a5d25dccSAndrew Jeffery sdbusplus::asio::object_server& objServer,
70a5d25dccSAndrew Jeffery std::function<void()>&& callback);
71a5d25dccSAndrew Jeffery void updateSystemConfiguration(const nlohmann::json& recordRef,
72a5d25dccSAndrew Jeffery const std::string& probeName,
73a5d25dccSAndrew Jeffery FoundDevices& foundDevices);
74a3ca14a6SDelphine CC Chiu void run();
75a5d25dccSAndrew Jeffery virtual ~PerformScan();
76a5d25dccSAndrew Jeffery nlohmann::json& _systemConfiguration;
77a5d25dccSAndrew Jeffery nlohmann::json& _missingConfigurations;
78a5d25dccSAndrew Jeffery std::list<nlohmann::json> _configurations;
79a5d25dccSAndrew Jeffery sdbusplus::asio::object_server& objServer;
80a5d25dccSAndrew Jeffery std::function<void()> _callback;
81a5d25dccSAndrew Jeffery bool _passed = false;
82a5d25dccSAndrew Jeffery MapperGetSubTreeResponse dbusProbeObjects;
83a5d25dccSAndrew Jeffery std::vector<std::string> passedProbes;
84a5d25dccSAndrew Jeffery };
85a5d25dccSAndrew Jeffery
86a5d25dccSAndrew Jeffery // this class finds the needed dbus fields and on destruction runs the probe
87a5d25dccSAndrew Jeffery struct PerformProbe : std::enable_shared_from_this<PerformProbe>
88a5d25dccSAndrew Jeffery {
89a5d25dccSAndrew Jeffery PerformProbe(nlohmann::json& recordRef,
90a5d25dccSAndrew Jeffery const std::vector<std::string>& probeCommand,
91a5d25dccSAndrew Jeffery std::string probeName, std::shared_ptr<PerformScan>& scanPtr);
92a5d25dccSAndrew Jeffery virtual ~PerformProbe();
93a5d25dccSAndrew Jeffery
94a5d25dccSAndrew Jeffery nlohmann::json& recordRef;
95a5d25dccSAndrew Jeffery std::vector<std::string> _probeCommand;
96a5d25dccSAndrew Jeffery std::string probeName;
97a5d25dccSAndrew Jeffery std::shared_ptr<PerformScan> scan;
98a5d25dccSAndrew Jeffery };
99a5d25dccSAndrew Jeffery
logDeviceAdded(const nlohmann::json & record)100a5d25dccSAndrew Jeffery inline void logDeviceAdded(const nlohmann::json& record)
101a5d25dccSAndrew Jeffery {
102a5d25dccSAndrew Jeffery if (!deviceHasLogging(record))
103a5d25dccSAndrew Jeffery {
104a5d25dccSAndrew Jeffery return;
105a5d25dccSAndrew Jeffery }
106a5d25dccSAndrew Jeffery auto findType = record.find("Type");
107a5d25dccSAndrew Jeffery auto findAsset =
108a5d25dccSAndrew Jeffery record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
109a5d25dccSAndrew Jeffery
110a5d25dccSAndrew Jeffery std::string model = "Unknown";
111a5d25dccSAndrew Jeffery std::string type = "Unknown";
112a5d25dccSAndrew Jeffery std::string sn = "Unknown";
113a5d25dccSAndrew Jeffery std::string name = "Unknown";
114a5d25dccSAndrew Jeffery
115a5d25dccSAndrew Jeffery if (findType != record.end())
116a5d25dccSAndrew Jeffery {
117a5d25dccSAndrew Jeffery type = findType->get<std::string>();
118a5d25dccSAndrew Jeffery }
119a5d25dccSAndrew Jeffery if (findAsset != record.end())
120a5d25dccSAndrew Jeffery {
121a5d25dccSAndrew Jeffery auto findModel = findAsset->find("Model");
122a5d25dccSAndrew Jeffery auto findSn = findAsset->find("SerialNumber");
123a5d25dccSAndrew Jeffery if (findModel != findAsset->end())
124a5d25dccSAndrew Jeffery {
125a5d25dccSAndrew Jeffery model = findModel->get<std::string>();
126a5d25dccSAndrew Jeffery }
127a5d25dccSAndrew Jeffery if (findSn != findAsset->end())
128a5d25dccSAndrew Jeffery {
129a5d25dccSAndrew Jeffery const std::string* getSn = findSn->get_ptr<const std::string*>();
130a5d25dccSAndrew Jeffery if (getSn != nullptr)
131a5d25dccSAndrew Jeffery {
132a5d25dccSAndrew Jeffery sn = *getSn;
133a5d25dccSAndrew Jeffery }
134a5d25dccSAndrew Jeffery else
135a5d25dccSAndrew Jeffery {
136a5d25dccSAndrew Jeffery sn = findSn->dump();
137a5d25dccSAndrew Jeffery }
138a5d25dccSAndrew Jeffery }
139a5d25dccSAndrew Jeffery }
140a5d25dccSAndrew Jeffery
141a5d25dccSAndrew Jeffery auto findName = record.find("Name");
142a5d25dccSAndrew Jeffery if (findName != record.end())
143a5d25dccSAndrew Jeffery {
144a5d25dccSAndrew Jeffery name = findName->get<std::string>();
145a5d25dccSAndrew Jeffery }
146a5d25dccSAndrew Jeffery
147a5d25dccSAndrew Jeffery sd_journal_send("MESSAGE=Inventory Added: %s", name.c_str(), "PRIORITY=%i",
148a5d25dccSAndrew Jeffery LOG_INFO, "REDFISH_MESSAGE_ID=%s",
149a5d25dccSAndrew Jeffery "OpenBMC.0.1.InventoryAdded",
150a5d25dccSAndrew Jeffery "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
151a5d25dccSAndrew Jeffery type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
152a5d25dccSAndrew Jeffery }
153a5d25dccSAndrew Jeffery
logDeviceRemoved(const nlohmann::json & record)154a5d25dccSAndrew Jeffery inline void logDeviceRemoved(const nlohmann::json& record)
155a5d25dccSAndrew Jeffery {
156a5d25dccSAndrew Jeffery if (!deviceHasLogging(record))
157a5d25dccSAndrew Jeffery {
158a5d25dccSAndrew Jeffery return;
159a5d25dccSAndrew Jeffery }
160a5d25dccSAndrew Jeffery auto findType = record.find("Type");
161a5d25dccSAndrew Jeffery auto findAsset =
162a5d25dccSAndrew Jeffery record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
163a5d25dccSAndrew Jeffery
164a5d25dccSAndrew Jeffery std::string model = "Unknown";
165a5d25dccSAndrew Jeffery std::string type = "Unknown";
166a5d25dccSAndrew Jeffery std::string sn = "Unknown";
167a5d25dccSAndrew Jeffery std::string name = "Unknown";
168a5d25dccSAndrew Jeffery
169a5d25dccSAndrew Jeffery if (findType != record.end())
170a5d25dccSAndrew Jeffery {
171a5d25dccSAndrew Jeffery type = findType->get<std::string>();
172a5d25dccSAndrew Jeffery }
173a5d25dccSAndrew Jeffery if (findAsset != record.end())
174a5d25dccSAndrew Jeffery {
175a5d25dccSAndrew Jeffery auto findModel = findAsset->find("Model");
176a5d25dccSAndrew Jeffery auto findSn = findAsset->find("SerialNumber");
177a5d25dccSAndrew Jeffery if (findModel != findAsset->end())
178a5d25dccSAndrew Jeffery {
179a5d25dccSAndrew Jeffery model = findModel->get<std::string>();
180a5d25dccSAndrew Jeffery }
181a5d25dccSAndrew Jeffery if (findSn != findAsset->end())
182a5d25dccSAndrew Jeffery {
183a5d25dccSAndrew Jeffery const std::string* getSn = findSn->get_ptr<const std::string*>();
184a5d25dccSAndrew Jeffery if (getSn != nullptr)
185a5d25dccSAndrew Jeffery {
186a5d25dccSAndrew Jeffery sn = *getSn;
187a5d25dccSAndrew Jeffery }
188a5d25dccSAndrew Jeffery else
189a5d25dccSAndrew Jeffery {
190a5d25dccSAndrew Jeffery sn = findSn->dump();
191a5d25dccSAndrew Jeffery }
192a5d25dccSAndrew Jeffery }
193a5d25dccSAndrew Jeffery }
194a5d25dccSAndrew Jeffery
195a5d25dccSAndrew Jeffery auto findName = record.find("Name");
196a5d25dccSAndrew Jeffery if (findName != record.end())
197a5d25dccSAndrew Jeffery {
198a5d25dccSAndrew Jeffery name = findName->get<std::string>();
199a5d25dccSAndrew Jeffery }
200a5d25dccSAndrew Jeffery
201a5d25dccSAndrew Jeffery sd_journal_send("MESSAGE=Inventory Removed: %s", name.c_str(),
202a5d25dccSAndrew Jeffery "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
203a5d25dccSAndrew Jeffery "OpenBMC.0.1.InventoryRemoved",
204a5d25dccSAndrew Jeffery "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
205a5d25dccSAndrew Jeffery type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
206a5d25dccSAndrew Jeffery }
207