Fix for Callback privilege

Issue: Not returning proper error when user privilege is Callback

Returning proper error codes.

Tested:
Command:  ipmitool raw 0x06 0x40 0x3 0x42 0x41   //SetChannelAccess
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x40 rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x40 0x3 0x42 0xc2 //SetChannelAccess
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x40 rsp=0x83): Unknown (0x83)
Command:  ipmitool user priv 2 0x01 1
Response: IPMI command failed: Invalid data field in request
          Set Privilege Level command failed (user 2)
Command:  ipmitool raw 0x06 0x38 1 1  //Get Channel Auth Capabilities
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x38 rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x40 0x1 0x42 0x81  //SetChannelAccess
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x40 rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x43 0x1 2 1 0  //Set User Access Command
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x43 rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x43 0x2 1 2 0 //Set User Access Command
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x43 rsp=0xff): Unspecified error
Command:  ipmitool raw 0x06 0x42 0x02  //Get Channel Info Command
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x42 rsp=0x82): Unknown (0x82)
Command:  ipmitool raw 0x06 0x4E 0x02  //Get Channel Payload Support
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x4e rsp=0xff): Unspecified error
Command:  ipmitool raw 0x06 0x4E 0x0F  //Get Channel Payload Support
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x4e rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x4F 0x02 0x00 //Get Channel Payload Version
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x4f rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x4C 0x02 0x01 0x02 0x00 0x00 0x00
                                    //Set User Payload Access
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x4c rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x44 0x02 0x02  //Get User Access Command
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x44 rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x44 0x01 0x11  //Get User Access Command
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x44 rsp=0xc9): Parameter out of range
Command:  ipmitool raw 0x06 0x4D 0x02 0x02  //Get User Payload Access
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x4d rsp=0xcc): Invalid data field in request
Command:  ipmitool raw 0x06 0x40 0x3 0x44 0x43
                      // set channel access for Non-volatile priv limit
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x40 rsp=0x83): Unknown (0x83)
Command:  ipmitool raw 0x06 0x40 0x1 0x85 0x82
                      // set channel access for volatile priv limit
Response: Unable to send RAW command (channel=0x0 netfn=0x6 lun=0x0
          cmd=0x40 rsp=0x83): Unknown (0x83)

Signed-off-by: jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
Change-Id: I4ff6fb5ae9a604e6b38fb92c249416605ec27cb5
diff --git a/user_channel/channel_layer.cpp b/user_channel/channel_layer.cpp
index faca91e..38fd43f 100644
--- a/user_channel/channel_layer.cpp
+++ b/user_channel/channel_layer.cpp
@@ -44,7 +44,8 @@
 
 bool isValidPrivLimit(const uint8_t privLimit)
 {
-    return ((privLimit >= PRIVILEGE_CALLBACK) && (privLimit <= PRIVILEGE_OEM));
+    // Callback privilege is deprecated in OpenBMC
+    return ((privLimit > PRIVILEGE_CALLBACK) && (privLimit <= PRIVILEGE_OEM));
 }
 
 bool isValidAccessMode(const uint8_t accessMode)
diff --git a/user_channel/channel_layer.hpp b/user_channel/channel_layer.hpp
index 0fefe2e..bddd6b5 100644
--- a/user_channel/channel_layer.hpp
+++ b/user_channel/channel_layer.hpp
@@ -24,6 +24,8 @@
 static constexpr uint8_t maxIpmiChannels = 16;
 static constexpr uint8_t currentChNum = 0xE;
 static constexpr uint8_t invalidChannel = 0xff;
+static constexpr const uint8_t ccActionNotSupportedForChannel = 0x82;
+static constexpr const uint8_t ccAccessModeNotSupportedForChannel = 0x83;
 
 /**
  * @array of privilege levels
@@ -31,13 +33,6 @@
 extern const std::array<std::string, PRIVILEGE_OEM + 1> privList;
 
 /**
- * @enum IPMI return codes specific to channel (refer spec se 22.22 response
- * data)
- */
-constexpr Cc ccActionNotSupportedForChannel = 0x82;
-constexpr Cc ccAccessModeNotSupportedForChannel = 0x83;
-
-/**
  * @enum Channel Protocol Type (refer spec sec 6.4)
  */
 enum class EChannelProtocolType : uint8_t
