diff --git a/apphandler.cpp b/apphandler.cpp
index 2430e8e..fdc2d67 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -1043,91 +1043,100 @@
     return ipmi::ccSuccess;
 }
 
-uint8_t getSessionState(std::shared_ptr<sdbusplus::asio::connection>& busp,
-                        const std::string& service, const std::string& objPath,
-                        uint8_t& sessionState)
+uint8_t getSessionState(ipmi::Context::ptr ctx, const std::string& service,
+                        const std::string& objPath, uint8_t& sessionState)
 {
-    try
-    {
-        sessionState = std::get<uint8_t>(ipmi::getDbusProperty(
-            *busp, service, objPath, session::sessionIntf, "State"));
-    }
-    catch (sdbusplus::exception::SdBusError& e)
+    boost::system::error_code ec = ipmi::getDbusProperty(
+        ctx, service, objPath, session::sessionIntf, "State", sessionState);
+    if (ec)
     {
         log<level::ERR>("Failed to fetch state property ",
                         entry("SERVICE=%s", service.c_str()),
                         entry("OBJECTPATH=%s", objPath.c_str()),
                         entry("INTERFACE=%s", session::sessionIntf),
-                        entry("ERRMSG=%s", e.what()));
+                        entry("ERRMSG=%s", ec.message().c_str()));
         return ipmi::ccUnspecifiedError;
     }
-
     return ipmi::ccSuccess;
 }
 
 static constexpr uint8_t macAddrLen = 6;
-struct GetSessionInfoRes
-{
-    uint8_t sessionHandle;
-    uint8_t totalSessionCount;
-    uint8_t activeSessionCount;
-    uint8_t userID;
-    uint8_t privLevel;
-    uint8_t channelNumber;
-    uint32_t remoteIpAddr;
-    std::array<uint8_t, macAddrLen> macAddr = {0};
-    uint16_t remotePort;
-};
+/** Alias SessionDetails - contain the optional information about an
+ *        RMCP+ session.
+ *
+ *  @param userID - uint6_t session user ID (0-63)
+ *  @param reserved - uint2_t reserved
+ *  @param privilege - uint4_t session privilege (0-5)
+ *  @param reserved - uint4_t reserved
+ *  @param channel - uint4_t session channel number
+ *  @param protocol - uint4_t session protocol
+ *  @param remoteIP - uint32_t remote IP address
+ *  @param macAddr - std::array<uint8_t, 6> mac address
+ *  @param port - uint16_t remote port
+ */
+using SessionDetails =
+    std::tuple<uint2_t, uint6_t, uint4_t, uint4_t, uint4_t, uint4_t, uint32_t,
+               std::array<uint8_t, macAddrLen>, uint16_t>;
 
-uint8_t
-    fillGetSessionInfoRes(std::shared_ptr<sdbusplus::asio::connection>& busp,
-                          const std::string& service,
-                          const std::string& objPath,
-                          struct GetSessionInfoRes& resp, uint8_t& sessionState)
+/** @brief get session details for a given session
+ *
+ *  @param[in] ctx - ipmi::Context pointer for accessing D-Bus
+ *  @param[in] service - D-Bus service name to fetch details from
+ *  @param[in] objPath - D-Bus object path for session
+ *  @param[out] sessionHandle - return session handle for session
+ *  @param[out] sessionState - return session state for session
+ *  @param[out] details - return a SessionDetails tuple containing other
+ *                        session info
+ *  @return - ipmi::Cc success or error code
+ */
+ipmi::Cc getSessionDetails(ipmi::Context::ptr ctx, const std::string& service,
+                           const std::string& objPath, uint8_t& sessionHandle,
+                           uint8_t& sessionState, SessionDetails& details)
 {
-    try
-    {
-        ipmi::PropertyMap sessionProps = ipmi::getAllDbusProperties(
-            *busp, service, objPath, session::sessionIntf);
+    ipmi::PropertyMap sessionProps;
+    boost::system::error_code ec = ipmi::getAllDbusProperties(
+        ctx, service, objPath, session::sessionIntf, sessionProps);
 
-        sessionState = std::get<uint8_t>(sessionProps.at("State"));
-        if (sessionState == static_cast<uint8_t>(session::State::active))
-        {
-            resp.sessionHandle =
-                std::get<uint8_t>(sessionProps["SessionHandle"]);
-            resp.userID = std::get<uint8_t>(sessionProps["UserID"]);
-            resp.privLevel =
-                std::get<uint8_t>(sessionProps["CurrentPrivilege"]);
-            resp.channelNumber = std::get<uint8_t>(sessionProps["ChannelNum"]);
-            resp.remoteIpAddr =
-                std::get<uint32_t>(sessionProps["RemoteIPAddr"]);
-            resp.remotePort = std::get<uint16_t>(sessionProps["RemotePort"]);
-        }
-    }
-    catch (sdbusplus::exception::SdBusError& e)
+    if (ec)
     {
         log<level::ERR>("Failed to fetch state property ",
                         entry("SERVICE=%s", service.c_str()),
                         entry("OBJECTPATH=%s", objPath.c_str()),
                         entry("INTERFACE=%s", session::sessionIntf),
-                        entry("ERRMSG=%s", e.what()));
+                        entry("ERRMSG=%s", ec.message().c_str()));
         return ipmi::ccUnspecifiedError;
     }
 
