diff --git a/include/oemcommands.hpp b/include/oemcommands.hpp
index b30d5c9..d2fb116 100644
--- a/include/oemcommands.hpp
+++ b/include/oemcommands.hpp
@@ -425,6 +425,7 @@
 {
     GetSmSignal = 0x14,
     SetSmSignal = 0x15,
-    BmcControlServices = 0xC0,
+    controlBmcServices = 0xB1,
+    getBmcServiceStatus = 0xB2,
     SetSensorOverride = 0xEE,
 };
diff --git a/src/bmccontrolservices.cpp b/src/bmccontrolservices.cpp
index 2bebab5..b446886 100644
--- a/src/bmccontrolservices.cpp
+++ b/src/bmccontrolservices.cpp
@@ -16,47 +16,51 @@
 
 #include "oemcommands.hpp"
 
-#include <openssl/hmac.h>
-
+#include <boost/algorithm/string.hpp>
 #include <ipmid/api.hpp>
 #include <ipmid/utils.hpp>
 #include <phosphor-logging/log.hpp>
-#include <sdbusplus/bus.hpp>
+#include <variant>
 
+namespace ipmi
+{
 void register_netfn_bmc_control_functions() __attribute__((constructor));
 
-enum ipmi_bmc_control_services_return_codes
-{
-    ipmiCCBmcControlInvalidBitMask = 0xCC,
-    ipmiCCBmcControlPasswdInvalid = 0xCD,
-    ipmiCCBmcControlInvalidChannel = 0xD4,
+static constexpr uint8_t rmcpServiceBitPos = 3;
+static constexpr uint8_t webServiceBitPos = 5;
+static constexpr uint8_t solServiceBitPos = 6;
+static constexpr uint8_t kvmServiceBitPos = 15;
+
+static const std::unordered_map<uint8_t, std::string> bmcServices = {
+    // {bit position for service, service object path}
+    {rmcpServiceBitPos,
+     "/xyz/openbmc_project/control/service/phosphor_2dipmi_2dnet"},
+    {webServiceBitPos, "/xyz/openbmc_project/control/service/bmcweb"},
+    {solServiceBitPos, "/xyz/openbmc_project/control/service/obmc_2dconsole"},
+    {kvmServiceBitPos, "/xyz/openbmc_project/control/service/start_2dipkvm"},
 };
 
-// TODO: Add other services, once they are supported
-static const std::unordered_map<uint8_t, std::string> bmcServices = {
-    {3, "netipmid"},
-    {5, "web"},
-    {6, "ssh"},
-};
+static constexpr uint16_t maskBit15 = 0xF000;
 
 static constexpr const char* objectManagerIntf =
     "org.freedesktop.DBus.ObjectManager";
+static constexpr const char* dBusPropIntf = "org.freedesktop.DBus.Properties";
 static constexpr const char* serviceConfigBasePath =
     "/xyz/openbmc_project/control/service";
 static constexpr const char* serviceConfigAttrIntf =
     "xyz.openbmc_project.Control.Service.Attributes";
-static constexpr const char* serviceStateProperty = "State";
-static std::string disableServiceValue = "disabled";
+static constexpr const char* getMgdObjMethod = "GetManagedObjects";
+static constexpr const char* propMasked = "Masked";
 
-static ipmi_ret_t disableBmcServices(const std::string& objName)
+std::string getServiceConfigMgrName()
 {
-    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
     static std::string serviceCfgMgr{};
     if (serviceCfgMgr.empty())
     {
         try
         {
-            serviceCfgMgr = ipmi::getService(*dbus, objectManagerIntf,
+            auto sdbusp = getSdBus();
+            serviceCfgMgr = ipmi::getService(*sdbusp, objectManagerIntf,
                                              serviceConfigBasePath);
         }
         catch (const sdbusplus::exception::SdBusError& e)
@@ -64,90 +68,147 @@
             serviceCfgMgr.clear();
             phosphor::logging::log<phosphor::logging::level::ERR>(
                 "Error: In fetching disabling service manager name");
-            return IPMI_CC_UNSPECIFIED_ERROR;
+            return serviceCfgMgr;
         }
     }
-    auto path = std::string(serviceConfigBasePath) + "/" + objName;
-    try
+    return serviceCfgMgr;
+}
+
+static inline void checkAndThrowError(boost::system::error_code& ec,
+                                      const std::string& msg)
+{
+    if (ec)
     {
-        ipmi::setDbusProperty(*dbus, serviceCfgMgr, path, serviceConfigAttrIntf,
-                              serviceStateProperty,
-                              ipmi::Value(disableServiceValue));
-        phosphor::logging::log<phosphor::logging::level::INFO>(
-            "Disabling service",
-            phosphor::logging::entry("PATH=%s", path.c_str()),
-            phosphor::logging::entry("MGR_NAME=%s", serviceCfgMgr.c_str()));
-        return IPMI_CC_OK;
+        std::string msgToLog = ec.message() + (msg.empty() ? "" : " - " + msg);
+        phosphor::logging::log<phosphor::logging::level::ERR>(msgToLog.c_str());
+        throw sdbusplus::exception::SdBusError(-EIO, msgToLog.c_str());
     }
-    catch (const sdbusplus::exception_t&)
+    return;
+}
+
+static inline bool getEnabledValue(const DbusInterfaceMap& intfMap)
+{
+    for (const auto& intf : intfMap)
     {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "Error: Disabling service",
-            phosphor::logging::entry("PATH=%s", path.c_str()),
-            phosphor::logging::entry("MGR_NAME=%s", serviceCfgMgr.c_str()));
-        return IPMI_CC_UNSPECIFIED_ERROR;
+        if (intf.first == serviceConfigAttrIntf)
+        {
+            auto it = intf.second.find(propMasked);
+            if (it == intf.second.end())
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Error: in getting Masked property value");
+                throw sdbusplus::exception::SdBusError(
+                    -EIO, "ERROR in reading Masked property value");
+            }
+            // return !Masked value
+            return !std::get<bool>(it->second);
+        }
     }
 }
 
