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 = std::optional<boost::container::flat_map< 61 const char*, probe_type_codes, CmpStr>::const_iterator>; 62 FoundProbeTypeT findProbeType(const std::string& probe); 63 64 struct PerformScan : std::enable_shared_from_this<PerformScan> 65 { 66 PerformScan(nlohmann::json& systemConfiguration, 67 nlohmann::json& missingConfigurations, 68 std::list<nlohmann::json>& configurations, 69 sdbusplus::asio::object_server& objServer, 70 std::function<void()>&& callback); 71 void updateSystemConfiguration(const nlohmann::json& recordRef, 72 const std::string& probeName, 73 FoundDevices& foundDevices); 74 void run(); 75 virtual ~PerformScan(); 76 nlohmann::json& _systemConfiguration; 77 nlohmann::json& _missingConfigurations; 78 std::list<nlohmann::json> _configurations; 79 sdbusplus::asio::object_server& objServer; 80 std::function<void()> _callback; 81 bool _passed = false; 82 MapperGetSubTreeResponse dbusProbeObjects; 83 std::vector<std::string> passedProbes; 84 }; 85 86 // this class finds the needed dbus fields and on destruction runs the probe 87 struct PerformProbe : std::enable_shared_from_this<PerformProbe> 88 { 89 PerformProbe(nlohmann::json& recordRef, 90 const std::vector<std::string>& probeCommand, 91 std::string probeName, std::shared_ptr<PerformScan>& scanPtr); 92 virtual ~PerformProbe(); 93 94 nlohmann::json& recordRef; 95 std::vector<std::string> _probeCommand; 96 std::string probeName; 97 std::shared_ptr<PerformScan> scan; 98 }; 99 100 inline void logDeviceAdded(const nlohmann::json& record) 101 { 102 if (!deviceHasLogging(record)) 103 { 104 return; 105 } 106 auto findType = record.find("Type"); 107 auto findAsset = 108 record.find("xyz.openbmc_project.Inventory.Decorator.Asset"); 109 110 std::string model = "Unknown"; 111 std::string type = "Unknown"; 112 std::string sn = "Unknown"; 113 std::string name = "Unknown"; 114 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 { 129 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 } 138 } 139 } 140 141 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", 150 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(), 151 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL); 152 } 153 154 inline void logDeviceRemoved(const nlohmann::json& record) 155 { 156 if (!deviceHasLogging(record)) 157 { 158 return; 159 } 160 auto findType = record.find("Type"); 161 auto findAsset = 162 record.find("xyz.openbmc_project.Inventory.Decorator.Asset"); 163 164 std::string model = "Unknown"; 165 std::string type = "Unknown"; 166 std::string sn = "Unknown"; 167 std::string name = "Unknown"; 168 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 { 183 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 } 192 } 193 } 194 195 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", 204 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(), 205 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL); 206 } 207