1 /* 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 */ 16 /// \file entity_manager.hpp 17 18 #pragma once 19 20 #include "utils.hpp" 21 22 #include <systemd/sd-journal.h> 23 24 #include <boost/container/flat_map.hpp> 25 #include <nlohmann/json.hpp> 26 #include <sdbusplus/asio/object_server.hpp> 27 28 #include <iostream> 29 #include <list> 30 #include <optional> 31 #include <string> 32 33 struct DBusDeviceDescriptor 34 { 35 DBusInterface interface; 36 std::string path; 37 }; 38 39 using FoundDevices = std::vector<DBusDeviceDescriptor>; 40 41 struct 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 50 enum class probe_type_codes 51 { 52 FALSE_T, 53 TRUE_T, 54 AND, 55 OR, 56 FOUND, 57 MATCH_ONE 58 }; 59 60 using FoundProbeTypeT = 61 std::optional<boost::container::flat_map<const char*, probe_type_codes, 62 CmpStr>::const_iterator>; 63 FoundProbeTypeT findProbeType(const std::string& probe); 64 65 struct PerformScan : std::enable_shared_from_this<PerformScan> 66 { 67 PerformScan(nlohmann::json& systemConfiguration, 68 nlohmann::json& missingConfigurations, 69 std::list<nlohmann::json>& configurations, 70 sdbusplus::asio::object_server& objServer, 71 std::function<void()>&& callback); 72 void updateSystemConfiguration(const nlohmann::json& recordRef, 73 const std::string& probeName, 74 FoundDevices& foundDevices); 75 void run(void); 76 virtual ~PerformScan(); 77 nlohmann::json& _systemConfiguration; 78 nlohmann::json& _missingConfigurations; 79 std::list<nlohmann::json> _configurations; 80 sdbusplus::asio::object_server& objServer; 81 std::function<void()> _callback; 82 bool _passed = false; 83 MapperGetSubTreeResponse dbusProbeObjects; 84 std::vector<std::string> passedProbes; 85 }; 86 87 // this class finds the needed dbus fields and on destruction runs the probe 88 struct PerformProbe : std::enable_shared_from_this<PerformProbe> 89 { 90 PerformProbe(nlohmann::json& recordRef, 91 const std::vector<std::string>& probeCommand, 92 std::string probeName, std::shared_ptr<PerformScan>& scanPtr); 93 virtual ~PerformProbe(); 94 95 nlohmann::json& recordRef; 96 std::vector<std::string> _probeCommand; 97 std::string probeName; 98 std::shared_ptr<PerformScan> scan; 99 }; 100 101 inline void logDeviceAdded(const nlohmann::json& record) 102 { 103 if (!deviceHasLogging(record)) 104 { 105 return; 106 } 107 auto findType = record.find("Type"); 108 auto findAsset = 109 record.find("xyz.openbmc_project.Inventory.Decorator.Asset"); 110 111 std::string model = "Unknown"; 112 std::string type = "Unknown"; 113 std::string sn = "Unknown"; 114 std::string name = "Unknown"; 115 116 if (findType != record.end()) 117 { 118 type = findType->get<std::string>(); 119 } 120 if (findAsset != record.end()) 121 { 122 auto findModel = findAsset->find("Model"); 123 auto findSn = findAsset->find("SerialNumber"); 124 if (findModel != findAsset->end()) 125 { 126 model = findModel->get<std::string>(); 127 } 128 if (findSn != findAsset->end()) 129 { 130 const std::string* getSn = findSn->get_ptr<const std::string*>(); 131 if (getSn != nullptr) 132 { 133 sn = *getSn; 134 } 135 else 136 { 137 sn = findSn->dump(); 138 } 139 } 140 } 141 142 auto findName = record.find("Name"); 143 if (findName != record.end()) 144 { 145 name = findName->get<std::string>(); 146 } 147 148 sd_journal_send("MESSAGE=Inventory Added: %s", name.c_str(), "PRIORITY=%i", 149 LOG_INFO, "REDFISH_MESSAGE_ID=%s", 150 "OpenBMC.0.1.InventoryAdded", 151 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(), 152 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL); 153 } 154 155 inline void logDeviceRemoved(const nlohmann::json& record) 156 { 157 if (!deviceHasLogging(record)) 158 { 159 return; 160 } 161 auto findType = record.find("Type"); 162 auto findAsset = 163 record.find("xyz.openbmc_project.Inventory.Decorator.Asset"); 164 165 std::string model = "Unknown"; 166 std::string type = "Unknown"; 167 std::string sn = "Unknown"; 168 std::string name = "Unknown"; 169 170 if (findType != record.end()) 171 { 172 type = findType->get<std::string>(); 173 } 174 if (findAsset != record.end()) 175 { 176 auto findModel = findAsset->find("Model"); 177 auto findSn = findAsset->find("SerialNumber"); 178 if (findModel != findAsset->end()) 179 { 180 model = findModel->get<std::string>(); 181 } 182 if (findSn != findAsset->end()) 183 { 184 const std::string* getSn = findSn->get_ptr<const std::string*>(); 185 if (getSn != nullptr) 186 { 187 sn = *getSn; 188 } 189 else 190 { 191 sn = findSn->dump(); 192 } 193 } 194 } 195 196 auto findName = record.find("Name"); 197 if (findName != record.end()) 198 { 199 name = findName->get<std::string>(); 200 } 201 202 sd_journal_send("MESSAGE=Inventory Removed: %s", name.c_str(), 203 "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", 204 "OpenBMC.0.1.InventoryRemoved", 205 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(), 206 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL); 207 } 208