blob: d4757dfeb4571244ac1889b4ca6e460c0d624204 [file] [log] [blame]
AppaRao Puli071f3f22018-05-24 16:45:30 +05301/*
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#include "channel_mgmt.hpp"
18
Johnathan Manteyfd61fc32021-04-08 11:05:38 -070019#include "user_layer.hpp"
AppaRao Puli071f3f22018-05-24 16:45:30 +053020
Johnathan Mantey0a2abc82021-02-18 12:39:12 -080021#include <ifaddrs.h>
AppaRao Puli071f3f22018-05-24 16:45:30 +053022#include <sys/stat.h>
Johnathan Mantey0a2abc82021-02-18 12:39:12 -080023#include <sys/types.h>
AppaRao Puli071f3f22018-05-24 16:45:30 +053024#include <unistd.h>
25
26#include <boost/interprocess/sync/scoped_lock.hpp>
George Liu42f64ef2024-02-05 15:03:18 +080027#include <ipmid/utils.hpp>
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -070028#include <phosphor-logging/lg2.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050029#include <sdbusplus/bus/match.hpp>
30#include <sdbusplus/server/object.hpp>
31
AppaRao Puli071f3f22018-05-24 16:45:30 +053032#include <cerrno>
AppaRao Puli9613ed72018-09-01 23:46:44 +053033#include <exception>
Patrick Williams3d8d7932022-06-16 12:01:28 -050034#include <filesystem>
AppaRao Puli071f3f22018-05-24 16:45:30 +053035#include <fstream>
AppaRao Puli071f3f22018-05-24 16:45:30 +053036#include <unordered_map>
37
38namespace ipmi
39{
40
AppaRao Puli071f3f22018-05-24 16:45:30 +053041static constexpr const char* channelAccessDefaultFilename =
42 "/usr/share/ipmi-providers/channel_access.json";
43static constexpr const char* channelConfigDefaultFilename =
44 "/usr/share/ipmi-providers/channel_config.json";
45static constexpr const char* channelNvDataFilename =
46 "/var/lib/ipmi/channel_access_nv.json";
47static constexpr const char* channelVolatileDataFilename =
48 "/run/ipmi/channel_access_volatile.json";
49
AppaRao Puli9613ed72018-09-01 23:46:44 +053050// TODO: Get the service name dynamically..
51static constexpr const char* networkIntfServiceName =
52 "xyz.openbmc_project.Network";
53static constexpr const char* networkIntfObjectBasePath =
54 "/xyz/openbmc_project/network";
55static constexpr const char* networkChConfigIntfName =
56 "xyz.openbmc_project.Channel.ChannelAccess";
57static constexpr const char* privilegePropertyString = "MaxPrivilege";
58static constexpr const char* dBusPropertiesInterface =
59 "org.freedesktop.DBus.Properties";
60static constexpr const char* propertiesChangedSignal = "PropertiesChanged";
Willy Tuac05aa12021-11-16 21:15:58 -080061static constexpr const char* interfaceAddedSignal = "InterfacesAdded";
62static constexpr const char* interfaceRemovedSignal = "InterfacesRemoved";
AppaRao Puli9613ed72018-09-01 23:46:44 +053063
AppaRao Puli071f3f22018-05-24 16:45:30 +053064// STRING DEFINES: Should sync with key's in JSON
65static constexpr const char* nameString = "name";
66static constexpr const char* isValidString = "is_valid";
67static constexpr const char* activeSessionsString = "active_sessions";
Vernon Mauery58317122018-11-28 11:02:43 -080068static constexpr const char* maxTransferSizeString = "max_transfer_size";
AppaRao Puli071f3f22018-05-24 16:45:30 +053069static constexpr const char* channelInfoString = "channel_info";
70static constexpr const char* mediumTypeString = "medium_type";
71static constexpr const char* protocolTypeString = "protocol_type";
72static constexpr const char* sessionSupportedString = "session_supported";
73static constexpr const char* isIpmiString = "is_ipmi";
Johnathan Manteyfd61fc32021-04-08 11:05:38 -070074static constexpr const char* isManagementNIC = "is_management_nic";
AppaRao Puli071f3f22018-05-24 16:45:30 +053075static constexpr const char* accessModeString = "access_mode";
76static constexpr const char* userAuthDisabledString = "user_auth_disabled";
77static constexpr const char* perMsgAuthDisabledString = "per_msg_auth_disabled";
78static constexpr const char* alertingDisabledString = "alerting_disabled";
79static constexpr const char* privLimitString = "priv_limit";
AppaRao Puli071f3f22018-05-24 16:45:30 +053080
81// Default values
82static constexpr const char* defaultChannelName = "RESERVED";
83static constexpr const uint8_t defaultMediumType =
84 static_cast<uint8_t>(EChannelMediumType::reserved);
85static constexpr const uint8_t defaultProtocolType =
86 static_cast<uint8_t>(EChannelProtocolType::reserved);
87static constexpr const uint8_t defaultSessionSupported =
88 static_cast<uint8_t>(EChannelSessSupported::none);
89static constexpr const uint8_t defaultAuthType =
90 static_cast<uint8_t>(EAuthType::none);
91static constexpr const bool defaultIsIpmiState = false;
Vernon Mauery58317122018-11-28 11:02:43 -080092static constexpr size_t smallChannelSize = 64;
AppaRao Puli071f3f22018-05-24 16:45:30 +053093
Lei YU4b0ddb62019-01-25 16:43:50 +080094std::unique_ptr<sdbusplus::bus::match_t> chPropertiesSignal
95 __attribute__((init_priority(101)));
AppaRao Puli9613ed72018-09-01 23:46:44 +053096
Willy Tuac05aa12021-11-16 21:15:58 -080097std::unique_ptr<sdbusplus::bus::match_t> chInterfaceAddedSignal
98 __attribute__((init_priority(101)));
99
100std::unique_ptr<sdbusplus::bus::match_t> chInterfaceRemovedSignal
101 __attribute__((init_priority(101)));
102
AppaRao Puli071f3f22018-05-24 16:45:30 +0530103// String mappings use in JSON config file
104static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
105 {"reserved", EChannelMediumType::reserved},
106 {"ipmb", EChannelMediumType::ipmb},
107 {"icmb-v1.0", EChannelMediumType::icmbV10},
108 {"icmb-v0.9", EChannelMediumType::icmbV09},
109 {"lan-802.3", EChannelMediumType::lan8032},
110 {"serial", EChannelMediumType::serial},
111 {"other-lan", EChannelMediumType::otherLan},
112 {"pci-smbus", EChannelMediumType::pciSmbus},
113 {"smbus-v1.0", EChannelMediumType::smbusV11},
114 {"smbus-v2.0", EChannelMediumType::smbusV20},
115 {"usb-1x", EChannelMediumType::usbV1x},
116 {"usb-2x", EChannelMediumType::usbV2x},
117 {"system-interface", EChannelMediumType::systemInterface},
118 {"oem", EChannelMediumType::oem},
119 {"unknown", EChannelMediumType::unknown}};
120
ssekarf4b2b092018-07-25 18:49:08 +0530121static std::unordered_map<EInterfaceIndex, std::string> interfaceMap = {
Richard Marian Thomaiyar43cb1282018-12-08 17:22:53 +0530122 {interfaceKCS, "SMS"},
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530123 {interfaceLAN1, "eth0"},
ssekarf4b2b092018-07-25 18:49:08 +0530124 {interfaceUnknown, "unknown"}};
125
AppaRao Puli071f3f22018-05-24 16:45:30 +0530126static std::unordered_map<std::string, EChannelProtocolType> protocolTypeMap = {
127 {"na", EChannelProtocolType::na},
128 {"ipmb-1.0", EChannelProtocolType::ipmbV10},
129 {"icmb-2.0", EChannelProtocolType::icmbV11},
130 {"reserved", EChannelProtocolType::reserved},
131 {"ipmi-smbus", EChannelProtocolType::ipmiSmbus},
132 {"kcs", EChannelProtocolType::kcs},
133 {"smic", EChannelProtocolType::smic},
134 {"bt-10", EChannelProtocolType::bt10},
135 {"bt-15", EChannelProtocolType::bt15},
136 {"tmode", EChannelProtocolType::tMode},
137 {"oem", EChannelProtocolType::oem}};
138
139static std::array<std::string, 4> accessModeList = {
140 "disabled", "pre-boot", "always_available", "shared"};
141
142static std::array<std::string, 4> sessionSupportList = {
143 "session-less", "single-session", "multi-session", "session-based"};
144
Sumanth Bhate4e633e2019-05-14 12:13:57 +0000145const std::array<std::string, PRIVILEGE_OEM + 1> privList = {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530146 "priv-reserved", "priv-callback", "priv-user",
147 "priv-operator", "priv-admin", "priv-oem"};
148
Richard Marian Thomaiyar55768e32019-03-02 22:54:37 +0530149std::string ChannelConfig::getChannelName(const uint8_t chNum)
Johnathan Mantey74a21022018-12-13 13:17:56 -0800150{
151 if (!isValidChannel(chNum))
152 {
George Liua0e545d2025-01-24 09:50:22 +0800153 lg2::error("Get channel name - Invalid channel number: {CHANNEL_ID}",
154 "CHANNEL_ID", chNum);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800155 throw std::invalid_argument("Invalid channel number");
156 }
157
158 return channelData[chNum].chName;
159}
160
161int ChannelConfig::convertToChannelNumberFromChannelName(
162 const std::string& chName)
163{
164 for (const auto& it : channelData)
165 {
166 if (it.chName == chName)
167 {
168 return it.chID;
169 }
170 }
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700171 lg2::error("Invalid channel name: {CHANNEL}", "CHANNEL", chName);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800172 throw std::invalid_argument("Invalid channel name");
173
174 return -1;
175}
176
177std::string ChannelConfig::getChannelNameFromPath(const std::string& path)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530178{
Peter Foley1214d6c2023-11-01 11:12:42 -0400179 const size_t length = strlen(networkIntfObjectBasePath);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530180 if (((length + 1) >= path.size()) ||
181 path.compare(0, length, networkIntfObjectBasePath))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530182 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700183 lg2::error("Invalid object path: {PATH}", "PATH", path);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530184 throw std::invalid_argument("Invalid object path");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530185 }
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530186 std::string chName(path, length + 1);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800187 return chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530188}
189
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800190void ChannelConfig::processChAccessPropChange(
191 const std::string& path, const DbusChObjProperties& chProperties)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530192{
193 // Get interface name from path. ex: '/xyz/openbmc_project/network/eth0'
Johnathan Mantey74a21022018-12-13 13:17:56 -0800194 std::string chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530195 try
196 {
Johnathan Mantey74a21022018-12-13 13:17:56 -0800197 chName = getChannelNameFromPath(path);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530198 }
199 catch (const std::invalid_argument& e)
200 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700201 lg2::error("Exception: {MSG}", "MSG", e.what());
AppaRao Puli9613ed72018-09-01 23:46:44 +0530202 return;
203 }
204
205 // Get the MaxPrivilege property value from the signal
206 std::string intfPrivStr;
207 std::string propName;
208 for (const auto& prop : chProperties)
209 {
210 if (prop.first == privilegePropertyString)
211 {
212 propName = privilegePropertyString;
Vernon Maueryf442e112019-04-09 11:44:36 -0700213 intfPrivStr = std::get<std::string>(prop.second);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530214 break;
215 }
216 }
217
218 if (propName != privilegePropertyString)
219 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700220 lg2::error("Unknown signal caught.");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530221 return;
222 }
223
224 if (intfPrivStr.empty())
225 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700226 lg2::error("Invalid privilege string for intf {INTF}", "INTF", chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530227 return;
228 }
229
230 uint8_t intfPriv = 0;
Johnathan Mantey74a21022018-12-13 13:17:56 -0800231 int chNum;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530232 try
233 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800234 intfPriv = static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800235 chNum = convertToChannelNumberFromChannelName(chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530236 }
237 catch (const std::invalid_argument& e)
238 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700239 lg2::error("Exception: {MSG}", "MSG", e.what());
AppaRao Puli9613ed72018-09-01 23:46:44 +0530240 return;
241 }
242
243 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800244 channelLock{*channelMutex};
AppaRao Puli9613ed72018-09-01 23:46:44 +0530245 // skip updating the values, if this property change originated from IPMI.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800246 if (signalFlag & (1 << chNum))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530247 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800248 signalFlag &= ~(1 << chNum);
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700249 lg2::debug("Request originated from IPMI so ignoring signal");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530250 return;
251 }
252
253 // Update both volatile & Non-volatile, if there is mismatch.
254 // as property change other than IPMI, has to update both volatile &
255 // non-volatile data.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800256 checkAndReloadVolatileData();
257 checkAndReloadNVData();
258 if (channelData[chNum].chAccess.chNonVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530259 {
260 // Update NV data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800261 channelData[chNum].chAccess.chNonVolatileData.privLimit = intfPriv;
262 if (writeChannelPersistData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530263 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700264 lg2::error("Failed to update the persist data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530265 return;
266 }
267
268 // Update Volatile data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800269 if (channelData[chNum].chAccess.chVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530270 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800271 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
272 if (writeChannelVolatileData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530273 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700274 lg2::error("Failed to update the volatile data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530275 return;
276 }
277 }
278 }
279
280 return;
281}
282
AppaRao Puli071f3f22018-05-24 16:45:30 +0530283ChannelConfig& getChannelConfigObject()
284{
285 static ChannelConfig channelConfig;
286 return channelConfig;
287}
288
AppaRao Puli9613ed72018-09-01 23:46:44 +0530289ChannelConfig::~ChannelConfig()
290{
291 if (signalHndlrObjectState)
292 {
293 chPropertiesSignal.reset();
Willy Tuac05aa12021-11-16 21:15:58 -0800294 chInterfaceAddedSignal.reset();
295 chInterfaceRemovedSignal.reset();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530296 sigHndlrLock.unlock();
297 }
298}
299
AppaRao Puli071f3f22018-05-24 16:45:30 +0530300ChannelConfig::ChannelConfig() : bus(ipmid_get_sd_bus_connection())
301{
302 std::ofstream mutexCleanUpFile;
303 mutexCleanUpFile.open(ipmiChMutexCleanupLockFile,
304 std::ofstream::out | std::ofstream::app);
305 if (!mutexCleanUpFile.good())
306 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700307 lg2::debug("Unable to open mutex cleanup file");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530308 return;
309 }
310 mutexCleanUpFile.close();
311 mutexCleanupLock =
312 boost::interprocess::file_lock(ipmiChMutexCleanupLockFile);
313 if (mutexCleanupLock.try_lock())
314 {
315 boost::interprocess::named_recursive_mutex::remove(ipmiChannelMutex);
316 channelMutex =
317 std::make_unique<boost::interprocess::named_recursive_mutex>(
318 boost::interprocess::open_or_create, ipmiChannelMutex);
319 mutexCleanupLock.lock_sharable();
320 }
321 else
322 {
323 mutexCleanupLock.lock_sharable();
324 channelMutex =
325 std::make_unique<boost::interprocess::named_recursive_mutex>(
326 boost::interprocess::open_or_create, ipmiChannelMutex);
327 }
328
329 initChannelPersistData();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530330
331 sigHndlrLock = boost::interprocess::file_lock(channelNvDataFilename);
George Liu1a2e1502022-07-08 12:20:19 +0800332 // Register it for single object and single process either netipmid /
AppaRao Puli9613ed72018-09-01 23:46:44 +0530333 // host-ipmid
334 if (chPropertiesSignal == nullptr && sigHndlrLock.try_lock())
335 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700336 lg2::debug("Registering channel signal handler.");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530337 chPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
338 bus,
339 sdbusplus::bus::match::rules::path_namespace(
340 networkIntfObjectBasePath) +
341 sdbusplus::bus::match::rules::type::signal() +
342 sdbusplus::bus::match::rules::member(propertiesChangedSignal) +
343 sdbusplus::bus::match::rules::interface(
344 dBusPropertiesInterface) +
345 sdbusplus::bus::match::rules::argN(0, networkChConfigIntfName),
Patrick Williams5d82f472022-07-22 19:26:53 -0500346 [&](sdbusplus::message_t& msg) {
Patrick Williams1318a5e2024-08-16 15:19:54 -0400347 DbusChObjProperties props;
348 std::string iface;
349 std::string path = msg.get_path();
350 msg.read(iface, props);
351 processChAccessPropChange(path, props);
352 });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530353 signalHndlrObjectState = true;
Willy Tuac05aa12021-11-16 21:15:58 -0800354
355 chInterfaceAddedSignal = std::make_unique<sdbusplus::bus::match_t>(
356 bus,
357 sdbusplus::bus::match::rules::type::signal() +
358 sdbusplus::bus::match::rules::member(interfaceAddedSignal) +
359 sdbusplus::bus::match::rules::argNpath(
360 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500361 [&](sdbusplus::message_t&) { initChannelPersistData(); });
Willy Tuac05aa12021-11-16 21:15:58 -0800362
363 chInterfaceRemovedSignal = std::make_unique<sdbusplus::bus::match_t>(
364 bus,
365 sdbusplus::bus::match::rules::type::signal() +
366 sdbusplus::bus::match::rules::member(interfaceRemovedSignal) +
367 sdbusplus::bus::match::rules::argNpath(
368 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500369 [&](sdbusplus::message_t&) { initChannelPersistData(); });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530370 }
371}
372
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530373bool ChannelConfig::isValidChannel(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530374{
Meera-Kattac1789482021-05-18 09:53:26 +0000375 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530376 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700377 lg2::debug("Invalid channel ID - Out of range");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530378 return false;
379 }
380
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800381 return channelData[chNum].isChValid;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530382}
383
Patrick Williams69b4c282025-03-03 11:19:13 -0500384EChannelSessSupported ChannelConfig::getChannelSessionSupport(
385 const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530386{
387 EChannelSessSupported chSessSupport =
388 (EChannelSessSupported)channelData[chNum].chInfo.sessionSupported;
389 return chSessSupport;
390}
391
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530392bool ChannelConfig::isValidAuthType(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530393 const EAuthType& authType)
394{
395 if ((authType < EAuthType::md2) || (authType > EAuthType::oem))
396 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700397 lg2::debug("Invalid authentication type");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530398 return false;
399 }
400
401 uint8_t authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
402 if (!(authTypeSupported & (1 << static_cast<uint8_t>(authType))))
403 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700404 lg2::debug("Authentication type is not supported.");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530405 return false;
406 }
407
408 return true;
409}
410
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530411int ChannelConfig::getChannelActiveSessions(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530412{
413 // TODO: TEMPORARY FIX
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800414 // Channels active session count is managed separately
AppaRao Puli071f3f22018-05-24 16:45:30 +0530415 // by monitoring channel session which includes LAN and
416 // RAKP layer changes. This will be updated, once the
417 // authentication part is implemented.
418 return channelData[chNum].activeSessCount;
419}
420
Vernon Mauery58317122018-11-28 11:02:43 -0800421size_t ChannelConfig::getChannelMaxTransferSize(uint8_t chNum)
422{
423 return channelData[chNum].maxTransferSize;
424}
425
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000426Cc ChannelConfig::getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530427{
428 if (!isValidChannel(chNum))
429 {
George Liua0e545d2025-01-24 09:50:22 +0800430 lg2::debug("Get channel info - Invalid channel: {CHANNEL}", "CHANNEL",
431 chNum);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000432 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530433 }
434
435 std::copy_n(reinterpret_cast<uint8_t*>(&channelData[chNum].chInfo),
436 sizeof(channelData[chNum].chInfo),
437 reinterpret_cast<uint8_t*>(&chInfo));
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000438 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530439}
440
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000441Cc ChannelConfig::getChannelAccessData(const uint8_t chNum,
442 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530443{
444 if (!isValidChannel(chNum))
445 {
George Liua0e545d2025-01-24 09:50:22 +0800446 lg2::debug("Get channel access data - Invalid channel: {CHANNEL}",
447 "CHANNEL", chNum);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000448 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530449 }
450
451 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
452 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700453 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000454 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530455 }
456
457 if (checkAndReloadVolatileData() != 0)
458 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000459 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530460 }
461
462 std::copy_n(
463 reinterpret_cast<uint8_t*>(&channelData[chNum].chAccess.chVolatileData),
464 sizeof(channelData[chNum].chAccess.chVolatileData),
465 reinterpret_cast<uint8_t*>(&chAccessData));
466
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000467 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530468}
469
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000470Cc ChannelConfig::setChannelAccessData(const uint8_t chNum,
471 const ChannelAccess& chAccessData,
472 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530473{
474 if (!isValidChannel(chNum))
475 {
George Liua0e545d2025-01-24 09:50:22 +0800476 lg2::debug("Set channel info - Invalid channel: {CHANNEL}", "CHANNEL",
477 chNum);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000478 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530479 }
480
481 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
482 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700483 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000484 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530485 }
486
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000487 if ((setFlag & setAccessMode) &&
488 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530489 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700490 lg2::debug("Invalid access mode specified");
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000491 return ccAccessModeNotSupportedForChannel;
492 }
493 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
494 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700495 lg2::debug("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000496 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530497 }
498
499 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
500 channelLock{*channelMutex};
501
502 if (checkAndReloadVolatileData() != 0)
503 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000504 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530505 }
506
507 if (setFlag & setAccessMode)
508 {
509 channelData[chNum].chAccess.chVolatileData.accessMode =
510 chAccessData.accessMode;
511 }
512 if (setFlag & setUserAuthEnabled)
513 {
514 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
515 chAccessData.userAuthDisabled;
516 }
517 if (setFlag & setMsgAuthEnabled)
518 {
519 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
520 chAccessData.perMsgAuthDisabled;
521 }
522 if (setFlag & setAlertingEnabled)
523 {
524 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
525 chAccessData.alertingDisabled;
526 }
527 if (setFlag & setPrivLimit)
528 {
529 channelData[chNum].chAccess.chVolatileData.privLimit =
530 chAccessData.privLimit;
531 }
532
533 // Write Volatile data to file
534 if (writeChannelVolatileData() != 0)
535 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700536 lg2::debug("Failed to update the channel volatile data");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000537 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530538 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000539 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530540}
541
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000542Cc ChannelConfig::getChannelAccessPersistData(const uint8_t chNum,
543 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530544{
545 if (!isValidChannel(chNum))
546 {
George Liua0e545d2025-01-24 09:50:22 +0800547 lg2::debug(
548 "Get channel access persist data - Invalid channel: {CHANNEL}",
549 "CHANNEL", chNum);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000550 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530551 }
552
553 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
554 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700555 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000556 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530557 }
558
559 if (checkAndReloadNVData() != 0)
560 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000561 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530562 }
563
564 std::copy_n(reinterpret_cast<uint8_t*>(
565 &channelData[chNum].chAccess.chNonVolatileData),
566 sizeof(channelData[chNum].chAccess.chNonVolatileData),
567 reinterpret_cast<uint8_t*>(&chAccessData));
568
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000569 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530570}
571
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000572Cc ChannelConfig::setChannelAccessPersistData(const uint8_t chNum,
573 const ChannelAccess& chAccessData,
574 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530575{
576 if (!isValidChannel(chNum))
577 {
George Liua0e545d2025-01-24 09:50:22 +0800578 lg2::debug(
579 "Set channel access persist data - Invalid channel: {CHANNEL}",
580 "CHANNEL", chNum);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000581 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530582 }
583
584 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
585 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700586 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000587 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530588 }
589
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000590 if ((setFlag & setAccessMode) &&
591 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530592 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700593 lg2::debug("Invalid access mode specified");
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000594 return ccAccessModeNotSupportedForChannel;
595 }
596 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
597 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700598 lg2::debug("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000599 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530600 }
601
602 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
603 channelLock{*channelMutex};
604
605 if (checkAndReloadNVData() != 0)
606 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000607 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530608 }
609
610 if (setFlag & setAccessMode)
611 {
612 channelData[chNum].chAccess.chNonVolatileData.accessMode =
613 chAccessData.accessMode;
614 }
615 if (setFlag & setUserAuthEnabled)
616 {
617 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
618 chAccessData.userAuthDisabled;
619 }
620 if (setFlag & setMsgAuthEnabled)
621 {
622 channelData[chNum].chAccess.chNonVolatileData.perMsgAuthDisabled =
623 chAccessData.perMsgAuthDisabled;
624 }
625 if (setFlag & setAlertingEnabled)
626 {
627 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
628 chAccessData.alertingDisabled;
629 }
630 if (setFlag & setPrivLimit)
631 {
AppaRao Puli9613ed72018-09-01 23:46:44 +0530632 // Send Update to network channel config interfaces over dbus
AppaRao Puli9613ed72018-09-01 23:46:44 +0530633 std::string privStr = convertToPrivLimitString(chAccessData.privLimit);
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530634 std::string networkIntfObj = std::string(networkIntfObjectBasePath) +
635 "/" + channelData[chNum].chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530636 try
637 {
Johnathan Manteyf92261d2018-12-10 15:49:34 -0800638 if (0 != setDbusProperty(networkIntfServiceName, networkIntfObj,
639 networkChConfigIntfName,
AppaRao Puli9613ed72018-09-01 23:46:44 +0530640 privilegePropertyString, privStr))
641 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700642 lg2::debug("Network interface '{INTERFACE}' does not exist",
643 "INTERFACE", channelData[chNum].chName);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000644 return ccUnspecifiedError;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530645 }
646 }
Patrick Williams5d82f472022-07-22 19:26:53 -0500647 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530648 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700649 lg2::error("Exception: Network interface does not exist");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000650 return ccInvalidFieldRequest;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530651 }
652 signalFlag |= (1 << chNum);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530653 channelData[chNum].chAccess.chNonVolatileData.privLimit =
654 chAccessData.privLimit;
655 }
656
657 // Write persistent data to file
658 if (writeChannelPersistData() != 0)
659 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700660 lg2::debug("Failed to update the presist data file");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000661 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530662 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000663 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530664}
665
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000666Cc ChannelConfig::getChannelAuthTypeSupported(const uint8_t chNum,
667 uint8_t& authTypeSupported)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530668{
669 if (!isValidChannel(chNum))
670 {
George Liua0e545d2025-01-24 09:50:22 +0800671 lg2::debug(
672 "Get channel auth type supported - Invalid channel: {CHANNEL}",
673 "CHANNEL", chNum);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000674 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530675 }
676
677 authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000678 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530679}
680
Patrick Williams1318a5e2024-08-16 15:19:54 -0400681Cc ChannelConfig::getChannelEnabledAuthType(
682 const uint8_t chNum, const uint8_t priv, EAuthType& authType)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530683{
684 if (!isValidChannel(chNum))
685 {
George Liua0e545d2025-01-24 09:50:22 +0800686 lg2::debug("Get channel enabled auth type - Invalid channel: {CHANNEL}",
687 "CHANNEL", chNum);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000688 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530689 }
690
691 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
692 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700693 lg2::debug("Sessionless channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000694 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530695 }
696
697 if (!isValidPrivLimit(priv))
698 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700699 lg2::debug("Invalid privilege specified.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000700 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530701 }
702
703 // TODO: Hardcoded for now. Need to implement.
704 authType = EAuthType::none;
705
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000706 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530707}
708
709std::time_t ChannelConfig::getUpdatedFileTime(const std::string& fileName)
710{
711 struct stat fileStat;
712 if (stat(fileName.c_str(), &fileStat) != 0)
713 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700714 lg2::debug("Error in getting last updated time stamp");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530715 return -EIO;
716 }
717 return fileStat.st_mtime;
718}
719
Patrick Williams69b4c282025-03-03 11:19:13 -0500720EChannelAccessMode ChannelConfig::convertToAccessModeIndex(
721 const std::string& mode)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530722{
723 auto iter = std::find(accessModeList.begin(), accessModeList.end(), mode);
724 if (iter == accessModeList.end())
725 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700726 lg2::error("Invalid access mode: {MODE_STR}", "MODE_STR", mode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530727 throw std::invalid_argument("Invalid access mode.");
728 }
729
730 return static_cast<EChannelAccessMode>(
731 std::distance(accessModeList.begin(), iter));
732}
733
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530734std::string ChannelConfig::convertToAccessModeString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530735{
736 if (accessModeList.size() <= value)
737 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700738 lg2::error("Invalid access mode: {MODE_IDX}", "MODE_IDX", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530739 throw std::invalid_argument("Invalid access mode.");
740 }
741
742 return accessModeList.at(value);
743}
744
Patrick Williams69b4c282025-03-03 11:19:13 -0500745CommandPrivilege ChannelConfig::convertToPrivLimitIndex(
746 const std::string& value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530747{
748 auto iter = std::find(privList.begin(), privList.end(), value);
749 if (iter == privList.end())
750 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700751 lg2::error("Invalid privilege: {PRIV_STR}", "PRIV_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530752 throw std::invalid_argument("Invalid privilege.");
753 }
754
755 return static_cast<CommandPrivilege>(std::distance(privList.begin(), iter));
756}
757
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530758std::string ChannelConfig::convertToPrivLimitString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530759{
760 if (privList.size() <= value)
761 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700762 lg2::error("Invalid privilege: {PRIV_IDX.", "PRIV_IDX", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530763 throw std::invalid_argument("Invalid privilege.");
764 }
765
766 return privList.at(value);
767}
768
Patrick Williams69b4c282025-03-03 11:19:13 -0500769EChannelSessSupported ChannelConfig::convertToSessionSupportIndex(
770 const std::string& value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530771{
Patrick Williams1318a5e2024-08-16 15:19:54 -0400772 auto iter =
773 std::find(sessionSupportList.begin(), sessionSupportList.end(), value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530774 if (iter == sessionSupportList.end())
775 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700776 lg2::error("Invalid session supported: {SESS_STR}", "SESS_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530777 throw std::invalid_argument("Invalid session supported.");
778 }
779
780 return static_cast<EChannelSessSupported>(
781 std::distance(sessionSupportList.begin(), iter));
782}
783
Patrick Williams69b4c282025-03-03 11:19:13 -0500784EChannelMediumType ChannelConfig::convertToMediumTypeIndex(
785 const std::string& value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530786{
787 std::unordered_map<std::string, EChannelMediumType>::iterator it =
788 mediumTypeMap.find(value);
789 if (it == mediumTypeMap.end())
790 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700791 lg2::error("Invalid medium type: {MEDIUM_STR}", "MEDIUM_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530792 throw std::invalid_argument("Invalid medium type.");
793 }
794
795 return static_cast<EChannelMediumType>(it->second);
796}
797
Patrick Williams69b4c282025-03-03 11:19:13 -0500798EChannelProtocolType ChannelConfig::convertToProtocolTypeIndex(
799 const std::string& value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530800{
801 std::unordered_map<std::string, EChannelProtocolType>::iterator it =
802 protocolTypeMap.find(value);
803 if (it == protocolTypeMap.end())
804 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700805 lg2::error("Invalid protocol type: {PROTO_STR}", "PROTO_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530806 throw std::invalid_argument("Invalid protocol type.");
807 }
808
809 return static_cast<EChannelProtocolType>(it->second);
810}
811
812Json ChannelConfig::readJsonFile(const std::string& configFile)
813{
814 std::ifstream jsonFile(configFile);
815 if (!jsonFile.good())
816 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700817 lg2::info("JSON file '{FILE_NAME}' not found", "FILE_NAME", configFile);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530818 return nullptr;
819 }
820
821 Json data = nullptr;
822 try
823 {
824 data = Json::parse(jsonFile, nullptr, false);
825 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500826 catch (const Json::parse_error& e)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530827 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700828 lg2::debug("Corrupted channel config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +0530829 throw std::runtime_error("Corrupted channel config file");
830 }
831
832 return data;
833}
834
835int ChannelConfig::writeJsonFile(const std::string& configFile,
836 const Json& jsonData)
837{
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530838 const std::string tmpFile = configFile + "_tmp";
839 int fd = open(tmpFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_SYNC,
840 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
841 if (fd < 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530842 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700843 lg2::error("Error in creating json file '{FILE_NAME}'", "FILE_NAME",
844 tmpFile);
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530845 return -EIO;
846 }
847 const auto& writeData = jsonData.dump();
848 if (write(fd, writeData.c_str(), writeData.size()) !=
849 static_cast<ssize_t>(writeData.size()))
850 {
851 close(fd);
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700852 lg2::error("Error in writing configuration file '{FILE_NAME}'",
853 "FILE_NAME", tmpFile);
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530854 return -EIO;
855 }
856 close(fd);
857
858 if (std::rename(tmpFile.c_str(), configFile.c_str()) != 0)
859 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700860 lg2::error("Error in renaming temporary data file '{FILE_NAME}'",
861 "FILE_NAME", tmpFile);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530862 return -EIO;
863 }
864
AppaRao Puli071f3f22018-05-24 16:45:30 +0530865 return 0;
866}
867
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530868void ChannelConfig::setDefaultChannelConfig(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530869 const std::string& chName)
870{
871 channelData[chNum].chName = chName;
872 channelData[chNum].chID = chNum;
873 channelData[chNum].isChValid = false;
874 channelData[chNum].activeSessCount = 0;
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700875 channelData[chNum].isManagementNIC = false;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530876
877 channelData[chNum].chInfo.mediumType = defaultMediumType;
878 channelData[chNum].chInfo.protocolType = defaultProtocolType;
879 channelData[chNum].chInfo.sessionSupported = defaultSessionSupported;
880 channelData[chNum].chInfo.isIpmi = defaultIsIpmiState;
881 channelData[chNum].chInfo.authTypeSupported = defaultAuthType;
882}
883
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700884uint8_t ChannelConfig::getManagementNICID()
885{
886 static bool idFound = false;
887 static uint8_t id = 0;
888
889 if (idFound)
890 {
891 return id;
892 }
893
894 for (uint8_t chIdx = 0; chIdx < maxIpmiChannels; chIdx++)
895 {
896 if (channelData[chIdx].isManagementNIC)
897 {
898 id = chIdx;
899 idFound = true;
900 break;
901 }
902 }
903
904 if (!idFound)
905 {
906 id = static_cast<uint8_t>(EChannelID::chanLan1);
907 idFound = true;
908 }
909 return id;
910}
911
AppaRao Puli071f3f22018-05-24 16:45:30 +0530912int ChannelConfig::loadChannelConfig()
913{
914 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
915 channelLock{*channelMutex};
916
917 Json data = readJsonFile(channelConfigDefaultFilename);
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800918 if (data.empty())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530919 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700920 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530921 return -EIO;
922 }
923
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800924 channelData.fill(ChannelProperties{});
925
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800926 // Collect the list of NIC interfaces connected to the BMC. Use this
927 // information to only add IPMI channels that have active NIC interfaces.
Snehalatha Venkatesh55f5d532021-07-13 11:06:36 +0000928 struct ifaddrs *ifaddr = nullptr, *ifa = nullptr;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800929 if (int err = getifaddrs(&ifaddr); err < 0)
930 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700931 lg2::debug("Unable to acquire network interfaces");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800932 return -EIO;
933 }
934
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800935 for (int chNum = 0; chNum < maxIpmiChannels; chNum++)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530936 {
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800937 try
AppaRao Puli071f3f22018-05-24 16:45:30 +0530938 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530939 std::string chKey = std::to_string(chNum);
940 Json jsonChData = data[chKey].get<Json>();
941 if (jsonChData.is_null())
942 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530943 // If user didn't want to configure specific channel (say
944 // reserved channel), then load that index with default values.
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800945 setDefaultChannelConfig(chNum, defaultChannelName);
946 continue;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530947 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800948 Json jsonChInfo = jsonChData[channelInfoString].get<Json>();
949 if (jsonChInfo.is_null())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530950 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700951 lg2::error("Invalid/corrupted channel config file");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800952 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800953 return -EBADMSG;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530954 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800955
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800956 bool channelFound = true;
957 // Confirm the LAN channel is present
958 if (jsonChInfo[mediumTypeString].get<std::string>() == "lan-802.3")
959 {
960 channelFound = false;
Jayanth Othayotha6fb32d2024-12-15 10:55:22 -0600961 for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800962 {
963 if (jsonChData[nameString].get<std::string>() ==
964 ifa->ifa_name)
965 {
966 channelFound = true;
967 break;
968 }
969 }
970 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800971 ChannelProperties& chData = channelData[chNum];
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800972 chData.chID = chNum;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800973 chData.chName = jsonChData[nameString].get<std::string>();
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500974 chData.isChValid = channelFound &&
975 jsonChData[isValidString].get<bool>();
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800976 chData.activeSessCount = jsonChData.value(activeSessionsString, 0);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400977 chData.maxTransferSize =
978 jsonChData.value(maxTransferSizeString, smallChannelSize);
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700979 if (jsonChData.count(isManagementNIC) != 0)
980 {
981 chData.isManagementNIC =
982 jsonChData[isManagementNIC].get<bool>();
983 }
984
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800985 std::string medTypeStr =
986 jsonChInfo[mediumTypeString].get<std::string>();
987 chData.chInfo.mediumType =
988 static_cast<uint8_t>(convertToMediumTypeIndex(medTypeStr));
989 std::string protoTypeStr =
990 jsonChInfo[protocolTypeString].get<std::string>();
991 chData.chInfo.protocolType =
992 static_cast<uint8_t>(convertToProtocolTypeIndex(protoTypeStr));
993 std::string sessStr =
994 jsonChInfo[sessionSupportedString].get<std::string>();
995 chData.chInfo.sessionSupported =
996 static_cast<uint8_t>(convertToSessionSupportIndex(sessStr));
997 chData.chInfo.isIpmi = jsonChInfo[isIpmiString].get<bool>();
998 chData.chInfo.authTypeSupported = defaultAuthType;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530999 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001000 catch (const Json::exception& e)
1001 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001002 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001003 freeifaddrs(ifaddr);
1004
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001005 return -EBADMSG;
1006 }
1007 catch (const std::invalid_argument& e)
1008 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001009 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001010 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001011 return -EBADMSG;
1012 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301013 }
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001014 freeifaddrs(ifaddr);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301015
1016 return 0;
1017}
1018
1019int ChannelConfig::readChannelVolatileData()
1020{
1021 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1022 channelLock{*channelMutex};
1023
1024 Json data = readJsonFile(channelVolatileDataFilename);
1025 if (data == nullptr)
1026 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001027 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301028 return -EIO;
1029 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301030 try
1031 {
1032 // Fill in global structure
1033 for (auto it = data.begin(); it != data.end(); ++it)
1034 {
1035 std::string chKey = it.key();
1036 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001037 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301038 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001039 lg2::debug("Invalid channel access entry in config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301040 throw std::out_of_range("Out of range - channel number");
1041 }
1042 Json jsonChData = it.value();
1043 if (!jsonChData.is_null())
1044 {
1045 std::string accModeStr =
1046 jsonChData[accessModeString].get<std::string>();
1047 channelData[chNum].chAccess.chVolatileData.accessMode =
1048 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1049 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
1050 jsonChData[userAuthDisabledString].get<bool>();
1051 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
1052 jsonChData[perMsgAuthDisabledString].get<bool>();
1053 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
1054 jsonChData[alertingDisabledString].get<bool>();
1055 std::string privStr =
1056 jsonChData[privLimitString].get<std::string>();
1057 channelData[chNum].chAccess.chVolatileData.privLimit =
1058 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1059 }
1060 else
1061 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001062 lg2::error(
1063 "Invalid/corrupted volatile channel access file '{FILE}'",
1064 "FILE", channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301065 throw std::runtime_error(
1066 "Corrupted volatile channel access file");
1067 }
1068 }
1069 }
1070 catch (const Json::exception& e)
1071 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001072 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301073 throw std::runtime_error("Corrupted volatile channel access file");
1074 }
1075 catch (const std::invalid_argument& e)
1076 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001077 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301078 throw std::runtime_error("Corrupted volatile channel access file");
1079 }
1080
1081 // Update the timestamp
1082 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1083 return 0;
1084}
1085
1086int ChannelConfig::readChannelPersistData()
1087{
1088 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1089 channelLock{*channelMutex};
1090
1091 Json data = readJsonFile(channelNvDataFilename);
1092 if (data == nullptr)
1093 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001094 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301095 return -EIO;
1096 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301097 try
1098 {
1099 // Fill in global structure
1100 for (auto it = data.begin(); it != data.end(); ++it)
1101 {
1102 std::string chKey = it.key();
1103 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001104 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301105 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001106 lg2::debug("Invalid channel access entry in config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301107 throw std::out_of_range("Out of range - channel number");
1108 }
1109 Json jsonChData = it.value();
1110 if (!jsonChData.is_null())
1111 {
1112 std::string accModeStr =
1113 jsonChData[accessModeString].get<std::string>();
1114 channelData[chNum].chAccess.chNonVolatileData.accessMode =
1115 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1116 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
1117 jsonChData[userAuthDisabledString].get<bool>();
1118 channelData[chNum]
1119 .chAccess.chNonVolatileData.perMsgAuthDisabled =
1120 jsonChData[perMsgAuthDisabledString].get<bool>();
1121 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
1122 jsonChData[alertingDisabledString].get<bool>();
1123 std::string privStr =
1124 jsonChData[privLimitString].get<std::string>();
1125 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1126 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1127 }
1128 else
1129 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001130 lg2::error("Invalid/corrupted nv channel access file {FILE}",
1131 "FILE", channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301132 throw std::runtime_error("Corrupted nv channel access file");
1133 }
1134 }
1135 }
1136 catch (const Json::exception& e)
1137 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001138 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301139 throw std::runtime_error("Corrupted nv channel access file");
1140 }
1141 catch (const std::invalid_argument& e)
1142 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001143 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301144 throw std::runtime_error("Corrupted nv channel access file");
1145 }
1146
1147 // Update the timestamp
1148 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1149 return 0;
1150}
1151
1152int ChannelConfig::writeChannelVolatileData()
1153{
1154 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1155 channelLock{*channelMutex};
1156 Json outData;
1157
1158 try
1159 {
1160 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1161 {
1162 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1163 {
1164 Json jsonObj;
1165 std::string chKey = std::to_string(chNum);
1166 std::string accModeStr = convertToAccessModeString(
1167 channelData[chNum].chAccess.chVolatileData.accessMode);
1168 jsonObj[accessModeString] = accModeStr;
1169 jsonObj[userAuthDisabledString] =
1170 channelData[chNum].chAccess.chVolatileData.userAuthDisabled;
1171 jsonObj[perMsgAuthDisabledString] =
1172 channelData[chNum]
1173 .chAccess.chVolatileData.perMsgAuthDisabled;
1174 jsonObj[alertingDisabledString] =
1175 channelData[chNum].chAccess.chVolatileData.alertingDisabled;
1176 std::string privStr = convertToPrivLimitString(
1177 channelData[chNum].chAccess.chVolatileData.privLimit);
1178 jsonObj[privLimitString] = privStr;
1179
1180 outData[chKey] = jsonObj;
1181 }
1182 }
1183 }
1184 catch (const std::invalid_argument& e)
1185 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001186 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301187 return -EINVAL;
1188 }
1189
1190 if (writeJsonFile(channelVolatileDataFilename, outData) != 0)
1191 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001192 lg2::debug("Error in write JSON data to file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301193 return -EIO;
1194 }
1195
1196 // Update the timestamp
1197 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1198 return 0;
1199}
1200
1201int ChannelConfig::writeChannelPersistData()
1202{
1203 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1204 channelLock{*channelMutex};
1205 Json outData;
1206
1207 try
1208 {
1209 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1210 {
1211 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1212 {
1213 Json jsonObj;
1214 std::string chKey = std::to_string(chNum);
1215 std::string accModeStr = convertToAccessModeString(
1216 channelData[chNum].chAccess.chNonVolatileData.accessMode);
1217 jsonObj[accessModeString] = accModeStr;
1218 jsonObj[userAuthDisabledString] =
1219 channelData[chNum]
1220 .chAccess.chNonVolatileData.userAuthDisabled;
1221 jsonObj[perMsgAuthDisabledString] =
1222 channelData[chNum]
1223 .chAccess.chNonVolatileData.perMsgAuthDisabled;
1224 jsonObj[alertingDisabledString] =
1225 channelData[chNum]
1226 .chAccess.chNonVolatileData.alertingDisabled;
1227 std::string privStr = convertToPrivLimitString(
1228 channelData[chNum].chAccess.chNonVolatileData.privLimit);
1229 jsonObj[privLimitString] = privStr;
1230
1231 outData[chKey] = jsonObj;
1232 }
1233 }
1234 }
1235 catch (const std::invalid_argument& e)
1236 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001237 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301238 return -EINVAL;
1239 }
1240
1241 if (writeJsonFile(channelNvDataFilename, outData) != 0)
1242 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001243 lg2::debug("Error in write JSON data to file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301244 return -EIO;
1245 }
1246
1247 // Update the timestamp
1248 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1249 return 0;
1250}
1251
1252int ChannelConfig::checkAndReloadNVData()
1253{
1254 std::time_t updateTime = getUpdatedFileTime(channelNvDataFilename);
1255 int ret = 0;
1256 if (updateTime != nvFileLastUpdatedTime || updateTime == -EIO)
1257 {
1258 try
1259 {
1260 ret = readChannelPersistData();
1261 }
1262 catch (const std::exception& e)
1263 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001264 lg2::error("Exception caught in readChannelPersistData: {MSG}",
1265 "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301266 ret = -EIO;
1267 }
1268 }
1269 return ret;
1270}
1271
1272int ChannelConfig::checkAndReloadVolatileData()
1273{
1274 std::time_t updateTime = getUpdatedFileTime(channelVolatileDataFilename);
1275 int ret = 0;
1276 if (updateTime != voltFileLastUpdatedTime || updateTime == -EIO)
1277 {
1278 try
1279 {
1280 ret = readChannelVolatileData();
1281 }
1282 catch (const std::exception& e)
1283 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001284 lg2::error("Exception caught in readChannelVolatileData: {MSG}",
1285 "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301286 ret = -EIO;
1287 }
1288 }
1289 return ret;
1290}
1291
Patrick Williams1318a5e2024-08-16 15:19:54 -04001292int ChannelConfig::setDbusProperty(
1293 const std::string& service, const std::string& objPath,
1294 const std::string& interface, const std::string& property,
1295 const DbusVariant& value)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301296{
1297 try
1298 {
Patrick Williams1318a5e2024-08-16 15:19:54 -04001299 auto method =
1300 bus.new_method_call(service.c_str(), objPath.c_str(),
1301 "org.freedesktop.DBus.Properties", "Set");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301302
1303 method.append(interface, property, value);
1304
1305 auto reply = bus.call(method);
1306 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001307 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301308 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001309 lg2::debug(
1310 "set-property {SERVICE}:{OBJPATH}/{INTERFACE}.{PROP} failed: {MSG}",
1311 "SERVICE", service, "OBJPATH", objPath, "INTERFACE", interface,
George Liu5a398942025-01-24 09:16:43 +08001312 "PROP", property, "MSG", e);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301313 return -EIO;
1314 }
1315
1316 return 0;
1317}
1318
AppaRao Puli9613ed72018-09-01 23:46:44 +05301319int ChannelConfig::syncNetworkChannelConfig()
1320{
1321 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1322 channelLock{*channelMutex};
1323 bool isUpdated = false;
1324 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1325 {
1326 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1327 {
1328 std::string intfPrivStr;
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001329 uint8_t intfPriv = 0;
AppaRao Puli9613ed72018-09-01 23:46:44 +05301330 try
1331 {
AppaRao Puli9613ed72018-09-01 23:46:44 +05301332 std::string networkIntfObj =
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +05301333 std::string(networkIntfObjectBasePath) + "/" +
1334 channelData[chNum].chName;
George Liu42f64ef2024-02-05 15:03:18 +08001335 auto propValue = ipmi::getDbusProperty(
1336 bus, networkIntfServiceName, networkIntfObj,
1337 networkChConfigIntfName, privilegePropertyString);
1338
1339 intfPrivStr = std::get<std::string>(propValue);
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001340 intfPriv =
1341 static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301342 }
Vernon Maueryf442e112019-04-09 11:44:36 -07001343 catch (const std::bad_variant_access& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301344 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001345 lg2::debug("Network interface '{INTERFACE}' does not exist",
1346 "INTERFACE", channelData[chNum].chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301347 continue;
1348 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001349 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301350 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001351 lg2::debug("Network interface '{INTERFACE}' does not exist",
1352 "INTERFACE", channelData[chNum].chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301353 continue;
1354 }
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001355 catch (const std::invalid_argument& e)
1356 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001357 lg2::debug("exception: Invalid privilege");
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001358 continue;
1359 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301360
AppaRao Puli9613ed72018-09-01 23:46:44 +05301361 if (channelData[chNum].chAccess.chNonVolatileData.privLimit !=
1362 intfPriv)
1363 {
1364 isUpdated = true;
1365 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1366 intfPriv;
1367 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
1368 }
1369 }
1370 }
1371
1372 if (isUpdated)
1373 {
1374 // Write persistent data to file
1375 if (writeChannelPersistData() != 0)
1376 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001377 lg2::debug("Failed to update the persistent data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301378 return -EIO;
1379 }
1380 // Write Volatile data to file
1381 if (writeChannelVolatileData() != 0)
1382 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001383 lg2::debug("Failed to update the channel volatile data");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301384 return -EIO;
1385 }
1386 }
1387
1388 return 0;
1389}
1390
AppaRao Puli071f3f22018-05-24 16:45:30 +05301391void ChannelConfig::initChannelPersistData()
1392{
Richard Marian Thomaiyare91474c2019-09-01 23:02:47 +05301393 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1394 channelLock{*channelMutex};
1395
AppaRao Puli071f3f22018-05-24 16:45:30 +05301396 /* Always read the channel config */
1397 if (loadChannelConfig() != 0)
1398 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001399 lg2::error("Failed to read channel config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301400 throw std::ios_base::failure("Failed to load channel configuration");
1401 }
1402
1403 /* Populate the channel persist data */
1404 if (readChannelPersistData() != 0)
1405 {
1406 // Copy default NV data to RW location
Patrick Williams3d8d7932022-06-16 12:01:28 -05001407 std::filesystem::copy_file(channelAccessDefaultFilename,
1408 channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301409
1410 // Load the channel access NV data
1411 if (readChannelPersistData() != 0)
1412 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001413 lg2::error("Failed to read channel access NV data");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301414 throw std::ios_base::failure(
1415 "Failed to read channel access NV configuration");
1416 }
1417 }
1418
1419 // First check the volatile data file
1420 // If not present, load the default values
1421 if (readChannelVolatileData() != 0)
1422 {
1423 // Copy default volatile data to temporary location
1424 // NV file(channelNvDataFilename) must have created by now.
Patrick Williams3d8d7932022-06-16 12:01:28 -05001425 std::filesystem::copy_file(channelNvDataFilename,
1426 channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301427
1428 // Load the channel access volatile data
1429 if (readChannelVolatileData() != 0)
1430 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001431 lg2::error("Failed to read channel access volatile data");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301432 throw std::ios_base::failure(
1433 "Failed to read channel access volatile configuration");
1434 }
1435 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301436
1437 // Synchronize the channel config(priv) with network channel
1438 // configuration(priv) over dbus
1439 if (syncNetworkChannelConfig() != 0)
1440 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001441 lg2::error(
AppaRao Puli9613ed72018-09-01 23:46:44 +05301442 "Failed to synchronize data with network channel config over dbus");
1443 throw std::ios_base::failure(
1444 "Failed to synchronize data with network channel config over dbus");
1445 }
1446
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001447 lg2::debug("Successfully completed channel data initialization.");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301448 return;
1449}
1450
1451} // namespace ipmi