1 /*
2  Copyright (c) 2020 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 
17 #pragma once
18 
19 #include <sdbusplus/asio/object_server.hpp>
20 #include <sdbusplus/server.hpp>
21 #include <xyz/openbmc_project/BIOSConfig/Manager/server.hpp>
22 
23 #include <filesystem>
24 #include <string>
25 
26 namespace bios_config
27 {
28 
29 static constexpr auto service = "xyz.openbmc_project.BIOSConfigManager";
30 static constexpr auto objectPath = "/xyz/openbmc_project/bios_config/manager";
31 constexpr auto biosPersistFile = "biosData";
32 
33 using Base = sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager;
34 namespace fs = std::filesystem;
35 
36 /** @class Manager
37  *
38  *  @brief Implements the BIOS Manager
39  */
40 class Manager : public Base
41 {
42   public:
43     using BaseTable = std::map<
44         std::string,
45         std::tuple<
46             AttributeType, bool, std::string, std::string, std::string,
47             std::variant<int64_t, std::string>,
48             std::variant<int64_t, std::string>,
49             std::vector<std::tuple<
50                 BoundType, std::variant<int64_t, std::string>, std::string>>>>;
51 
52     using ResetFlag = std::map<std::string, ResetFlag>;
53 
54     using PendingAttributes =
55         std::map<std::string,
56                  std::tuple<AttributeType, std::variant<int64_t, std::string>>>;
57 
58     using PendingAttribute =
59         std::tuple<AttributeType, std::variant<int64_t, std::string>>;
60 
61     using AttributeName = std::string;
62     using AttributeValue = std::variant<int64_t, std::string>;
63     using CurrentValue = std::variant<int64_t, std::string>;
64     using PendingValue = std::variant<int64_t, std::string>;
65     using AttributeDetails =
66         std::tuple<AttributeType, CurrentValue, PendingValue>;
67 
68     Manager() = delete;
69     ~Manager() = default;
70     Manager(const Manager&) = delete;
71     Manager& operator=(const Manager&) = delete;
72     Manager(Manager&&) = delete;
73     Manager& operator=(Manager&&) = delete;
74 
75     /** @brief Constructs Manager object.
76      *
77      *  @param[in] objectServer  - object server
78      *  @param[in] systemBus - bus connection
79      */
80     Manager(sdbusplus::asio::object_server& objectServer,
81             std::shared_ptr<sdbusplus::asio::connection>& systemBus,
82             std::string persistPath);
83 
84     /** @brief Set the BIOS attribute with a new value, the new value is added
85      *         to the PendingAttribute.
86      *
87      *  @param[in] attribute - attribute name
88      *  @param[in] value - new value for the attribute
89      *
90      *  @return On error, throw exception
91      */
92     void setAttribute(AttributeName attribute, AttributeValue value) override;
93 
94     /** @brief Get the details of the BIOS attribute
95      *
96      *  @param[in] attribute - attribute name
97      *
98      *  @return On success, return the attribute details: attribute type,
99      *          current value, pending value. On error, throw exception
100      */
101     AttributeDetails getAttribute(AttributeName attribute) override;
102 
103     /** @brief Set the BaseBIOSTable property and clears the PendingAttributes
104      *         property
105      *
106      *  @param[in] value - new BaseBIOSTable
107      *
108      *  @return The new BaseBIOSTable that is applied.
109      */
110     BaseTable baseBIOSTable(BaseTable value) override;
111 
112     ResetFlag resetBIOSSettings(ResetFlag value);
113 
114     /** @brief Set the PendingAttributes property, additionally checks if the
115      *         attributes are in the BaseBIOSTable, whether the attributes are
116      *         read only and validate the attribute value based on the
117      *         attribute type. PendingAttributes is cleared if value is empty.
118      *
119      *  @param[in] value - new PendingAttributes to append to the
120      *                     PendingAttributes property
121      *
122      *  @return On success, return the new PendingAttributes property that is
123      *          set.Throw exception if the validation fails.
124      */
125     PendingAttributes pendingAttributes(PendingAttributes value) override;
126 
127   private:
128     /** @enum Index into the fields in the BaseBIOSTable
129      */
130     enum class Index : uint8_t
131     {
132         attributeType = 0,
133         readOnly,
134         displayName,
135         description,
136         menuPath,
137         currentValue,
138         defaultValue,
139         options,
140     };
141 
142     bool validateEnumOption(
143         const std::string& attrValue,
144         const std::vector<std::tuple<
145             BoundType, std::variant<int64_t, std::string>, std::string>>&
146             options);
147 
148     bool validateStringOption(
149         const std::string& attrValue,
150         const std::vector<std::tuple<
151             BoundType, std::variant<int64_t, std::string>, std::string>>&
152             options);
153 
154     bool validateIntegerOption(
155         const int64_t& attrValue,
156         const std::vector<std::tuple<
157             BoundType, std::variant<int64_t, std::string>, std::string>>&
158             options);
159 
160     sdbusplus::asio::object_server& objServer;
161     std::shared_ptr<sdbusplus::asio::connection>& systemBus;
162     std::filesystem::path biosFile;
163 };
164 
165 } // namespace bios_config
166