IPMI channel to NIC device mapping modified within JSON config file

The IPMI to NIC channel mapping was done using a hard coded scheme.
The scheme used generic channel names which were then mapped to
specific device names.  The hard coded generic to specific naming
convention is removed, and the JSON file contains the device name
directly.

Change-Id: Ibc6821cae5a26f2666467aba5346d364053f2582
Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
diff --git a/Makefile.am b/Makefile.am
index 48aa48f..738092c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -99,6 +99,7 @@
 
 TESTS = $(check_PROGRAMS)
 
+libipmi20_la_LIBADD = user_channel/libuserlayer.la
 libipmi20_la_LDFLAGS = \
 	$(SYSTEMD_LIBS) \
 	$(libmapper_LIBS) \
diff --git a/app/channel.cpp b/app/channel.cpp
index e5d6770..93fba24 100644
--- a/app/channel.cpp
+++ b/app/channel.cpp
@@ -1,8 +1,8 @@
 #include "channel.hpp"
 
-#include "net.hpp"
 #include "transporthandler.hpp"
 #include "types.hpp"
+#include "user_channel/channel_layer.hpp"
 #include "utils.hpp"
 
 #include <arpa/inet.h>
@@ -56,7 +56,7 @@
      */
     constexpr auto channelE = 0x0E;
     int channel = requestData->channelNumber;