diff --git a/user_channel/channel_mgmt.cpp b/user_channel/channel_mgmt.cpp
index 70e2c7d..b8e0b85 100644
--- a/user_channel/channel_mgmt.cpp
+++ b/user_channel/channel_mgmt.cpp
@@ -462,12 +462,15 @@
         return ccActionNotSupportedForChannel;
     }
 
-    if (((setFlag & setAccessMode) &&
-         (!isValidAccessMode(chAccessData.accessMode))) ||
-        ((setFlag & setPrivLimit) &&
-         (!isValidPrivLimit(chAccessData.privLimit))))
+    if ((setFlag & setAccessMode) &&
+        (!isValidAccessMode(chAccessData.accessMode)))
     {
-        log<level::DEBUG>("Invalid access mode / privilege limit specified");
+        log<level::DEBUG>("Invalid access mode specified");
+        return ccAccessModeNotSupportedForChannel;
+    }
+    if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
+    {
+        log<level::DEBUG>("Invalid privilege limit specified");
         return ccInvalidFieldRequest;
     }
 
@@ -558,12 +561,15 @@
         return ccActionNotSupportedForChannel;
     }
 
-    if (((setFlag & setAccessMode) &&
-         (!isValidAccessMode(chAccessData.accessMode))) ||
-        ((setFlag & setPrivLimit) &&
-         (!isValidPrivLimit(chAccessData.privLimit))))
+    if ((setFlag & setAccessMode) &&
+        (!isValidAccessMode(chAccessData.accessMode)))
     {
-        log<level::DEBUG>("Invalid access mode / privilege limit specified");
+        log<level::DEBUG>("Invalid access mode specified");
+        return ccAccessModeNotSupportedForChannel;
+    }
+    if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
+    {
+        log<level::DEBUG>("Invalid privilege limit specified");
         return ccInvalidFieldRequest;
     }
 
diff --git a/user_channel/channelcommands.cpp b/user_channel/channelcommands.cpp
index 714c05a..4bf8071 100644
--- a/user_channel/channelcommands.cpp
+++ b/user_channel/channelcommands.cpp
@@ -47,16 +47,17 @@
                                uint2_t chanAccess, uint4_t channelPrivLimit,
                                uint2_t reserved2, uint2_t channelPrivMode)
 {
-    const uint8_t chNum =
-        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
-
-    if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0)
+    if (reserved1 || reserved2 ||
+        !isValidPrivLimit(static_cast<uint8_t>(channelPrivLimit)))
     {
         log<level::DEBUG>("Set channel access - Invalid field in request");
         return responseInvalidFieldRequest();
     }
 
-    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    const uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+    if ((getChannelSessionSupport(chNum) == EChannelSessSupported::none) ||
+        (!isValidChannel(chNum)))
     {
         log<level::DEBUG>("Set channel access - No support on channel");
         return response(ccActionNotSupportedForChannel);
@@ -95,7 +96,7 @@
         case reserved:
         default:
             log<level::DEBUG>("Set channel access - Invalid access set mode");
-            return responseInvalidFieldRequest();
+            return response(ccAccessModeNotSupportedForChannel);
     }
 
     // cannot static cast directly from uint2_t to enum; must go via int
@@ -116,7 +117,7 @@
         case reserved:
         default:
             log<level::DEBUG>("Set channel access - Invalid access priv mode");
-            return responseInvalidFieldRequest();
+            return response(ccAccessModeNotSupportedForChannel);
     }
 
     if (setNVFlag != 0)
