1 /* 2 // Copyright (c) 2019 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 #pragma once 17 18 #include "registries.hpp" 19 #include "registries/base_message_registry.hpp" 20 #include "registries/openbmc_message_registry.hpp" 21 #include "registries/resource_event_message_registry.hpp" 22 #include "registries/task_event_message_registry.hpp" 23 24 #include <app.hpp> 25 #include <query.hpp> 26 #include <registries/privilege_registry.hpp> 27 28 namespace redfish 29 { 30 31 inline void handleMessageRegistryFileCollectionGet( 32 crow::App& app, const crow::Request& req, 33 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 34 { 35 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 36 { 37 return; 38 } 39 // Collections don't include the static data added by SubRoute 40 // because it has a duplicate entry for members 41 42 asyncResp->res.jsonValue["@odata.type"] = 43 "#MessageRegistryFileCollection.MessageRegistryFileCollection"; 44 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries"; 45 asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection"; 46 asyncResp->res.jsonValue["Description"] = 47 "Collection of MessageRegistryFiles"; 48 asyncResp->res.jsonValue["Members@odata.count"] = 4; 49 asyncResp->res.jsonValue["Members"] = { 50 {{"@odata.id", "/redfish/v1/Registries/Base"}}, 51 {{"@odata.id", "/redfish/v1/Registries/TaskEvent"}}, 52 {{"@odata.id", "/redfish/v1/Registries/ResourceEvent"}}, 53 {{"@odata.id", "/redfish/v1/Registries/OpenBMC"}}}; 54 } 55 56 inline void requestRoutesMessageRegistryFileCollection(App& app) 57 { 58 /** 59 * Functions triggers appropriate requests on DBus 60 */ 61 BMCWEB_ROUTE(app, "/redfish/v1/Registries/") 62 .privileges(redfish::privileges::getMessageRegistryFileCollection) 63 .methods(boost::beast::http::verb::get)(std::bind_front( 64 handleMessageRegistryFileCollectionGet, std::ref(app))); 65 } 66 67 inline void handleMessageRoutesMessageRegistryFileGet( 68 crow::App& app, const crow::Request& req, 69 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 70 const std::string& registry) 71 { 72 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 73 { 74 return; 75 } 76 const registries::Header* header = nullptr; 77 std::string dmtf = "DMTF "; 78 const char* url = nullptr; 79 80 if (registry == "Base") 81 { 82 header = ®istries::base::header; 83 url = registries::base::url; 84 } 85 else if (registry == "TaskEvent") 86 { 87 header = ®istries::task_event::header; 88 url = registries::task_event::url; 89 } 90 else if (registry == "OpenBMC") 91 { 92 header = ®istries::openbmc::header; 93 dmtf.clear(); 94 } 95 else if (registry == "ResourceEvent") 96 { 97 header = ®istries::resource_event::header; 98 url = registries::resource_event::url; 99 } 100 else 101 { 102 messages::resourceNotFound( 103 asyncResp->res, "#MessageRegistryFile.v1_1_0.MessageRegistryFile", 104 registry); 105 return; 106 } 107 108 asyncResp->res.jsonValue["@odata.id"] = 109 "/redfish/v1/Registries/" + registry; 110 asyncResp->res.jsonValue["@odata.type"] = 111 "#MessageRegistryFile.v1_1_0.MessageRegistryFile"; 112 asyncResp->res.jsonValue["Name"] = registry + " Message Registry File"; 113 asyncResp->res.jsonValue["Description"] = 114 dmtf + registry + " Message Registry File Location"; 115 asyncResp->res.jsonValue["Id"] = header->registryPrefix; 116 asyncResp->res.jsonValue["Registry"] = header->id; 117 asyncResp->res.jsonValue["Languages"] = {"en"}; 118 asyncResp->res.jsonValue["Languages@odata.count"] = 1; 119 asyncResp->res.jsonValue["Location"] = { 120 {{"Language", "en"}, 121 {"Uri", "/redfish/v1/Registries/" + registry + "/" + registry}}}; 122 123 asyncResp->res.jsonValue["Location@odata.count"] = 1; 124 125 if (url != nullptr) 126 { 127 asyncResp->res.jsonValue["Location"][0]["PublicationUri"] = url; 128 } 129 } 130 131 inline void requestRoutesMessageRegistryFile(App& app) 132 { 133 BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/") 134 .privileges(redfish::privileges::getMessageRegistryFile) 135 .methods(boost::beast::http::verb::get)(std::bind_front( 136 handleMessageRoutesMessageRegistryFileGet, std::ref(app))); 137 } 138 139 inline void handleMessageRegistryGet( 140 crow::App& app, const crow::Request& req, 141 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 142 const std::string& registry, const std::string& registryMatch) 143 144 { 145 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 146 { 147 return; 148 } 149 const registries::Header* header = nullptr; 150 std::vector<const registries::MessageEntry*> registryEntries; 151 if (registry == "Base") 152 { 153 header = ®istries::base::header; 154 for (const registries::MessageEntry& entry : registries::base::registry) 155 { 156 registryEntries.emplace_back(&entry); 157 } 158 } 159 else if (registry == "TaskEvent") 160 { 161 header = ®istries::task_event::header; 162 for (const registries::MessageEntry& entry : 163 registries::task_event::registry) 164 { 165 registryEntries.emplace_back(&entry); 166 } 167 } 168 else if (registry == "OpenBMC") 169 { 170 header = ®istries::openbmc::header; 171 for (const registries::MessageEntry& entry : 172 registries::openbmc::registry) 173 { 174 registryEntries.emplace_back(&entry); 175 } 176 } 177 else if (registry == "ResourceEvent") 178 { 179 header = ®istries::resource_event::header; 180 for (const registries::MessageEntry& entry : 181 registries::resource_event::registry) 182 { 183 registryEntries.emplace_back(&entry); 184 } 185 } 186 else 187 { 188 messages::resourceNotFound( 189 asyncResp->res, "#MessageRegistryFile.v1_1_0.MessageRegistryFile", 190 registry); 191 return; 192 } 193 194 if (registry != registryMatch) 195 { 196 messages::resourceNotFound(asyncResp->res, header->type, registryMatch); 197 return; 198 } 199 200 asyncResp->res.jsonValue["@Redfish.Copyright"] = header->copyright; 201 asyncResp->res.jsonValue["@odata.type"] = header->type; 202 asyncResp->res.jsonValue["Id"] = header->id; 203 asyncResp->res.jsonValue["Name"] = header->name; 204 asyncResp->res.jsonValue["Language"] = header->language; 205 asyncResp->res.jsonValue["Description"] = header->description; 206 asyncResp->res.jsonValue["RegistryPrefix"] = header->registryPrefix; 207 asyncResp->res.jsonValue["RegistryVersion"] = header->registryVersion; 208 asyncResp->res.jsonValue["OwningEntity"] = header->owningEntity; 209 210 nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"]; 211 212 // Go through the Message Registry and populate each Message 213 for (const registries::MessageEntry* message : registryEntries) 214 { 215 nlohmann::json& obj = messageObj[message->first]; 216 obj["Description"] = message->second.description; 217 obj["Message"] = message->second.message; 218 obj["Severity"] = message->second.messageSeverity; 219 obj["MessageSeverity"] = message->second.messageSeverity; 220 obj["NumberOfArgs"] = message->second.numberOfArgs; 221 obj["Resolution"] = message->second.resolution; 222 if (message->second.numberOfArgs > 0) 223 { 224 nlohmann::json& messageParamArray = obj["ParamTypes"]; 225 messageParamArray = nlohmann::json::array(); 226 for (const char* str : message->second.paramTypes) 227 { 228 if (str == nullptr) 229 { 230 break; 231 } 232 messageParamArray.push_back(str); 233 } 234 } 235 } 236 } 237 238 inline void requestRoutesMessageRegistry(App& app) 239 { 240 BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/") 241 .privileges(redfish::privileges::getMessageRegistryFile) 242 .methods(boost::beast::http::verb::get)( 243 std::bind_front(handleMessageRegistryGet, std::ref(app))); 244 } 245 } // namespace redfish 246