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