@@ -170,10 +171,7 @@
     ipmiGetChannelAccess(Context::ptr ctx, uint4_t channel, uint4_t reserved1,
                          uint6_t reserved2, uint2_t accessSetMode)
 {
-    const uint8_t chNum =
-        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
-
-    if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0)
+    if (reserved1 || reserved2)
     {
         log<level::DEBUG>("Get channel access - Invalid field in request");
         return responseInvalidFieldRequest();
@@ -182,10 +180,14 @@
     if ((accessSetMode == doNotSet) || (accessSetMode == reserved))
     {
         log<level::DEBUG>("Get channel access - Invalid Access mode");
-        return responseInvalidFieldRequest();
+        return response(ccAccessModeNotSupportedForChannel);
     }
 
-    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    const uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+
+    if ((getChannelSessionSupport(chNum) == EChannelSessSupported::none) ||
+        (!isValidChannel(chNum)))
     {
         log<level::DEBUG>("Get channel access - No support on channel");
         return response(ccActionNotSupportedForChannel);
@@ -245,14 +247,20 @@
         >
     ipmiGetChannelInfo(Context::ptr ctx, uint4_t channel, uint4_t reserved)
 {
-    uint8_t chNum =
-        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
-    if (!isValidChannel(chNum) || reserved)
+    if (reserved)
     {
         log<level::DEBUG>("Get channel access - Invalid field in request");
         return responseInvalidFieldRequest();
     }
 
+    uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Get channel Info - No support on channel");
+        return response(ccActionNotSupportedForChannel);
+    }
+
     ChannelInfo chInfo;
     Cc compCode = getChannelInfo(chNum, chInfo);
     if (compCode != ccSuccess)
@@ -315,20 +323,19 @@
 {
     uint8_t chNum =
         convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
-    if (!isValidChannel(chNum) || reserved)
+
+    if (!doesDeviceExist(chNum) || !isValidChannel(chNum) || reserved)
     {
-        log<level::DEBUG>("Get channel access - Invalid field in request");
+        log<level::DEBUG>("Get channel payload - Invalid field in request");
         return responseInvalidFieldRequest();
     }
 
     // Session support is available in active LAN channels.
-    if ((getChannelSessionSupport(chNum) == EChannelSessSupported::none) ||
-        !(doesDeviceExist(chNum)))
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
     {
-        log<level::DEBUG>("Get channel payload - Device not exist");
-        return responseInvalidFieldRequest();
+        log<level::DEBUG>("Get channel payload - No support on channel");
+        return response(ccActionNotSupportedForChannel);
     }
-
     constexpr uint16_t stdPayloadType = standardPayloadBit(PayloadType::IPMI) |
                                         standardPayloadBit(PayloadType::SOL);
     constexpr uint16_t sessSetupPayloadType =
@@ -361,15 +368,24 @@
     uint8_t channel =
         convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel);
 
-    if (reserved || !isValidChannel(channel) ||
-        (getChannelSessionSupport(channel)) == EChannelSessSupported::none)
+    if (reserved || !isValidChannel(channel))
     {
+        log<level::DEBUG>(
+            "Get channel payload version - Invalid field in request");
         return responseInvalidFieldRequest();
     }
 
+    if (getChannelSessionSupport(channel) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>(
+            "Get channel payload version - No support on channel");
+        return response(ccActionNotSupportedForChannel);
+    }
+
     if (!isValidPayloadType(static_cast<PayloadType>(payloadTypeNum)))
     {
-        log<level::ERR>("Channel payload version - Payload type unavailable");
+        log<level::ERR>(
+            "Get channel payload version - Payload type unavailable");
 
         constexpr uint8_t payloadTypeNotSupported = 0x80;
         return response(payloadTypeNotSupported);
diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp
index c3517fd..14978a1 100644
--- a/user_channel/user_mgmt.cpp
+++ b/user_channel/user_mgmt.cpp
@@ -503,8 +503,8 @@
 
 bool UserAccess::isValidPrivilege(const uint8_t priv)
 {
-    return ((priv >= PRIVILEGE_CALLBACK && priv <= PRIVILEGE_OEM) ||
-            priv == privNoAccess);
+    // Callback privilege is deprecated in OpenBMC
+    return (isValidPrivLimit(priv) || priv == privNoAccess);
 }
 
 uint8_t UserAccess::getUsrMgmtSyncIndex()
diff --git a/user_channel/usercommands.cpp b/user_channel/usercommands.cpp
index 34687d5..36c6ebc 100644
--- a/user_channel/usercommands.cpp
+++ b/user_channel/usercommands.cpp
@@ -131,16 +131,25 @@
                                   std::optional<uint8_t> sessionLimit)
 {
     uint8_t sessLimit = sessionLimit.value_or(0);
-    uint8_t chNum =
-        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
-    if (reserved1 != 0 || reserved2 != 0 || sessLimit != 0 ||
-        (!isValidChannel(chNum)) ||
-        (!ipmiUserIsValidPrivilege(static_cast<uint8_t>(privilege))) ||
-        (EChannelSessSupported::none == getChannelSessionSupport(chNum)))
+    if (reserved1 || reserved2 || sessLimit ||
+        !ipmiUserIsValidPrivilege(static_cast<uint8_t>(privilege)))
     {
         log<level::DEBUG>("Set user access - Invalid field in request");
         return ipmi::responseInvalidFieldRequest();
     }
+
+    uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
+    if (!isValidChannel(chNum))
+    {
+        log<level::DEBUG>("Set user access - Invalid channel request");
+        return ipmi::response(invalidChannel);
+    }
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>("Set user access - No support on channel");
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
     if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
     {
         log<level::DEBUG>("Set user access - Parameter out of range");
@@ -202,12 +211,18 @@
 {
     uint8_t chNum =
         convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
-    if (reserved1 != 0 || reserved2 != 0 || (!isValidChannel(chNum)) ||
-        (EChannelSessSupported::none == getChannelSessionSupport(chNum)))
+
+    if (reserved1 || reserved2 || !isValidChannel(chNum))
     {
         log<level::DEBUG>("Get user access - Invalid field in request");
         return ipmi::responseInvalidFieldRequest();
     }
+
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>("Get user access - No support on channel");
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
     if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
     {
         log<level::DEBUG>("Get user access - Parameter out of range");
@@ -450,15 +465,22 @@
                                              bool extData, uint4_t privLevel,
                                              uint4_t reserved2)
 {
-
     uint8_t channel =
         convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel);
 
     if (reserved1 || reserved2 || !isValidChannel(channel) ||
-        !isValidPrivLimit(static_cast<uint8_t>(privLevel)) ||
-        (EChannelSessSupported::none == getChannelSessionSupport(channel)))
+        !isValidPrivLimit(static_cast<uint8_t>(privLevel)))
     {
-        return ipmi::response(ccInvalidFieldRequest);
+        log<level::DEBUG>(
+            "Get channel auth capabilities - Invalid field in request");
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    if (getChannelSessionSupport(channel) == EChannelSessSupported::none)
+    {
+        log<level::DEBUG>(
+            "Get channel auth capabilities - No support on channel");
+        return ipmi::response(ccActionNotSupportedForChannel);
     }
 
     constexpr bool extDataSupport = true; // true for IPMI 2.0 extensions
@@ -532,25 +554,27 @@
 
     uint8_t oemPayloadEnables2Reserved)
 {
+    auto chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
     // Validate the reserved args. Only SOL payload is supported as on date.
     if (reserved || stdPayload0ipmiReserved || stdPayload2 || stdPayload3 ||
         stdPayload4 || stdPayload5 || stdPayload6 || stdPayload7 ||
         oemPayload0 || oemPayload1 || oemPayload2 || oemPayload3 ||
         oemPayload4 || oemPayload5 || oemPayload6 || oemPayload7 ||
-        stdPayloadEnables2Reserved || oemPayloadEnables2Reserved)
+        stdPayloadEnables2Reserved || oemPayloadEnables2Reserved ||
+        !isValidChannel(chNum))
     {
         return ipmi::responseInvalidFieldRequest();
     }
 
-    auto chNum =
-        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
-    if ((operation != enableOperation && operation != disableOperation) ||
-        (!isValidChannel(chNum)) ||
-        (getChannelSessionSupport(chNum) == EChannelSessSupported::none))
+    if ((operation != enableOperation && operation != disableOperation))
     {
         return ipmi::responseInvalidFieldRequest();
     }
-
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
     if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
     {
         return ipmi::responseParmOutOfRange();
@@ -627,11 +651,15 @@
 {
     uint8_t chNum =
         convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
-    if (reserved1 != 0 || reserved2 != 0 || (!isValidChannel(chNum)) ||
-        (getChannelSessionSupport(chNum) == EChannelSessSupported::none))
+
+    if (reserved1 || reserved2 || !isValidChannel(chNum))
     {
         return ipmi::responseInvalidFieldRequest();
     }
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
+    {
+        return ipmi::response(ccActionNotSupportedForChannel);
+    }
     if (!ipmiUserIsValidUserId(static_cast<uint8_t>(userId)))
     {
         return ipmi::responseParmOutOfRange();