diff options
Diffstat (limited to 'apphandler.cpp')
-rw-r--r-- | apphandler.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/apphandler.cpp b/apphandler.cpp index c5a608d..0c8eb92 100644 --- a/apphandler.cpp +++ b/apphandler.cpp @@ -20,6 +20,8 @@ #include <filesystem> #include <fstream> #include <ipmid/api.hpp> +#include <ipmid/sessiondef.hpp> +#include <ipmid/sessionhelper.hpp> #include <ipmid/types.hpp> #include <ipmid/utils.hpp> #include <memory> @@ -842,6 +844,112 @@ auto ipmiAppGetSystemGuid() -> ipmi::RspType<std::array<uint8_t, 16>> return ipmi::responseSuccess(uuid); } +/** + * @brief set the session state as teardown + * + * This function is to set the session state to tear down in progress if the + * state is active. + * + * @param[in] busp - Dbus obj + * @param[in] service - service name + * @param[in] obj - object path + * + * @return success completion code if it sets the session state to + * tearDownInProgress else return the corresponding error completion code. + **/ +uint8_t setSessionState(std::shared_ptr<sdbusplus::asio::connection>& busp, + const std::string& service, const std::string& obj) +{ + try + { + uint8_t sessionState = std::get<uint8_t>(ipmi::getDbusProperty( + *busp, service, obj, session::sessionIntf, "State")); + + if (sessionState == static_cast<uint8_t>(session::State::active)) + { + ipmi::setDbusProperty( + *busp, service, obj, session::sessionIntf, "State", + static_cast<uint8_t>(session::State::tearDownInProgress)); + return ipmi::ccSuccess; + } + } + catch (std::exception& e) + { + log<level::ERR>("Failed in getting session state property", + entry("service=%s", service.c_str()), + entry("object path=%s", obj.c_str()), + entry("interface=%s", session::sessionIntf)); + return ipmi::ccUnspecifiedError; + } + + return ipmi::ccInvalidFieldRequest; +} + +ipmi::RspType<> ipmiAppCloseSession(uint32_t reqSessionId, + std::optional<uint8_t> requestSessionHandle) +{ + auto busp = getSdBus(); + uint8_t reqSessionHandle = + requestSessionHandle.value_or(session::defaultSessionHandle); + + if (reqSessionId == session::sessionZero && + reqSessionHandle == session::defaultSessionHandle) + { + return ipmi::response(session::ccInvalidSessionId); + } + + if (reqSessionId == session::sessionZero && + reqSessionHandle == session::invalidSessionHandle) + { + return ipmi::response(session::ccInvalidSessionHandle); + } + + if (reqSessionId != session::sessionZero && + reqSessionHandle != session::defaultSessionHandle) + { + return ipmi::response(ipmi::ccInvalidFieldRequest); + } + + try + { + ipmi::ObjectTree objectTree = ipmi::getAllDbusObjects( + *busp, session::sessionManagerRootPath, session::sessionIntf); + + for (auto& objectTreeItr : objectTree) + { + const std::string obj = objectTreeItr.first; + + if (isSessionObjectMatched(obj, reqSessionId, reqSessionHandle)) + { + auto& serviceMap = objectTreeItr.second; + + // Session id and session handle are unique for each session. + // Session id and handler are retrived from the object path and + // object path will be unique for each session. Checking if + // multiple objects exist with same object path under multiple + // services. + if (serviceMap.size() != 1) + { + return ipmi::responseUnspecifiedError(); + } + + auto itr = serviceMap.begin(); + const std::string service = itr->first; + return ipmi::response(setSessionState(busp, service, obj)); + } + } + } + catch (sdbusplus::exception::SdBusError& e) + { + log<level::ERR>("Failed to fetch object from dbus", + entry("INTERFACE=%s", session::sessionIntf), + entry("ERRMSG=%s", e.what())); + return ipmi::responseUnspecifiedError(); + } + + return ipmi::responseInvalidFieldRequest(); +} + static std::unique_ptr<SysInfoParamStore> sysInfoParamStore; static std::string sysInfoReadSystemName() @@ -1175,6 +1283,10 @@ void register_netfn_app_functions() ipmi::app::cmdSetWatchdogTimer, ipmi::Privilege::Operator, ipmiSetWatchdogTimer); + ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, + ipmi::app::cmdCloseSession, ipmi::Privilege::Callback, + ipmiAppCloseSession); + // <Get Watchdog Timer> ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp, ipmi::app::cmdGetWatchdogTimer, |