+    sessionState = ipmi::mappedVariant<uint8_t>(
+        sessionProps, "State", static_cast<uint8_t>(session::State::inactive));
+    if (sessionState == static_cast<uint8_t>(session::State::active))
+    {
+        sessionHandle =
+            ipmi::mappedVariant<uint8_t>(sessionProps, "SessionHandle", 0);
+        std::get<0>(details) =
+            ipmi::mappedVariant<uint8_t>(sessionProps, "UserID", 0xff);
+        // std::get<1>(details) = 0; // (default constructed to 0)
+        std::get<2>(details) =
+            ipmi::mappedVariant<uint8_t>(sessionProps, "CurrentPrivilege", 0);
+        // std::get<3>(details) = 0; // (default constructed to 0)
+        std::get<4>(details) =
+            ipmi::mappedVariant<uint8_t>(sessionProps, "ChannelNum", 0xff);
+        constexpr uint4_t rmcpPlusProtocol = 1;
+        std::get<5>(details) = rmcpPlusProtocol;
+        std::get<6>(details) =
+            ipmi::mappedVariant<uint32_t>(sessionProps, "RemoteIPAddr", 0);
+        // std::get<7>(details) = {{0}}; // default constructed to all 0
+        std::get<8>(details) =
+            ipmi::mappedVariant<uint16_t>(sessionProps, "RemotePort", 0);
+    }
+
     return ipmi::ccSuccess;
 }
 
