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 
17 #pragma once
18 #include "channel_layer.hpp"
19 
20 #include <boost/interprocess/sync/file_lock.hpp>
21 #include <boost/interprocess/sync/named_recursive_mutex.hpp>
22 #include <cstdint>
23 #include <ctime>
24 #include <nlohmann/json.hpp>
25 #include <sdbusplus/bus.hpp>
26 
27 namespace ipmi
28 {
29 
30 using Json = nlohmann::json;
31 
32 static constexpr const char* ipmiChannelMutex = "ipmi_channel_mutex";
33 static constexpr const char* ipmiChMutexCleanupLockFile =
34     "/var/lib/ipmi/ipmi_channel_mutex_cleanup";
35 
36 struct ChannelAccessData
37 {
38     ChannelAccess chNonVolatileData;
39     ChannelAccess chVolatileData;
40 };
41 
42 struct ChannelData
43 {
44     std::string chName;
45     uint8_t chID;
46     bool isChValid;
47     uint8_t activeSessCount;
48     ChannelInfo chInfo;
49     ChannelAccessData chAccess;
50 };
51 
52 class ChannelConfig;
53 
54 ChannelConfig& getChannelConfigObject();
55 
56 class ChannelConfig
57 {
58   public:
59     ChannelConfig(const ChannelConfig&) = delete;
60     ChannelConfig& operator=(const ChannelConfig&) = delete;
61     ChannelConfig(ChannelConfig&&) = delete;
62     ChannelConfig& operator=(ChannelConfig&&) = delete;
63 
64     ~ChannelConfig() = default;
65     ChannelConfig();
66 
67     /** @brief determines valid channel
68      *
69      *  @param[in] chNum - channel number
70      *
71      *  @return true if valid, false otherwise
72      */
73     bool isValidChannel(const uint8_t& chNum);
74 
75     /** @brief determines valid authentication type
76      *
77      *  @param[in] chNum - channel number
78      *  @param[in] authType - authentication type
79      *
80      *  @return true if valid, false otherwise
81      */
82     bool isValidAuthType(const uint8_t& chNum, const EAuthType& authType);
83 
84     /** @brief determines supported session type of a channel
85      *
86      *  @param[in] chNum - channel number
87      *
88      *  @return EChannelSessSupported - supported session type
89      */
90     EChannelSessSupported getChannelSessionSupport(const uint8_t& chNum);
91 
92     /** @brief determines number of active sessions on a channel
93      *
94      *  @param[in] chNum - channel number
95      *
96      *  @return numer of active sessions
97      */
98     int getChannelActiveSessions(const uint8_t& chNum);
99 
100     /** @brief provides channel info details
101      *
102      *  @param[in] chNum - channel number
103      *  @param[out] chInfo - channel info details
104      *
105      *  @return IPMI_CC_OK for success, others for failure.
106      */
107     ipmi_ret_t getChannelInfo(const uint8_t& chNum, ChannelInfo& chInfo);
108 
109     /** @brief provides channel access data
110      *
111      *  @param[in] chNum - channel number
112      *  @param[out] chAccessData - channel access data
113      *
114      *  @return IPMI_CC_OK for success, others for failure.
115      */
116     ipmi_ret_t getChannelAccessData(const uint8_t& chNum,
117                                     ChannelAccess& chAccessData);
118 
119     /** @brief to set channel access data
120      *
121      *  @param[in] chNum - channel number
122      *  @param[in] chAccessData - channel access data
123      *  @param[in] setFlag - flag to indicate updatable fields
124      *
125      *  @return IPMI_CC_OK for success, others for failure.
126      */
127     ipmi_ret_t setChannelAccessData(const uint8_t& chNum,
128                                     const ChannelAccess& chAccessData,
129                                     const uint8_t& setFlag);
130 
131     /** @brief to get channel access data persistent data
132      *
133      *  @param[in] chNum - channel number
134      *  @param[out] chAccessData - channel access data
135      *
136      *  @return IPMI_CC_OK for success, others for failure.
137      */
138     ipmi_ret_t getChannelAccessPersistData(const uint8_t& chNum,
139                                            ChannelAccess& chAccessData);
140 
141     /** @brief to set channel access data persistent data
142      *
143      *  @param[in] chNum - channel number
144      *  @param[in] chAccessData - channel access data
145      *  @param[in] setFlag - flag to indicate updatable fields
146      *
147      *  @return IPMI_CC_OK for success, others for failure.
148      */
149     ipmi_ret_t setChannelAccessPersistData(const uint8_t& chNum,
150                                            const ChannelAccess& chAccessData,
151                                            const uint8_t& setFlag);
152 
153     /** @brief provides supported authentication type for the channel
154      *
155      *  @param[in] chNum - channel number
156      *  @param[out] authTypeSupported - supported authentication type
157      *
158      *  @return IPMI_CC_OK for success, others for failure.
159      */
160     ipmi_ret_t getChannelAuthTypeSupported(const uint8_t& chNum,
161                                            uint8_t& authTypeSupported);
162 
163     /** @brief provides enabled authentication type for the channel
164      *
165      *  @param[in] chNum - channel number
166      *  @param[in] priv - privilege
167      *  @param[out] authType - enabled authentication type
168      *
169      *  @return IPMI_CC_OK for success, others for failure.
170      */
171     ipmi_ret_t getChannelEnabledAuthType(const uint8_t& chNum,
172                                          const uint8_t& priv,
173                                          EAuthType& authType);
174 
175     std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{
176         nullptr};
177 
178   private:
179     ChannelData channelData[maxIpmiChannels];
180     std::time_t nvFileLastUpdatedTime;
181     std::time_t voltFileLastUpdatedTime;
182     std::time_t getUpdatedFileTime(const std::string& fileName);
183     boost::interprocess::file_lock mutexCleanupLock;
184     sdbusplus::bus::bus bus;
185 
186     /** @brief function to initialize persistent channel configuration
187      *
188      */
189     void initChannelPersistData();
190 
191     /** @brief function to set default channel configuration based on channel
192      * number
193      *
194      *  @param[in] chNum - channel number
195      *  @param[in] chName - channel name
196      */
197     void setDefaultChannelConfig(const uint8_t& chNum,
198                                  const std::string& chName);
199 
200     /** @brief function to load all channel configuration
201      *
202      *  @return 0 for success, -errno for failure.
203      */
204     int loadChannelConfig();
205 
206     /** @brief function to read persistent channel data
207      *
208      *  @return 0 for success, -errno for failure.
209      */
210     int readChannelPersistData();
211 
212     /** @brief function to write persistent channel configuration to config file
213      *
214      *  @return 0 for success, -errno for failure.
215      */
216     int writeChannelPersistData();
217 
218     /** @brief function to read volatile channel data
219      *
220      *  @return 0 for success, -errno for failure.
221      */
222     int readChannelVolatileData();
223 
224     /** @brief function to write volatile channel configuration to config file
225      *
226      *  @return 0 for success, -errno for failure.
227      */
228     int writeChannelVolatileData();
229 
230     /** @brief function to check and reload persistent channel data
231      *
232      *  @return 0 for success, -errno for failure.
233      */
234     int checkAndReloadNVData();
235 
236     /** @brief function to check and reload volatile channel data
237      *
238      *  @return 0 for success, -errno for failure.
239      */
240     int checkAndReloadVolatileData();
241 
242     /** @brief function to read json config file
243      *
244      *  @param[in] configFile - configuration file name
245      *
246      *  @return Json object
247      */
248     Json readJsonFile(const std::string& configFile);
249 
250     /** @brief function to write json config file
251      *
252      *  @param[in] configFile - configuration file name
253      *  @param[in] jsonData - json object
254      *
255      *  @return 0 for success, -errno for failure.
256      */
257     int writeJsonFile(const std::string& configFile, const Json& jsonData);
258 
259     /** @brief function to convert system access mode to Channel access mode
260      * type
261      *
262      *  @param[in] mode - access mode in string
263      *
264      *  @return Channel access mode.
265      */
266     EChannelAccessMode convertToAccessModeIndex(const std::string& mode);
267 
268     /** @brief function to convert access mode value to string
269      *
270      *  @param[in] value - acess mode value
271      *
272      *  @return access mode in string
273      */
274     std::string convertToAccessModeString(const uint8_t& value);
275 
276     /** @brief conver to channel privilege from system privilege
277      *
278      *  @param[in] value - privilege value
279      *
280      *  @return Channel privilege
281      */
282     CommandPrivilege convertToPrivLimitIndex(const std::string& value);
283 
284     /** @brief function to convert privilege value to string
285      *
286      *  @param[in] value - privilege value
287      *
288      *  @return privilege in string
289      */
290     std::string convertToPrivLimitString(const uint8_t& value);
291 
292     /** @brief function to convert session support string to value type
293      *
294      *  @param[in] value - session support type in string
295      *
296      *  @return support session type
297      */
298     EChannelSessSupported
299         convertToSessionSupportIndex(const std::string& value);
300 
301     /** @brief function to convert medium type string to value type
302      *
303      *  @param[in] value - medium type in string
304      *
305      *  @return channel medium type
306      */
307     EChannelMediumType convertToMediumTypeIndex(const std::string& value);
308 
309     /** @brief function to convert protocol type string to value type
310      *
311      *  @param[in] value - protocol type in string
312      *
313      *  @return channel protocol  type
314      */
315     EChannelProtocolType convertToProtocolTypeIndex(const std::string& value);
316 
317     /** @brief function to convert channel number to channel index
318      *
319      *  @param[in] chNum - channel number
320      *
321      *  @return channel index
322      */
323     uint8_t convertToChannelIndexNumber(const uint8_t& chNum);
324 
325     /** @brief function to convert channel name to network interface name
326      *
327      *  @param[in] value - channel interface name - ipmi centric
328      *
329      *  @return network channel interface name
330      */
331     std::string convertToNetInterface(const std::string& value);
332 };
333 
334 } // namespace ipmi
335