-    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
+    auto ethdevice = ipmi::getChannelName(channel);
 
     if (channel != channelE && ethdevice.empty())
     {
@@ -102,7 +102,7 @@
     ipmi_ret_t rc = IPMI_CC_OK;
     auto* p = static_cast<uint8_t*>(request);
     int channel = (*p) & CHANNEL_MASK;
-    std::string ethdevice = ipmi::network::ChanneltoEthernet(channel);
+    std::string ethdevice = ipmi::getChannelName(channel);
 
     // The supported channels numbers are those which are configured.
     // Channel Number E is used as way to identify the current channel
@@ -365,7 +365,7 @@
 
     int channel = requestData->channelNumber;
     // Validate the channel number corresponds to any of the network channel.
-    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
+    auto ethdevice = ipmi::getChannelName(channel);
     if (ethdevice.empty())
     {
         *data_len = 0;
diff --git a/dcmihandler.cpp b/dcmihandler.cpp
index e1a44b5..15ab26c 100644
--- a/dcmihandler.cpp
+++ b/dcmihandler.cpp
@@ -2,7 +2,7 @@
 
 #include "dcmihandler.hpp"
 
-#include "net.hpp"
+#include "user_channel/channel_layer.hpp"
 #include "utils.hpp"
 
 #include <host-ipmid/ipmid-api.h>
@@ -247,8 +247,7 @@
 {
     sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
 
-    auto ethdevice =
-        ipmi::network::ChanneltoEthernet(ethernetDefaultChannelNum);
+    auto ethdevice = ipmi::getChannelName(ethernetDefaultChannelNum);
     auto ethernetObj =
         ipmi::getDbusObject(bus, ethernetIntf, networkRoot, ethdevice);
     auto service = ipmi::getService(bus, ethernetIntf, ethernetObj.first);
diff --git a/transporthandler.cpp b/transporthandler.cpp
index 88938b1..72beebc 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -2,7 +2,7 @@
 
 #include "app/channel.hpp"
 #include "ipmid.hpp"
-#include "net.hpp"
+#include "user_channel/channel_layer.hpp"
 #include "utils.hpp"
 
 #include <arpa/inet.h>
@@ -70,7 +70,7 @@
     ipmi_ret_t rc = IPMI_CC_OK;
     sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
 
-    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
+    auto ethdevice = ipmi::getChannelName(channel);
     // if ethdevice is an empty string they weren't expecting this channel.
     if (ethdevice.empty())
     {
@@ -416,7 +416,7 @@
 
     // channel number is the lower nibble
     int channel = reqptr->channel & CHANNEL_MASK;
-    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
+    auto ethdevice = ipmi::getChannelName(channel);
     if (ethdevice.empty())
     {
         return IPMI_CC_INVALID_FIELD_REQUEST;
@@ -578,7 +578,7 @@
         }
     }
 
-    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
+    auto ethdevice = ipmi::getChannelName(channel);
     if (ethdevice.empty())
     {
         return IPMI_CC_INVALID_FIELD_REQUEST;
@@ -706,7 +706,7 @@
     ipmi::DbusObjectInfo ipObject;
     ipmi::DbusObjectInfo systemObject;
 
-    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
+    auto ethdevice = ipmi::getChannelName(channel);
     if (ethdevice.empty())
     {
         log<level::ERR>("Unable to get the interface name",
diff --git a/user_channel/channel_layer.cpp b/user_channel/channel_layer.cpp
index 12b10c9..0bd7ffe 100644
--- a/user_channel/channel_layer.cpp
+++ b/user_channel/channel_layer.cpp
@@ -29,8 +29,7 @@
     // associated with ethernet interface as the channel number to
     // eth association is not done. Need to revisit later
     struct stat fileStat = {0};
-    std::string devName("/sys/class/net/" +
-                        getChannelConfigObject().getChannelName(chNum));
+    std::string devName("/sys/class/net/" + getChannelName(chNum));
 
     if (stat(devName.data(), &fileStat) != 0)
     {
@@ -138,4 +137,9 @@
                                                               authType);
 }
 
+std::string getChannelName(const int chNum)
+{
+    return getChannelConfigObject().getChannelName(chNum);
+}
+
 } // namespace ipmi
diff --git a/user_channel/channel_layer.hpp b/user_channel/channel_layer.hpp
index 87e791c..a3aebb8 100644
--- a/user_channel/channel_layer.hpp
+++ b/user_channel/channel_layer.hpp
@@ -322,4 +322,12 @@
 ipmi_ret_t getChannelEnabledAuthType(const uint8_t chNum, const uint8_t priv,
                                      EAuthType& authType);
 
+/** @brief Retrieves the LAN channel name from the IPMI channel number
+ *
+ *  @param[in] chNum - IPMI channel number
+ *
+ *  @return the LAN channel name (i.e. eth0)
+ */
+std::string getChannelName(const int chNum);
+
 } // namespace ipmi
diff --git a/user_channel/channel_mgmt.cpp b/user_channel/channel_mgmt.cpp
index 45a703a..585d441 100644
--- a/user_channel/channel_mgmt.cpp
+++ b/user_channel/channel_mgmt.cpp
@@ -137,7 +137,36 @@
     "priv-reserved", "priv-callback", "priv-user",
     "priv-operator", "priv-admin",    "priv-oem"};
 
-std::string getNetIntfFromPath(const std::string& path)
+std::string ChannelConfig::getChannelName(const int chNum)
+{
+    if (!isValidChannel(chNum))
+    {
+        log<level::ERR>("Invalid channel number.",
+                        entry("ChannelID:%d", chNum));
+        throw std::invalid_argument("Invalid channel number");
+    }
+
+    return channelData[chNum].chName;
+}
+
+int ChannelConfig::convertToChannelNumberFromChannelName(
+    const std::string& chName)
+{
+    for (const auto& it : channelData)
+    {
+        if (it.chName == chName)
+        {
+            return it.chID;
+        }
+    }
+    log<level::ERR>("Invalid channel name.",
+                    entry("Channel:%s", chName.c_str()));
+    throw std::invalid_argument("Invalid channel name");
+
+    return -1;
+}
+
+std::string ChannelConfig::getChannelNameFromPath(const std::string& path)
 {
     std::size_t pos = path.find(networkIntfObjectBasePath);
     if (pos == std::string::npos)
@@ -146,19 +175,19 @@
                         entry("PATH:%s", path.c_str()));
         throw std::invalid_argument("Invalid interface path");
     }
-    std::string intfName =
+    std::string chName =
         path.substr(pos + strlen(networkIntfObjectBasePath) + 1);
-    return intfName;
+    return chName;
 }
 
 void ChannelConfig::processChAccessPropChange(
     const std::string& path, const DbusChObjProperties& chProperties)
 {
     // Get interface name from path. ex: '/xyz/openbmc_project/network/eth0'
-    std::string channelName;
+    std::string chName;
     try
     {
-        channelName = getNetIntfFromPath(path);
+        chName = getChannelNameFromPath(path);
     }
     catch (const std::invalid_argument& e)
     {
@@ -188,14 +217,16 @@
     if (intfPrivStr.empty())
     {
         log<level::ERR>("Invalid privilege string.",
-                        entry("INTF:%s", channelName.c_str()));
+                        entry("INTF:%s", chName.c_str()));
         return;
     }
 
     uint8_t intfPriv = 0;
+    int chNum;
     try
     {
         intfPriv = static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
+        chNum = convertToChannelNumberFromChannelName(chName);
     }
     catch (const std::invalid_argument& e)
     {
@@ -205,21 +236,6 @@
 
     boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
         channelLock{*channelMutex};
-    uint8_t chNum = 0;
-    // Get the channel number based on the channel name.
-    for (chNum = 0; chNum < maxIpmiChannels; chNum++)
-    {
-        if (channelData[chNum].chName == channelName)
-        {
-            break;
-        }
-    }
-    if (chNum >= maxIpmiChannels)
-    {
-        log<level::ERR>("Invalid interface in signal path");
-        return;
-    }
-
     // skip updating the values, if this property change originated from IPMI.
     if (signalFlag & (1 << chNum))
     {
diff --git a/user_channel/channel_mgmt.hpp b/user_channel/channel_mgmt.hpp
index 89e069e..cb0ea33 100644
--- a/user_channel/channel_mgmt.hpp
+++ b/user_channel/channel_mgmt.hpp
@@ -232,6 +232,14 @@
      */
     int writeChannelVolatileData();
 
+    /** @brief function to get channel name from channel number
+     *
+     *  @param[in] chNum - channel number index
+     *
+     *  @return network channel interface name
+     */
+    std::string getChannelName(const int chNum);
+
   private:
     uint32_t signalFlag = 0;
     std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{
@@ -390,13 +398,14 @@
      */
     EChannelProtocolType convertToProtocolTypeIndex(const std::string& value);
 
-    /** @brief function to convert channel name to network interface name
+    /** @brief function to convert channel name to the IPMI channel number.
      *
-     *  @param[in] value - channel interface name - ipmi centric
+     *  @param[in] chName - the channel name defined in the JSON input file
+     *  (i.e. LAN1)
      *
-     *  @return network channel interface name
+     *  @return IPMI channel number
      */
-    std::string convertToNetInterface(const std::string& value);
+    int convertToChannelNumberFromChannelName(const std::string& chName);
 
     /** @brief function to handle Channel access property update through the
      * D-Bus handler.
@@ -415,6 +424,14 @@
      *  @return time the file was last modified
      */
     std::time_t getUpdatedFileTime(const std::string& fileName);
+
+    /** @brief function to convert the DBus path to a network channel name
+     *
+     *  @param[in] path - The DBus path to the device
+     *
+     *  @return network channel name (i.e. eth0)
+     */
+    std::string getChannelNameFromPath(const std::string& path);
 };
 
 } // namespace ipmi