-ipmi::RspType<
-    uint8_t,                           // session handle,
-    uint8_t,                           // total session count
-    uint8_t,                           // active session count
-    std::optional<std::tuple<uint8_t,  // user ID
-                             uint8_t,  // privilege level
-                             uint8_t,  // channel number
-                             uint32_t, // remote ip address,
-                             std::array<uint8_t, macAddrLen>, // mac address
-                             uint16_t                         // remote port
-                             >>>
+ipmi::RspType<uint8_t, // session handle,
+              uint8_t, // total session count
+              uint8_t, // active session count
+              std::optional<SessionDetails>>
     ipmiAppGetSessionInfo(ipmi::Context::ptr ctx, uint8_t sessionIndex,
                           ipmi::message::Payload& payload)
 {
@@ -1143,87 +1152,77 @@
     {
         return ipmi::response(completionCode);
     }
-    struct GetSessionInfoRes res = {0};
-    res.totalSessionCount = getTotalSessionCount();
-    res.activeSessionCount = 0;
-    auto busp = getSdBus();
-
-    try
-    {
-        uint8_t index = 0;
-        ipmi::ObjectTree objectTree = ipmi::getAllDbusObjects(
-            *busp, session::sessionManagerRootPath, session::sessionIntf);
-
-        for (auto& objectTreeItr : objectTree)
-        {
-            uint32_t sessionId = 0;
-            uint8_t sessionHandle = session::defaultSessionHandle;
-            std::string objectPath = objectTreeItr.first;
-
-            if (!parseCloseSessionInputPayload(objectPath, sessionId,
-                                               sessionHandle))
-            {
-                continue;
-            }
-            index++;
-            auto& serviceMap = objectTreeItr.second;
-            auto itr = serviceMap.begin();
-
-            if (serviceMap.size() != 1)
-            {
-                return ipmi::responseUnspecifiedError();
-            }
-
-            std::string service = itr->first;
-            uint8_t sessionState = 0;
-            completionCode =
-                getSessionState(busp, service, objectPath, sessionState);
-            if (completionCode)
-            {
-                return ipmi::response(completionCode);
-            }
-
-            if (sessionState == static_cast<uint8_t>(session::State::active))
-            {
-                res.activeSessionCount++;
-            }
-
-            if (index != sessionIndex && reqSessionId != sessionId &&
-                reqSessionHandle != sessionHandle)
-            {
-                continue;
-            }
-
-            completionCode =
-                fillGetSessionInfoRes(busp, service, objectPath, res, state);
-
-            if (completionCode)
-            {
-                return ipmi::response(completionCode);
-            }
-        }
-    }
-
-    catch (sdbusplus::exception::SdBusError& e)
+    ipmi::ObjectTree objectTree;
+    boost::system::error_code ec = ipmi::getAllDbusObjects(
+        ctx, session::sessionManagerRootPath, session::sessionIntf, objectTree);
+    if (ec)
     {
         log<level::ERR>("Failed to fetch object from dbus",
                         entry("INTERFACE=%s", session::sessionIntf),
-                        entry("ERRMSG=%s", e.what()));
+                        entry("ERRMSG=%s", ec.message().c_str()));
         return ipmi::responseUnspecifiedError();
     }
 
-    if (state == static_cast<uint8_t>(session::State::active))
+    uint8_t totalSessionCount = getTotalSessionCount();
+    uint8_t activeSessionCount = 0;
+    uint8_t sessionHandle = session::defaultSessionHandle;
+    std::optional<SessionDetails> maybeDetails;
+    uint8_t index = 0;
+    for (auto& objectTreeItr : objectTree)
     {
-        return ipmi::responseSuccess(
-            res.sessionHandle, res.totalSessionCount, res.activeSessionCount,
-            std::make_tuple(res.userID, res.privLevel, res.channelNumber,
-                            res.remoteIpAddr, res.macAddr, res.remotePort));
+        uint32_t sessionId = 0;
+        std::string objectPath = objectTreeItr.first;
+
+        if (!parseCloseSessionInputPayload(objectPath, sessionId,
+                                           sessionHandle))
+        {
+            continue;
+        }
+        index++;
+        auto& serviceMap = objectTreeItr.second;
+        auto itr = serviceMap.begin();
+
+        if (serviceMap.size() != 1)
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+
+        std::string service = itr->first;
+        uint8_t sessionState = 0;
+        completionCode =
+            getSessionState(ctx, service, objectPath, sessionState);
+        if (completionCode)
+        {
+            return ipmi::response(completionCode);
+        }
+
+        if (sessionState == static_cast<uint8_t>(session::State::active))
+        {
+            activeSessionCount++;
+        }
+
+        if (index != sessionIndex && reqSessionId != sessionId &&
+            reqSessionHandle != sessionHandle)
+        {
+            continue;
+        }
+
+        SessionDetails details{};
+        completionCode = getSessionDetails(ctx, service, objectPath,
+                                           sessionHandle, state, details);
+
+        if (completionCode)
+        {
+            return ipmi::response(completionCode);
+        }
+        maybeDetails = std::move(details);
     }
-    else if (state == static_cast<uint8_t>(session::State::tearDownInProgress))
+
+    if (state == static_cast<uint8_t>(session::State::active) ||
+        state == static_cast<uint8_t>(session::State::tearDownInProgress))
     {
-        res.sessionHandle = 0;
-        return ipmi::responseSuccess(res.sessionHandle, res.totalSessionCount,
-                                     res.activeSessionCount, std::nullopt);
+        return ipmi::responseSuccess(sessionHandle, totalSessionCount,
+                                     activeSessionCount, maybeDetails);
     }
 
     return ipmi::responseInvalidFieldRequest();
