xref: /openbmc/entity-manager/src/entity_manager.hpp (revision b7077437d4a6b2cc935e1ba8d71f365ed324eb41)
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