xref: /openbmc/phosphor-host-ipmid/user_channel/channel_mgmt.hpp (revision 74a2102e1fcf15097878449cd2989b5facd9b956)
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 ChannelProperties
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 ChannelProperties
58 {
59     std::string chName;
60     uint8_t chID;
61     bool isChValid;
62     uint8_t activeSessCount;
63     ChannelInfo chInfo;
64     ChannelAccessData chAccess;
65     size_t maxTransferSize;
66 };
67 
68 class ChannelConfig;
69 
70 ChannelConfig& getChannelConfigObject();
71 
72 class ChannelConfig
73 {
74   public:
75     ChannelConfig(const ChannelConfig&) = delete;
76     ChannelConfig& operator=(const ChannelConfig&) = delete;
77     ChannelConfig(ChannelConfig&&) = delete;
78     ChannelConfig& operator=(ChannelConfig&&) = delete;
79 
80     ~ChannelConfig();
81     ChannelConfig();
82 
83     /** @brief determines valid channel
84      *
85      *  @param[in] chNum - channel number
86      *
87      *  @return true if valid, false otherwise
88      */
89     bool isValidChannel(const uint8_t chNum);
90 
91     /** @brief determines valid authentication type
92      *
93      *  @param[in] chNum - channel number
94      *  @param[in] authType - authentication type
95      *
96      *  @return true if valid, false otherwise
97      */
98     bool isValidAuthType(const uint8_t chNum, const EAuthType& authType);
99 
100     /** @brief function to get channel name from channel number
101      *
102      *  @param[in] chNum - channel number index
103      *
104      *  @return network channel interface name
105      */
106     std::string getChannelName(const uint8_t chNum);
107 
108     /** @brief determines supported session type of a channel
109      *
110      *  @param[in] chNum - channel number
111      *
112      *  @return EChannelSessSupported - supported session type
113      */
114     EChannelSessSupported getChannelSessionSupport(const uint8_t chNum);
115 
116     /** @brief determines number of active sessions on a channel
117      *
118      *  @param[in] chNum - channel number
119      *
120      *  @return numer of active sessions
121      */
122     int getChannelActiveSessions(const uint8_t chNum);
123 
124     /** @brief determines maximum transfer size for a channel
125      *
126      *  @param[in] chNum - channel number
127      *
128      *  @return maximum bytes that can be transferred on this channel
129      */
130     size_t getChannelMaxTransferSize(uint8_t chNum);
131 
132     /** @brief provides channel info details
133      *
134      *  @param[in] chNum - channel number
135      *  @param[out] chInfo - channel info details
136      *
137      *  @return IPMI_CC_OK for success, others for failure.
138      */
139     ipmi_ret_t getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo);
140 
141     /** @brief provides channel access data
142      *
143      *  @param[in] chNum - channel number
144      *  @param[out] chAccessData - channel access data
145      *
146      *  @return IPMI_CC_OK for success, others for failure.
147      */
148     ipmi_ret_t getChannelAccessData(const uint8_t chNum,
149                                     ChannelAccess& chAccessData);
150 
151     /** @brief to set channel access data
152      *
153      *  @param[in] chNum - channel number
154      *  @param[in] chAccessData - channel access data
155      *  @param[in] setFlag - flag to indicate updatable fields
156      *
157      *  @return IPMI_CC_OK for success, others for failure.
158      */
159     ipmi_ret_t setChannelAccessData(const uint8_t chNum,
160                                     const ChannelAccess& chAccessData,
161                                     const uint8_t setFlag);
162 
163     /** @brief to get channel access data persistent data
164      *
165      *  @param[in] chNum - channel number
166      *  @param[out] chAccessData - channel access data
167      *
168      *  @return IPMI_CC_OK for success, others for failure.
169      */
170     ipmi_ret_t getChannelAccessPersistData(const uint8_t chNum,
171                                            ChannelAccess& chAccessData);
172 
173     /** @brief to set channel access data persistent data
174      *
175      *  @param[in] chNum - channel number
176      *  @param[in] chAccessData - channel access data
177      *  @param[in] setFlag - flag to indicate updatable fields
178      *
179      *  @return IPMI_CC_OK for success, others for failure.
180      */
181     ipmi_ret_t setChannelAccessPersistData(const uint8_t chNum,
182                                            const ChannelAccess& chAccessData,
183                                            const uint8_t setFlag);
184 
185     /** @brief provides supported authentication type for the channel
186      *
187      *  @param[in] chNum - channel number
188      *  @param[out] authTypeSupported - supported authentication type
189      *
190      *  @return IPMI_CC_OK for success, others for failure.
191      */
192     ipmi_ret_t getChannelAuthTypeSupported(const uint8_t chNum,
193                                            uint8_t& authTypeSupported);
194 
195     /** @brief provides enabled authentication type for the channel
196      *
197      *  @param[in] chNum - channel number
198      *  @param[in] priv - privilege
199      *  @param[out] authType - enabled authentication type
200      *
201      *  @return IPMI_CC_OK for success, others for failure.
202      */
203     ipmi_ret_t getChannelEnabledAuthType(const uint8_t chNum,
204                                          const uint8_t priv,
205                                          EAuthType& authType);
206 
207     /** @brief conver to channel privilege from system privilege
208      *
209      *  @param[in] value - privilege value
210      *
211      *  @return Channel privilege
212      */
213     CommandPrivilege convertToPrivLimitIndex(const std::string& value);
214 
215     /** @brief function to convert channel number to channel index
216      *
217      *  @param[in] chNum - channel number
218      *
219      *  @return channel index
220      */
221     uint8_t convertToChannelIndexNumber(const uint8_t chNum);
222 
223     /** @brief function to write persistent channel configuration to config file
224      *
225      *  @return 0 for success, -errno for failure.
226      */
227     int writeChannelPersistData();
228 
229     /** @brief function to write volatile channel configuration to config file
230      *
231      *  @return 0 for success, -errno for failure.
232      */
233     int writeChannelVolatileData();
234 
235     /** @brief function to get channel name from channel number
236      *
237      *  @param[in] chNum - channel number index
238      *
239      *  @return network channel interface name
240      */
241     std::string getChannelName(const int chNum);
242 
243   private:
244     uint32_t signalFlag = 0;
245     std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{
246         nullptr};
247     std::array<ChannelProperties, maxIpmiChannels> channelData;
248     std::time_t nvFileLastUpdatedTime;
249     std::time_t voltFileLastUpdatedTime;
250     boost::interprocess::file_lock mutexCleanupLock;
251     sdbusplus::bus::bus bus;
252     bool signalHndlrObjectState = false;
253     boost::interprocess::file_lock sigHndlrLock;
254 
255     /** @brief function to initialize persistent channel configuration
256      *
257      */
258     void initChannelPersistData();
259 
260     /** @brief function to set default channel configuration based on channel
261      * number
262      *
263      *  @param[in] chNum - channel number
264      *  @param[in] chName - channel name
265      */
266     void setDefaultChannelConfig(const uint8_t chNum,
267                                  const std::string& chName);
268 
269     /** @brief function to load all channel configuration
270      *
271      *  @return 0 for success, -errno for failure.
272      */
273     int loadChannelConfig();
274 
275     /** @brief function to read persistent channel data
276      *
277      *  @return 0 for success, -errno for failure.
278      */
279     int readChannelPersistData();
280 
281     /** @brief function to read volatile channel data
282      *
283      *  @return 0 for success, -errno for failure.
284      */
285     int readChannelVolatileData();
286 
287     /** @brief function to check and reload persistent channel data
288      *
289      *  @return 0 for success, -errno for failure.
290      */
291     int checkAndReloadNVData();
292 
293     /** @brief function to check and reload volatile channel data
294      *
295      *  @return 0 for success, -errno for failure.
296      */
297     int checkAndReloadVolatileData();
298 
299     /** @brief function to sync channel privilege with system network channel
300      * privilege
301      *
302      *  @return 0 for success, -errno for failure.
303      */
304     int syncNetworkChannelConfig();
305 
306     /** @brief function to set D-Bus property value
307      *
308      *  @param[in] service - service name
309      *  @param[in] objPath - object path
310      *  @param[in] interface - interface
311      *  @param[in] property - property name
312      *  @param[in] value - property value
313      *
314      *  @return 0 for success, -errno for failure.
315      */
316     int setDbusProperty(const std::string& service, const std::string& objPath,
317                         const std::string& interface,
318                         const std::string& property, const DbusVariant& value);
319 
320     /** @brief function to get D-Bus property value
321      *
322      *  @param[in] service - service name
323      *  @param[in] objPath - object path
324      *  @param[in] interface - interface
325      *  @param[in] property - property name
326      *  @param[out] value - property value
327      *
328      *  @return 0 for success, -errno for failure.
329      */
330     int getDbusProperty(const std::string& service, const std::string& objPath,
331                         const std::string& interface,
332                         const std::string& property, DbusVariant& value);
333 
334     /** @brief function to read json config file
335      *
336      *  @param[in] configFile - configuration file name
337      *
338      *  @return Json object
339      */
340     Json readJsonFile(const std::string& configFile);
341 
342     /** @brief function to write json config file
343      *
344      *  @param[in] configFile - configuration file name
345      *  @param[in] jsonData - json object
346      *
347      *  @return 0 for success, -errno for failure.
348      */
349     int writeJsonFile(const std::string& configFile, const Json& jsonData);
350 
351     /** @brief function to convert system access mode to Channel access mode
352      * type
353      *
354      *  @param[in] mode - access mode in string
355      *
356      *  @return Channel access mode.
357      */
358     EChannelAccessMode convertToAccessModeIndex(const std::string& mode);
359 
360     /** @brief function to convert access mode value to string
361      *
362      *  @param[in] value - acess mode value
363      *
364      *  @return access mode in string
365      */
366     std::string convertToAccessModeString(const uint8_t value);
367 
368     /** @brief function to convert privilege value to string
369      *
370      *  @param[in] value - privilege value
371      *
372      *  @return privilege in string
373      */
374     std::string convertToPrivLimitString(const uint8_t value);
375 
376     /** @brief function to convert session support string to value type
377      *
378      *  @param[in] value - session support type in string
379      *
380      *  @return support session type
381      */
382     EChannelSessSupported
383         convertToSessionSupportIndex(const std::string& value);
384 
385     /** @brief function to convert medium type string to value type
386      *
387      *  @param[in] value - medium type in string
388      *
389      *  @return channel medium type
390      */
391     EChannelMediumType convertToMediumTypeIndex(const std::string& value);
392 
393     /** @brief function to convert protocol type string to value type
394      *
395      *  @param[in] value - protocol type in string
396      *
397      *  @return channel protocol  type
398      */
399     EChannelProtocolType convertToProtocolTypeIndex(const std::string& value);
400 
401     /** @brief function to convert channel name to the IPMI channel number.
402      *
403      *  @param[in] chName - the channel name defined in the JSON input file
404      *  (i.e. LAN1)
405      *
406      *  @return IPMI channel number
407      */
408     int convertToChannelNumberFromChannelName(const std::string& chName);
409 
410     /** @brief function to handle Channel access property update through the
411      * D-Bus handler.
412      *
413      *  @param[in] path - D-Bus path to the network element (i.e. eth0)
414      *  @param[in] chProperties - D-Bus channel properties
415      */
416     void processChAccessPropChange(const std::string& path,
417                                    const DbusChObjProperties& chProperties);
418 
419     /** @brief function to retrieve last modification time for the named file
420      *
421      *  @param[in] fileName - the name of the file for which to acquire
422      *  timestamp data
423      *
424      *  @return time the file was last modified
425      */
426     std::time_t getUpdatedFileTime(const std::string& fileName);
427 
428     /** @brief function to convert the DBus path to a network channel name
429      *
430      *  @param[in] path - The DBus path to the device
431      *
432      *  @return network channel name (i.e. eth0)
433      */
434     std::string getChannelNameFromPath(const std::string& path);
435 };
436 
437 } // namespace ipmi
438