blob: db7804e0117d01125f802ed80ee9c39431d49ed2 [file] [log] [blame]
James Feist1df06a42019-04-11 14:23:04 -07001/*
2// Copyright (c) 2018 Intel 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*/
Brad Bishope45d8c72022-05-25 15:12:53 -040016/// \file entity_manager.hpp
James Feist1df06a42019-04-11 14:23:04 -070017
18#pragma once
19
Brad Bishope45d8c72022-05-25 15:12:53 -040020#include "utils.hpp"
James Feist733f7652019-11-13 14:32:29 -080021
James Feist1df06a42019-04-11 14:23:04 -070022#include <systemd/sd-journal.h>
23
James Feist733f7652019-11-13 14:32:29 -080024#include <boost/container/flat_map.hpp>
James Feist1a996582019-05-14 15:10:06 -070025#include <nlohmann/json.hpp>
James Feist4dc617b2020-05-01 09:54:47 -070026#include <sdbusplus/asio/object_server.hpp>
James Feist8c505da2020-05-28 10:06:33 -070027
28#include <iostream>
29#include <list>
Andrew Jeffery666583b2021-12-01 15:50:12 +103030#include <optional>
James Feist1df06a42019-04-11 14:23:04 -070031#include <string>
32
Andrew Jefferyf5772d22022-04-12 22:05:30 +093033struct DBusDeviceDescriptor
34{
35 DBusInterface interface;
36 std::string path;
37};
38
39using FoundDevices = std::vector<DBusDeviceDescriptor>;
James Feist7d807752019-11-13 14:47:57 -080040
Andrew Jeffery47af65a2021-12-01 14:16:31 +103041struct CmpStr
42{
43 bool operator()(const char* a, const char* b) const
44 {
45 return std::strcmp(a, b) < 0;
46 }
47};
48
49// underscore T for collison with dbus c api
50enum class probe_type_codes
51{
52 FALSE_T,
53 TRUE_T,
54 AND,
55 OR,
56 FOUND,
57 MATCH_ONE
58};
59
Patrick Williamsb7077432024-08-16 15:22:21 -040060using FoundProbeTypeT = std::optional<boost::container::flat_map<
61 const char*, probe_type_codes, CmpStr>::const_iterator>;
Andrew Jeffery666583b2021-12-01 15:50:12 +103062FoundProbeTypeT findProbeType(const std::string& probe);
63
James Feist733f7652019-11-13 14:32:29 -080064struct PerformScan : std::enable_shared_from_this<PerformScan>
65{
James Feist733f7652019-11-13 14:32:29 -080066 PerformScan(nlohmann::json& systemConfiguration,
67 nlohmann::json& missingConfigurations,
68 std::list<nlohmann::json>& configurations,
James Feist4dc617b2020-05-01 09:54:47 -070069 sdbusplus::asio::object_server& objServer,
70 std::function<void()>&& callback);
Andrew Jefferyae6c1a42022-04-19 15:44:42 +093071 void updateSystemConfiguration(const nlohmann::json& recordRef,
72 const std::string& probeName,
Andrew Jefferyaf9b46b2022-04-21 12:34:43 +093073 FoundDevices& foundDevices);
Delphine CC Chiua3ca14a2024-03-27 17:02:24 +080074 void run();
James Feist733f7652019-11-13 14:32:29 -080075 virtual ~PerformScan();
76 nlohmann::json& _systemConfiguration;
77 nlohmann::json& _missingConfigurations;
78 std::list<nlohmann::json> _configurations;
James Feist4dc617b2020-05-01 09:54:47 -070079 sdbusplus::asio::object_server& objServer;
80 std::function<void()> _callback;
James Feist733f7652019-11-13 14:32:29 -080081 bool _passed = false;
Andrew Jefferyac20bd92022-04-05 11:11:40 +093082 MapperGetSubTreeResponse dbusProbeObjects;
James Feist733f7652019-11-13 14:32:29 -080083 std::vector<std::string> passedProbes;
84};
85
James Feist7d807752019-11-13 14:47:57 -080086// this class finds the needed dbus fields and on destruction runs the probe
87struct PerformProbe : std::enable_shared_from_this<PerformProbe>
88{
Andrew Jefferyea4ff022022-04-21 12:31:40 +093089 PerformProbe(nlohmann::json& recordRef,
90 const std::vector<std::string>& probeCommand,
91 std::string probeName, std::shared_ptr<PerformScan>& scanPtr);
James Feist7d807752019-11-13 14:47:57 -080092 virtual ~PerformProbe();
93
Andrew Jefferyea4ff022022-04-21 12:31:40 +093094 nlohmann::json& recordRef;
James Feist7d807752019-11-13 14:47:57 -080095 std::vector<std::string> _probeCommand;
Andrew Jefferyea4ff022022-04-21 12:31:40 +093096 std::string probeName;
James Feist7d807752019-11-13 14:47:57 -080097 std::shared_ptr<PerformScan> scan;
James Feist7d807752019-11-13 14:47:57 -080098};
99
James Feist1a996582019-05-14 15:10:06 -0700100inline void logDeviceAdded(const nlohmann::json& record)
James Feist1df06a42019-04-11 14:23:04 -0700101{
James Feist1ffa4a42020-04-22 18:27:17 -0700102 if (!deviceHasLogging(record))
103 {
104 return;
105 }
James Feist1a996582019-05-14 15:10:06 -0700106 auto findType = record.find("Type");
107 auto findAsset =
108 record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
109
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300110 std::string model = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700111 std::string type = "Unknown";
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300112 std::string sn = "Unknown";
Matt Spinler200bf402022-08-04 09:14:18 -0500113 std::string name = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700114
115 if (findType != record.end())
116 {
117 type = findType->get<std::string>();
118 }
119 if (findAsset != record.end())
120 {
121 auto findModel = findAsset->find("Model");
122 auto findSn = findAsset->find("SerialNumber");
123 if (findModel != findAsset->end())
124 {
125 model = findModel->get<std::string>();
126 }
127 if (findSn != findAsset->end())
128 {
James Feistf5125b02019-06-06 11:27:43 -0700129 const std::string* getSn = findSn->get_ptr<const std::string*>();
130 if (getSn != nullptr)
131 {
132 sn = *getSn;
133 }
134 else
135 {
136 sn = findSn->dump();
137 }
James Feist1a996582019-05-14 15:10:06 -0700138 }
139 }
140
Matt Spinler200bf402022-08-04 09:14:18 -0500141 auto findName = record.find("Name");
142 if (findName != record.end())
143 {
144 name = findName->get<std::string>();
145 }
146
147 sd_journal_send("MESSAGE=Inventory Added: %s", name.c_str(), "PRIORITY=%i",
148 LOG_INFO, "REDFISH_MESSAGE_ID=%s",
149 "OpenBMC.0.1.InventoryAdded",
James Feist1a996582019-05-14 15:10:06 -0700150 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
Matt Spinler200bf402022-08-04 09:14:18 -0500151 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
James Feist1df06a42019-04-11 14:23:04 -0700152}
153
James Feist1a996582019-05-14 15:10:06 -0700154inline void logDeviceRemoved(const nlohmann::json& record)
James Feist1df06a42019-04-11 14:23:04 -0700155{
James Feist1ffa4a42020-04-22 18:27:17 -0700156 if (!deviceHasLogging(record))
157 {
158 return;
159 }
James Feist1a996582019-05-14 15:10:06 -0700160 auto findType = record.find("Type");
161 auto findAsset =
162 record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
163
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300164 std::string model = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700165 std::string type = "Unknown";
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300166 std::string sn = "Unknown";
Matt Spinler200bf402022-08-04 09:14:18 -0500167 std::string name = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700168
169 if (findType != record.end())
170 {
171 type = findType->get<std::string>();
172 }
173 if (findAsset != record.end())
174 {
175 auto findModel = findAsset->find("Model");
176 auto findSn = findAsset->find("SerialNumber");
177 if (findModel != findAsset->end())
178 {
179 model = findModel->get<std::string>();
180 }
181 if (findSn != findAsset->end())
182 {
James Feistf5125b02019-06-06 11:27:43 -0700183 const std::string* getSn = findSn->get_ptr<const std::string*>();
184 if (getSn != nullptr)
185 {
186 sn = *getSn;
187 }
188 else
189 {
190 sn = findSn->dump();
191 }
James Feist1a996582019-05-14 15:10:06 -0700192 }
193 }
James Feist1df06a42019-04-11 14:23:04 -0700194
Matt Spinler200bf402022-08-04 09:14:18 -0500195 auto findName = record.find("Name");
196 if (findName != record.end())
197 {
198 name = findName->get<std::string>();
199 }
200
201 sd_journal_send("MESSAGE=Inventory Removed: %s", name.c_str(),
202 "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
203 "OpenBMC.0.1.InventoryRemoved",
James Feist1a996582019-05-14 15:10:06 -0700204 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
Matt Spinler200bf402022-08-04 09:14:18 -0500205 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
James Feist4dc617b2020-05-01 09:54:47 -0700206}