-static constexpr size_t controlPasswdSize = 32;
-
-ipmi::RspType<> bmcIntelControlServices(
-    ipmi::Context::ptr ctx,
-    const std::array<uint8_t, controlPasswdSize>& passwd, uint8_t stdServices,
-    uint8_t oemServices)
+ipmi::RspType<> setBmcControlServices(boost::asio::yield_context yield,
+                                      uint8_t state, uint16_t serviceValue)
 {
-    // Execute this command only in KCS interface
-    if (ctx->channel != interfaceKCS)
+    constexpr uint16_t servicesRsvdMask = 0x3F97;
+    constexpr uint8_t enableService = 0x1;
+
+    if ((state > enableService) || (serviceValue & servicesRsvdMask) ||
+        !serviceValue)
     {
-        return ipmi::response(ipmiCCBmcControlInvalidChannel);
+        return ipmi::responseInvalidFieldRequest();
     }
-
-    static std::string hashData("Intel 0penBMC");
-    static std::vector<uint8_t> hashedValue = {
-        0x89, 0x6A, 0xAB, 0x7D, 0xB0, 0x5A, 0x2D, 0x92, 0x41, 0xAD, 0x92,
-        0xEE, 0xD4, 0x82, 0xDE, 0x62, 0x66, 0x16, 0xC1, 0x08, 0xFD, 0x23,
-        0xC6, 0xD8, 0x75, 0xB3, 0x52, 0x53, 0x31, 0x3C, 0x7F, 0x69};
-    std::vector<uint8_t> hashedOutput(EVP_MAX_MD_SIZE, 0);
-    unsigned int outputLen = 0;
-    HMAC(EVP_sha256(), passwd.data(), passwd.size(),
-         reinterpret_cast<const uint8_t*>(hashData.c_str()), hashData.length(),
-         &hashedOutput[0], &outputLen);
-    hashedOutput.resize(outputLen);
-
-    if (hashedOutput != hashedValue)
+    try
     {
-        return ipmi::response(ipmiCCBmcControlPasswdInvalid);
-    }
+        auto sdbusp = getSdBus();
+        boost::system::error_code ec;
+        auto objectMap = sdbusp->yield_method_call<ObjectValueTree>(
+            yield, ec, getServiceConfigMgrName().c_str(), serviceConfigBasePath,
+            objectManagerIntf, getMgdObjMethod);
+        checkAndThrowError(ec, "GetMangagedObjects for service cfg failed");
 
-    if (stdServices == 0 && oemServices == 0)
-    {
-        return ipmi::response(ipmiCCBmcControlInvalidBitMask);
-    }
-
-    ipmi_ret_t retVal = IPMI_CC_OK;
-    for (size_t bitIndex = 0; bitIndex < 8; ++bitIndex)
-    {
-        if (stdServices & (1 << bitIndex))
+        for (const auto& services : bmcServices)
         {
-            auto it = bmcServices.find(bitIndex);
-            if (it == bmcServices.end())
+            // services.first holds the bit position of the service, check
+            // whether it has to be updated.
+            const uint16_t serviceMask = 1 << services.first;
+            if (!(serviceValue & serviceMask))
             {
-                return ipmi::response(ipmiCCBmcControlInvalidBitMask);
+                continue;
             }
-            retVal = disableBmcServices(it->second);
-            if (retVal != IPMI_CC_OK)
+            for (const auto& obj : objectMap)
             {
-                return ipmi::response(retVal);
+                if (boost::algorithm::starts_with(obj.first.str,
+                                                  services.second))
+                {
+                    if (state != getEnabledValue(obj.second))
+                    {
+                        ec.clear();
+                        sdbusp->yield_method_call<>(
+                            yield, ec, getServiceConfigMgrName().c_str(),
+                            obj.first.str, dBusPropIntf, "Set",
+                            serviceConfigAttrIntf, propMasked,
+                            std::variant<bool>(!state));
+                        checkAndThrowError(ec, "Set Masked property failed");
+                        // Multiple instances may be present, so continue
+                    }
+                }
             }
         }
     }
+    catch (sdbusplus::exception::SdBusError& e)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
     return ipmi::responseSuccess();
 }
 
