channelcmds: move set channel access to new ipmi provider API

This updates the set channel access command to use the new IPMI provider
API. As part of this change, this command should now work with the
special channel 0x0e.

Tested-by:
    (set channel access: 6 0x40)
    # ipmitool -I lanplus -H ... -U ... raw 6 0x40 0xe 0x82 0x84
    (get channel access: 6 0x41)
    # ipmitool -I lanplus -H ... -U ... raw 6 0x41 0xe 0x80
     02 04
    # ipmitool raw 6 0x40 1 0x80 0x83
    # ipmitool raw 6 0x41 1 0x80
     00 03

Change-Id: Icc6e8ff7deebb7a6f89af616fa70258ea18ed0ce
Signed-off-by: NITIN SHARMA <nitin1x.sharma@intel.com>
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/user_channel/channelcommands.cpp b/user_channel/channelcommands.cpp
index d1b275e..6a1df7a 100644
--- a/user_channel/channelcommands.cpp
+++ b/user_channel/channelcommands.cpp
@@ -19,6 +19,7 @@
 #include "apphandler.hpp"
 #include "channel_layer.hpp"
 
+#include <ipmid/api.hpp>
 #include <phosphor-logging/log.hpp>
 #include <regex>
 
@@ -27,39 +28,6 @@
 namespace ipmi
 {
 
-/** @struct SetChannelAccessReq
- *
- *  Structure for set channel access request command (refer spec sec 22.22)
- */
-struct SetChannelAccessReq
-{
-#if BYTE_ORDER == LITTLE_ENDIAN
-    uint8_t chNum : 4;
-    uint8_t reserved_1 : 4;
-    uint8_t accessMode : 3;
-    uint8_t usrAuthDisabled : 1;
-    uint8_t msgAuthDisabled : 1;
-    uint8_t alertDisabled : 1;
-    uint8_t accessSetMode : 2;
-    uint8_t privLimit : 4;
-    uint8_t reserved_2 : 2;
-    uint8_t privSetMode : 2;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
-    uint8_t reserved_1 : 4;
-    uint8_t chNum : 4;
-    uint8_t accessSetMode : 2;
-    uint8_t alertDisabled : 1;
-    uint8_t msgAuthDisabled : 1;
-    uint8_t usrAuthDisabled : 1;
-    uint8_t accessMode : 3;
-    uint8_t privSetMode : 2;
-    uint8_t reserved_2 : 2;
-    uint8_t privLimit : 4;
-#endif
-
-} __attribute__((packed));
-
 /** @struct GetChannelAccessReq
  *
  *  Structure for get channel access request command (refer spec sec 22.23)
@@ -182,86 +150,97 @@
     uint8_t reserved[2];
 } __attribute__((packed));
 
-ipmi_ret_t ipmiSetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                                ipmi_request_t request,
-                                ipmi_response_t response,
-                                ipmi_data_len_t data_len,
-                                ipmi_context_t context)
+/** @brief implements the set channel access command
+ *  @ param ctx - context pointer
+ *  @ param channel - channel number
+ *  @ param reserved - skip 4 bits
+ *  @ param accessMode - access mode for IPMI messaging
+ *  @ param usrAuth - user level authentication (enable/disable)
+ *  @ param msgAuth - per message authentication (enable/disable)
+ *  @ param alertDisabled - PEF alerting (enable/disable)
+ *  @ param chanAccess - channel access
+ *  @ param channelPrivLimit - channel privilege limit
+ *  @ param reserved - skip 3 bits
+ *  @ param channelPrivMode - channel priviledge mode
+ *
+ *  @ returns IPMI completion code
+ **/
+RspType<> ipmiSetChannelAccess(Context::ptr ctx, uint4_t channel,
+                               uint4_t reserved1, uint3_t accessMode,
+                               bool usrAuth, bool msgAuth, bool alertDisabled,
+                               uint2_t chanAccess, uint4_t channelPrivLimit,
+                               uint2_t reserved2, uint2_t channelPrivMode)
 {
-    const SetChannelAccessReq* req = static_cast<SetChannelAccessReq*>(request);
-    size_t reqLength = *data_len;
+    const uint8_t chNum =
+        convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
 
-    *data_len = 0;
-
-    if (reqLength != sizeof(*req))
-    {
-        log<level::DEBUG>("Set channel access - Invalid Length");
-        return IPMI_CC_REQ_DATA_LEN_INVALID;
-    }
-
-    uint8_t chNum = convertCurrentChannelNum(req->chNum);
-    if (!isValidChannel(chNum) || req->reserved_1 != 0 || req->reserved_2 != 0)
+    if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0)
     {
         log<level::DEBUG>("Set channel access - Invalid field in request");
-        return IPMI_CC_INVALID_FIELD_REQUEST;
+        return responseInvalidFieldRequest();
     }
 
-    if (EChannelSessSupported::none == getChannelSessionSupport(chNum))
+    if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
     {
         log<level::DEBUG>("Set channel access - No support on channel");
-        return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL;
+        return responseInvalidFieldRequest();
     }
 
     ChannelAccess chActData;
     ChannelAccess chNVData;
     uint8_t setActFlag = 0;
     uint8_t setNVFlag = 0;
-    ipmi_ret_t compCode = IPMI_CC_OK;
+    Cc compCode;
 
-    switch (req->accessSetMode)
+    // cannot static cast directly from uint2_t to enum; must go via int
+    uint8_t channelAccessAction = static_cast<uint8_t>(chanAccess);
+    switch (static_cast<EChannelActionType>(channelAccessAction))
     {
         case doNotSet:
-            // Do nothing
             break;
         case nvData:
-            chNVData.accessMode = req->accessMode;
-            chNVData.userAuthDisabled = req->usrAuthDisabled;
-            chNVData.perMsgAuthDisabled = req->msgAuthDisabled;
-            chNVData.alertingDisabled = req->alertDisabled;
+            chNVData.accessMode = static_cast<uint8_t>(accessMode);
+            chNVData.userAuthDisabled = usrAuth;
+            chNVData.perMsgAuthDisabled = msgAuth;
+            chNVData.alertingDisabled = alertDisabled;
             setNVFlag |= (setAccessMode | setUserAuthEnabled |
                           setMsgAuthEnabled | setAlertingEnabled);
             break;
+
         case activeData:
-            chActData.accessMode = req->accessMode;
-            chActData.userAuthDisabled = req->usrAuthDisabled;
-            chActData.perMsgAuthDisabled = req->msgAuthDisabled;
-            chActData.alertingDisabled = req->alertDisabled;
+            chActData.accessMode = static_cast<uint8_t>(accessMode);
+            chActData.userAuthDisabled = usrAuth;
+            chActData.perMsgAuthDisabled = msgAuth;
+            chActData.alertingDisabled = alertDisabled;
             setActFlag |= (setAccessMode | setUserAuthEnabled |
                            setMsgAuthEnabled | setAlertingEnabled);
             break;
+
         case reserved:
         default:
             log<level::DEBUG>("Set channel access - Invalid access set mode");
-            return IPMI_CC_INVALID_FIELD_REQUEST;
+            return responseInvalidFieldRequest();
     }
 
-    switch (req->privSetMode)
+    // cannot static cast directly from uint2_t to enum; must go via int
+    uint8_t channelPrivAction = static_cast<uint8_t>(channelPrivMode);
+    switch (static_cast<EChannelActionType>(channelPrivAction))
     {
         case doNotSet:
-            // Do nothing
             break;
         case nvData:
-            chNVData.privLimit = req->privLimit;
+            chNVData.privLimit = static_cast<uint8_t>(channelPrivLimit);
             setNVFlag |= setPrivLimit;
             break;
         case activeData:
-            chActData.privLimit = req->privLimit;
+            chActData.privLimit = static_cast<uint8_t>(channelPrivLimit);
+
             setActFlag |= setPrivLimit;
             break;
         case reserved:
         default:
             log<level::DEBUG>("Set channel access - Invalid access priv mode");
-            return IPMI_CC_INVALID_FIELD_REQUEST;
+            return responseInvalidFieldRequest();
     }
 
     if (setNVFlag != 0)
@@ -270,7 +249,7 @@
         if (compCode != IPMI_CC_OK)
         {
             log<level::DEBUG>("Set channel access - Failed to set access data");
-            return compCode;
+            return response(compCode);
         }
     }
 
@@ -280,11 +259,11 @@
         if (compCode != IPMI_CC_OK)
         {
             log<level::DEBUG>("Set channel access - Failed to set access data");
-            return compCode;
+            return response(compCode);
         }
     }
 
-    return IPMI_CC_OK;
+    return responseSuccess();
 }
 
 ipmi_ret_t ipmiGetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
@@ -500,8 +479,8 @@
 {
     ipmiChannelInit();
 
-    ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_CHANNEL_ACCESS, NULL,
-                           ipmiSetChannelAccess, PRIVILEGE_ADMIN);
+    registerHandler(prioOpenBmcBase, netFnApp, app::cmdSetChannelAccess,
+                    Privilege::Admin, ipmiSetChannelAccess);
 
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS, NULL,
                            ipmiGetChannelAccess, PRIVILEGE_USER);