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 using DbusVariant =
33     sdbusplus::message::variant<std::vector<std::string>, std::string, bool>;
34 
35 using DbusChObjProperties = std::vector<std::pair<std::string, DbusVariant>>;
36 
37 static constexpr const char* ipmiChannelMutex = "ipmi_channel_mutex";
38 static constexpr const char* ipmiChMutexCleanupLockFile =
39     "/var/lib/ipmi/ipmi_channel_mutex_cleanup";
40 
41 /** @struct ChannelAccessData
42  *
43  *  Structure to store both non-volatile and volatile channel access information
44  *  as used by IPMI specification (refer spec sec 22.22 to 22.24)
45  */
46 struct ChannelAccessData
47 {
48     ChannelAccess chNonVolatileData;
49     ChannelAccess chVolatileData;
50 };
51 
52 /** @struct ChannelData
53  *
54  *  Structure for channel information - base structure to get all information
55  * about the channel.(refer spec sec 22.22 to 22.24)
56  */
57 struct ChannelData
58 {
59     std::string chName;
60     uint8_t chID;
61     bool isChValid;
62     uint8_t activeSessCount;
63     ChannelInfo chInfo;
64     ChannelAccessData chAccess;
65 };
66 
67 class ChannelConfig;
68 
69 ChannelConfig& getChannelConfigObject();
70 
71 class ChannelConfig
72 {
73   public:
74     ChannelConfig(const ChannelConfig&) = delete;
75     ChannelConfig& operator=(const ChannelConfig&) = delete;
76     ChannelConfig(ChannelConfig&&) = delete;
77     ChannelConfig& operator=(ChannelConfig&&) = delete;
78 
79     ~ChannelConfig();
80     ChannelConfig();
81 
82     /** @brief determines valid channel
83      *
84      *  @param[in] chNum - channel number
85      *
86      *  @return true if valid, false otherwise
87      */
88     bool isValidChannel(const uint8_t chNum);
89 
90     /** @brief determines valid authentication type
91      *
92      *  @param[in] chNum - channel number
93      *  @param[in] authType - authentication type
94      *
95      *  @return true if valid, false otherwise
96      */
97     bool isValidAuthType(const uint8_t chNum, const EAuthType& authType);
98 
99     /** @brief determines supported session type of a channel
100      *
101      *  @param[in] chNum - channel number
102      *
103      *  @return EChannelSessSupported - supported session type
104      */
105     EChannelSessSupported getChannelSessionSupport(const uint8_t chNum);
106 
107     /** @brief determines number of active sessions on a channel
108      *
109      *  @param[in] chNum - channel number
110      *
111      *  @return numer of active sessions
112      */
113     int getChannelActiveSessions(const uint8_t chNum);
114 
115     /** @brief provides channel info details
116      *
117      *  @param[in] chNum - channel number
118      *  @param[out] chInfo - channel info details
119      *
120      *  @return IPMI_CC_OK for success, others for failure.
121      */
122     ipmi_ret_t getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo);
123 
124     /** @brief provides channel access data
125      *
126      *  @param[in] chNum - channel number
127      *  @param[out] chAccessData - channel access data
128      *
129      *  @return IPMI_CC_OK for success, others for failure.
130      */
131     ipmi_ret_t getChannelAccessData(const uint8_t chNum,
132                                     ChannelAccess& chAccessData);
133 
134     /** @brief to set channel access data
135      *
136      *  @param[in] chNum - channel number
137      *  @param[in] chAccessData - channel access data
138      *  @param[in] setFlag - flag to indicate updatable fields
139      *
140      *  @return IPMI_CC_OK for success, others for failure.
141      */
142     ipmi_ret_t setChannelAccessData(const uint8_t chNum,
143                                     const ChannelAccess& chAccessData,
144                                     const uint8_t setFlag);
145 
146     /** @brief to get channel access data persistent data
147      *
148      *  @param[in] chNum - channel number
149      *  @param[out] chAccessData - channel access data
150      *
151      *  @return IPMI_CC_OK for success, others for failure.
152      */
153     ipmi_ret_t getChannelAccessPersistData(const uint8_t chNum,
154                                            ChannelAccess& chAccessData);
155 
156     /** @brief to set channel access data persistent data
157      *
158      *  @param[in] chNum - channel number
159      *  @param[in] chAccessData - channel access data
160      *  @param[in] setFlag - flag to indicate updatable fields
161      *
162      *  @return IPMI_CC_OK for success, others for failure.
163      */
164     ipmi_ret_t setChannelAccessPersistData(const uint8_t chNum,
165                                            const ChannelAccess& chAccessData,
166                                            const uint8_t setFlag);
167 
168     /** @brief provides supported authentication type for the channel
169      *
170      *  @param[in] chNum - channel number
171      *  @param[out] authTypeSupported - supported authentication type
172      *
173      *  @return IPMI_CC_OK for success, others for failure.
174      */
175     ipmi_ret_t getChannelAuthTypeSupported(const uint8_t chNum,
176                                            uint8_t& authTypeSupported);
177 
178     /** @brief provides enabled authentication type for the channel
179      *
180      *  @param[in] chNum - channel number
181      *  @param[in] priv - privilege
182      *  @param[out] authType - enabled authentication type
183      *
184      *  @return IPMI_CC_OK for success, others for failure.
185      */
186     ipmi_ret_t getChannelEnabledAuthType(const uint8_t chNum,
187                                          const uint8_t priv,
188                                          EAuthType& authType);
189 
190     /** @brief conver to channel privilege from system privilege
191      *
192      *  @param[in] value - privilege value
193      *
194      *  @return Channel privilege
195      */
196     CommandPrivilege convertToPrivLimitIndex(const std::string& value);
197 
198     /** @brief function to convert channel number to channel index
199      *
200      *  @param[in] chNum - channel number
201      *
202      *  @return channel index
203      */
204     uint8_t convertToChannelIndexNumber(const uint8_t chNum);
205 
206     /** @brief function to write persistent channel configuration to config file
207      *
208      *  @return 0 for success, -errno for failure.
209      */
210     int writeChannelPersistData();
211 
212     /** @brief function to write volatile channel configuration to config file
213      *
214      *  @return 0 for success, -errno for failure.
215      */
216     int writeChannelVolatileData();
217 
218     /** @brief function to get channel data based on channel number
219      *
220      *  @param[in] chNum - channel number
221      *
222      *  @return 0 for success, -errno for failure.
223      */
224     ChannelData* getChannelDataPtr(const uint8_t chNum);
225 
226     uint32_t signalFlag = 0;
227 
228     std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{
229         nullptr};
230 
231   private:
232     ChannelData channelData[maxIpmiChannels];
233     std::time_t nvFileLastUpdatedTime;
234     std::time_t voltFileLastUpdatedTime;
235     std::time_t getUpdatedFileTime(const std::string& fileName);
236     boost::interprocess::file_lock mutexCleanupLock;
237     sdbusplus::bus::bus bus;
238     bool signalHndlrObjectState = false;
239     boost::interprocess::file_lock sigHndlrLock;
240 
241     /** @brief function to initialize persistent channel configuration
242      *
243      */
244     void initChannelPersistData();
245 
246     /** @brief function to set default channel configuration based on channel
247      * number
248      *
249      *  @param[in] chNum - channel number
250      *  @param[in] chName - channel name
251      */
252     void setDefaultChannelConfig(const uint8_t chNum,
253                                  const std::string& chName);
254 
255     /** @brief function to load all channel configuration
256      *
257      *  @return 0 for success, -errno for failure.
258      */
259     int loadChannelConfig();
260 
261     /** @brief function to read persistent channel data
262      *
263      *  @return 0 for success, -errno for failure.
264      */
265     int readChannelPersistData();
266 
267     /** @brief function to read volatile channel data
268      *
269      *  @return 0 for success, -errno for failure.
270      */
271     int readChannelVolatileData();
272 
273     /** @brief function to check and reload persistent channel data
274      *
275      *  @return 0 for success, -errno for failure.
276      */
277     int checkAndReloadNVData();
278 
279     /** @brief function to check and reload volatile channel data
280      *
281      *  @return 0 for success, -errno for failure.
282      */
283     int checkAndReloadVolatileData();
284 
285     /** @brief function to sync channel privilege with system network channel
286      * privilege
287      *
288      *  @return 0 for success, -errno for failure.
289      */
290     int syncNetworkChannelConfig();
291 
292     /** @brief function to set D-Bus property value
293      *
294      *  @param[in] bus - bus
295      *  @param[in] service - service name
296      *  @param[in] objPath - object path
297      *  @param[in] interface - interface
298      *  @param[in] property - property name
299      *  @param[in] value - property value
300      *
301      *  @return 0 for success, -errno for failure.
302      */
303     int setDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
304                         const std::string& objPath,
305                         const std::string& interface,
306                         const std::string& property, const DbusVariant& value);
307 
308     /** @brief function to get D-Bus property value
309      *
310      *  @param[in] bus - bus
311      *  @param[in] service - service name
312      *  @param[in] objPath - object path
313      *  @param[in] interface - interface
314      *  @param[in] property - property name
315      *  @param[out] value - property value
316      *
317      *  @return 0 for success, -errno for failure.
318      */
319     int getDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
320                         const std::string& objPath,
321                         const std::string& interface,
322                         const std::string& property, DbusVariant& value);
323 
324     /** @brief function to read json config file
325      *
326      *  @param[in] configFile - configuration file name
327      *
328      *  @return Json object
329      */
330     Json readJsonFile(const std::string& configFile);
331 
332     /** @brief function to write json config file
333      *
334      *  @param[in] configFile - configuration file name
335      *  @param[in] jsonData - json object
336      *
337      *  @return 0 for success, -errno for failure.
338      */
339     int writeJsonFile(const std::string& configFile, const Json& jsonData);
340 
341     /** @brief function to convert system access mode to Channel access mode
342      * type
343      *
344      *  @param[in] mode - access mode in string
345      *
346      *  @return Channel access mode.
347      */
348     EChannelAccessMode convertToAccessModeIndex(const std::string& mode);
349 
350     /** @brief function to convert access mode value to string
351      *
352      *  @param[in] value - acess mode value
353      *
354      *  @return access mode in string
355      */
356     std::string convertToAccessModeString(const uint8_t value);
357 
358     /** @brief function to convert privilege value to string
359      *
360      *  @param[in] value - privilege value
361      *
362      *  @return privilege in string
363      */
364     std::string convertToPrivLimitString(const uint8_t value);
365 
366     /** @brief function to convert session support string to value type
367      *
368      *  @param[in] value - session support type in string
369      *
370      *  @return support session type
371      */
372     EChannelSessSupported
373         convertToSessionSupportIndex(const std::string& value);
374 
375     /** @brief function to convert medium type string to value type
376      *
377      *  @param[in] value - medium type in string
378      *
379      *  @return channel medium type
380      */
381     EChannelMediumType convertToMediumTypeIndex(const std::string& value);
382 
383     /** @brief function to convert protocol type string to value type
384      *
385      *  @param[in] value - protocol type in string
386      *
387      *  @return channel protocol  type
388      */
389     EChannelProtocolType convertToProtocolTypeIndex(const std::string& value);
390 
391     /** @brief function to convert channel name to network interface name
392      *
393      *  @param[in] value - channel interface name - ipmi centric
394      *
395      *  @return network channel interface name
396      */
397     std::string convertToNetInterface(const std::string& value);
398 };
399 
400 } // namespace ipmi
401