+ipmi::RspType<uint16_t> getBmcControlServices(boost::asio::yield_context yield)
+{
+    uint16_t serviceValue = 0;
+    try
+    {
+        auto sdbusp = getSdBus();
+        boost::system::error_code ec;
+        auto objectMap = sdbusp->yield_method_call<ObjectValueTree>(
+            yield, ec, getServiceConfigMgrName().c_str(), serviceConfigBasePath,
+            objectManagerIntf, getMgdObjMethod);
+        checkAndThrowError(ec, "GetMangagedObjects for service cfg failed");
+
+        for (const auto& services : bmcServices)
+        {
+            for (const auto& obj : objectMap)
+            {
+                if (boost::algorithm::starts_with(obj.first.str,
+                                                  services.second))
+                {
+                    serviceValue |= getEnabledValue(obj.second)
+                                    << services.first;
+                    break;
+                }
+            }
+        }
+    }
+    catch (sdbusplus::exception::SdBusError& e)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    // Bit 14 should match bit 15 as single service maintains Video & USB
+    // redirection
+    serviceValue |= (serviceValue & maskBit15) >> 1;
+    return ipmi::responseSuccess(serviceValue);
+}
+
 void register_netfn_bmc_control_functions()
 {
     ipmi::registerHandler(ipmi::prioOpenBmcBase, netfnIntcOEMGeneral,
                           static_cast<ipmi_cmd_t>(
-                              IPMINetFnIntelOemGeneralCmds::BmcControlServices),
-                          ipmi::Privilege::User, bmcIntelControlServices);
+                              IPMINetFnIntelOemGeneralCmds::controlBmcServices),
+                          ipmi::Privilege::Admin, setBmcControlServices);
+
+    ipmi::registerHandler(
+        ipmi::prioOpenBmcBase, netfnIntcOEMGeneral,
+        static_cast<ipmi_cmd_t>(
+            IPMINetFnIntelOemGeneralCmds::getBmcServiceStatus),
+        ipmi::Privilege::User, getBmcControlServices);
 }
+} // namespace ipmi
