#include "transporthandler.hpp"

#include "app/channel.hpp"
#include "ipmid.hpp"
#include "net.hpp"
#include "timer.hpp"
#include "utils.hpp"

#include <arpa/inet.h>
#include <host-ipmid/ipmid-api.h>

#include <chrono>
#include <fstream>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <string>
#include <xyz/openbmc_project/Common/error.hpp>

#define SYSTEMD_NETWORKD_DBUS 1

#ifdef SYSTEMD_NETWORKD_DBUS
#include <mapper.h>
#include <systemd/sd-bus.h>
#endif

#if __has_include(<filesystem>)
#include <filesystem>
#elif __has_include(<experimental/filesystem>)
#include <experimental/filesystem>
namespace std
{
// splice experimental::filesystem into std
namespace filesystem = std::experimental::filesystem;
} // namespace std
#else
#error filesystem not available
#endif

extern std::unique_ptr<phosphor::ipmi::Timer> networkTimer;

const int SIZE_MAC = 18; // xx:xx:xx:xx:xx:xx
constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";

std::map<int, std::unique_ptr<struct ChannelConfig_t>> channelConfig;

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;

namespace fs = std::filesystem;

void register_netfn_transport_functions() __attribute__((constructor));

struct ChannelConfig_t* getChannelConfig(int channel)
{
    auto item = channelConfig.find(channel);
    if (item == channelConfig.end())
    {
        channelConfig[channel] = std::make_unique<struct ChannelConfig_t>();
    }

    return channelConfig[channel].get();
}

// Helper Function to get IP Address/NetMask/Gateway/MAC Address from Network
// Manager or Cache based on Set-In-Progress State
ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data, int channel)
{
    ipmi_ret_t rc = IPMI_CC_OK;
    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());

    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
    // if ethdevice is an empty string they weren't expecting this channel.
    if (ethdevice.empty())
    {
        // TODO: return error from getNetworkData()
        return IPMI_CC_INVALID_FIELD_REQUEST;
    }
    auto ethIP = ethdevice + "/" + ipmi::network::IP_TYPE;
    auto channelConf = getChannelConfig(channel);

    try
    {
        switch (lan_param)
        {
            case LAN_PARM_IP:
            {
                std::string ipaddress;
                if (channelConf->lan_set_in_progress == SET_COMPLETE)
                {
                    try
                    {
                        auto ipObjectInfo =
                            ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE,
                                              ipmi::network::ROOT, ethIP);

                        auto properties = ipmi::getAllDbusProperties(
                            bus, ipObjectInfo.second, ipObjectInfo.first,
                            ipmi::network::IP_INTERFACE);

                        ipaddress = properties["Address"].get<std::string>();
                    }
                    // ignore the exception, as it is a valid condition that
                    // the system is not configured with any IP.
                    catch (InternalFailure& e)
                    {
                        // nothing to do.
                    }
                }
                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
                {
                    ipaddress = channelConf->ipaddr;
                }

                inet_pton(AF_INET, ipaddress.c_str(),
                          reinterpret_cast<void*>(data));
            }
            break;

            case LAN_PARM_IPSRC:
            {
                std::string networkInterfacePath;

                if (channelConf->lan_set_in_progress == SET_COMPLETE)
                {
                    try
                    {
                        ipmi::ObjectTree ancestorMap;
                        // if the system is having ip object,then
                        // get the IP object.
                        auto ipObject = ipmi::getDbusObject(
                            bus, ipmi::network::IP_INTERFACE,
                            ipmi::network::ROOT, ethIP);

                        // Get the parent interface of the IP object.
                        try
                        {
                            ipmi::InterfaceList interfaces;
                            interfaces.emplace_back(
                                ipmi::network::ETHERNET_INTERFACE);

                            ancestorMap = ipmi::getAllAncestors(
                                bus, ipObject.first, std::move(interfaces));
                        }
                        catch (InternalFailure& e)
                        {
                            // if unable to get the parent interface
                            // then commit the error and return.
                            log<level::ERR>(
                                "Unable to get the parent interface",
                                entry("PATH=%s", ipObject.first.c_str()),
                                entry("INTERFACE=%s",
                                      ipmi::network::ETHERNET_INTERFACE));
                            break;
                        }
                        // for an ip object there would be single parent
                        // interface.
                        networkInterfacePath = ancestorMap.begin()->first;
                    }
                    catch (InternalFailure& e)
                    {
                        // if there is no ip configured on the system,then
                        // get the network interface object.
                        auto networkInterfaceObject = ipmi::getDbusObject(
                            bus, ipmi::network::ETHERNET_INTERFACE,
                            ipmi::network::ROOT, ethdevice);

                        networkInterfacePath = networkInterfaceObject.first;
                    }

                    auto variant = ipmi::getDbusProperty(
                        bus, ipmi::network::SERVICE, networkInterfacePath,
                        ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled");

                    auto dhcpEnabled = variant.get<bool>();
                    // As per IPMI spec 2=>DHCP, 1=STATIC
                    auto ipsrc = dhcpEnabled ? ipmi::network::IPOrigin::DHCP
                                             : ipmi::network::IPOrigin::STATIC;

                    memcpy(data, &ipsrc, ipmi::network::IPSRC_SIZE_BYTE);
                }
                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
                {
                    memcpy(data, &(channelConf->ipsrc),
                           ipmi::network::IPSRC_SIZE_BYTE);
                }
            }
            break;

            case LAN_PARM_SUBNET:
            {
                unsigned long mask{};
                if (channelConf->lan_set_in_progress == SET_COMPLETE)
                {
                    try
                    {
                        auto ipObjectInfo = ipmi::getIPObject(
                            bus, ipmi::network::IP_INTERFACE,
                            ipmi::network::ROOT, ipmi::network::IP_TYPE);

                        auto properties = ipmi::getAllDbusProperties(
                            bus, ipObjectInfo.second, ipObjectInfo.first,
                            ipmi::network::IP_INTERFACE);

                        auto prefix = properties["PrefixLength"].get<uint8_t>();
                        mask = ipmi::network::MASK_32_BIT;
                        mask = htonl(mask << (ipmi::network::BITS_32 - prefix));
                    }
                    // ignore the exception, as it is a valid condition that
                    // the system is not configured with any IP.
                    catch (InternalFailure& e)
                    {
                        // nothing to do
                    }
                    memcpy(data, &mask, ipmi::network::IPV4_ADDRESS_SIZE_BYTE);
                }
                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
                {
                    inet_pton(AF_INET, channelConf->netmask.c_str(),
                              reinterpret_cast<void*>(data));
                }
            }
            break;

            case LAN_PARM_GATEWAY:
            {
                std::string gateway;

                if (channelConf->lan_set_in_progress == SET_COMPLETE)
                {
                    try
                    {
                        auto systemObject = ipmi::getDbusObject(
                            bus, ipmi::network::SYSTEMCONFIG_INTERFACE,
                            ipmi::network::ROOT);

                        auto systemProperties = ipmi::getAllDbusProperties(
                            bus, systemObject.second, systemObject.first,
                            ipmi::network::SYSTEMCONFIG_INTERFACE);

                        gateway = systemProperties["DefaultGateway"]
                                      .get<std::string>();
                    }
                    // ignore the exception, as it is a valid condition that
                    // the system is not configured with any IP.
                    catch (InternalFailure& e)
                    {
                        // nothing to do
                    }
                }
                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
                {
                    gateway = channelConf->gateway;
                }

                inet_pton(AF_INET, gateway.c_str(),
                          reinterpret_cast<void*>(data));
            }
            break;

            case LAN_PARM_MAC:
            {
                std::string macAddress;
                if (channelConf->lan_set_in_progress == SET_COMPLETE)
                {
                    auto macObjectInfo =
                        ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
                                            ipmi::network::ROOT, ethdevice);

                    auto variant = ipmi::getDbusProperty(
                        bus, macObjectInfo.second, macObjectInfo.first,
                        ipmi::network::MAC_INTERFACE, "MACAddress");

                    macAddress = variant.get<std::string>();
                }
                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
                {
                    macAddress = channelConf->macAddress;
                }

                sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
                       (data), (data + 1), (data + 2), (data + 3), (data + 4),
                       (data + 5));
            }
            break;

            case LAN_PARM_VLAN:
            {
                uint16_t vlanID{};
                if (channelConf->lan_set_in_progress == SET_COMPLETE)
                {
                    try
                    {
                        auto ipObjectInfo = ipmi::getIPObject(
                            bus, ipmi::network::IP_INTERFACE,
                            ipmi::network::ROOT, ipmi::network::IP_TYPE);

                        vlanID = static_cast<uint16_t>(
                            ipmi::network::getVLAN(ipObjectInfo.first));

                        vlanID = htole16(vlanID);

                        if (vlanID)
                        {
                            // Enable the 16th bit
                            vlanID |= htole16(ipmi::network::VLAN_ENABLE_MASK);
                        }
                    }
                    // ignore the exception, as it is a valid condition that
                    // the system is not configured with any IP.
                    catch (InternalFailure& e)
                    {
                        // nothing to do
                    }

                    memcpy(data, &vlanID, ipmi::network::VLAN_SIZE_BYTE);
                }
                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
                {
                    memcpy(data, &(channelConf->vlanID),
                           ipmi::network::VLAN_SIZE_BYTE);
                }
            }
            break;

            default:
                rc = IPMI_CC_PARM_OUT_OF_RANGE;
        }
    }
    catch (InternalFailure& e)
    {
        commit<InternalFailure>();
        rc = IPMI_CC_UNSPECIFIED_ERROR;
        return rc;
    }
    return rc;
}

namespace cipher
{

std::vector<uint8_t> getCipherList()
{
    std::vector<uint8_t> cipherList;

    std::ifstream jsonFile(configFile);
    if (!jsonFile.is_open())
    {
        log<level::ERR>("Channel Cipher suites file not found");
        elog<InternalFailure>();
    }

    auto data = Json::parse(jsonFile, nullptr, false);
    if (data.is_discarded())
    {
        log<level::ERR>("Parsing channel cipher suites JSON failed");
        elog<InternalFailure>();
    }

    // Byte 1 is reserved
    cipherList.push_back(0x00);

    for (const auto& record : data)
    {
        cipherList.push_back(record.value(cipher, 0));
    }

    return cipherList;
}

} // namespace cipher

ipmi_ret_t ipmi_transport_wildcard(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)
{
    // Status code.
    ipmi_ret_t rc = IPMI_CC_INVALID;
    *data_len = 0;
    return rc;
}

struct set_lan_t
{
    uint8_t channel;
    uint8_t parameter;
    uint8_t data[8]; // Per IPMI spec, not expecting more than this size
} __attribute__((packed));

ipmi_ret_t ipmi_transport_set_lan(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)
{
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = 0;

    using namespace std::chrono_literals;

    // time to wait before applying the network changes.
    constexpr auto networkTimeout = 10000000us; // 10 sec

    char ipaddr[INET_ADDRSTRLEN];
    char netmask[INET_ADDRSTRLEN];
    char gateway[INET_ADDRSTRLEN];

    auto reqptr = reinterpret_cast<const set_lan_t*>(request);
    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());

    // channel number is the lower nibble
    int channel = reqptr->channel & CHANNEL_MASK;
    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
    if (ethdevice.empty())
    {
        return IPMI_CC_INVALID_FIELD_REQUEST;
    }
    auto channelConf = getChannelConfig(channel);

    switch (reqptr->parameter)
    {
        case LAN_PARM_IP:
        {
            snprintf(ipaddr, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
                     reqptr->data[0], reqptr->data[1], reqptr->data[2],
                     reqptr->data[3]);

            channelConf->ipaddr.assign(ipaddr);
        }
        break;

        case LAN_PARM_IPSRC:
        {
            uint8_t ipsrc{};
            memcpy(&ipsrc, reqptr->data, ipmi::network::IPSRC_SIZE_BYTE);
            channelConf->ipsrc = static_cast<ipmi::network::IPOrigin>(ipsrc);
        }
        break;

        case LAN_PARM_MAC:
        {
            char mac[SIZE_MAC];

            snprintf(mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT,
                     reqptr->data[0], reqptr->data[1], reqptr->data[2],
                     reqptr->data[3], reqptr->data[4], reqptr->data[5]);

            auto macObjectInfo =
                ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
                                    ipmi::network::ROOT, ethdevice);

            ipmi::setDbusProperty(
                bus, macObjectInfo.second, macObjectInfo.first,
                ipmi::network::MAC_INTERFACE, "MACAddress", std::string(mac));

            channelConf->macAddress = mac;
        }
        break;

        case LAN_PARM_SUBNET:
        {
            snprintf(netmask, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
                     reqptr->data[0], reqptr->data[1], reqptr->data[2],
                     reqptr->data[3]);
            channelConf->netmask.assign(netmask);
        }
        break;

        case LAN_PARM_GATEWAY:
        {
            snprintf(gateway, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
                     reqptr->data[0], reqptr->data[1], reqptr->data[2],
                     reqptr->data[3]);
            channelConf->gateway.assign(gateway);
        }
        break;

        case LAN_PARM_VLAN:
        {
            uint16_t vlan{};
            memcpy(&vlan, reqptr->data, ipmi::network::VLAN_SIZE_BYTE);
            // We are not storing the enable bit
            // We assume that ipmitool always send enable
            // bit as 1.
            vlan = le16toh(vlan);
            channelConf->vlanID = vlan;
        }
        break;

        case LAN_PARM_INPROGRESS:
        {
            if (reqptr->data[0] == SET_COMPLETE)
            {
                channelConf->lan_set_in_progress = SET_COMPLETE;

                log<level::INFO>(
                    "Network data from Cache",
                    entry("PREFIX=%s", channelConf->netmask.c_str()),
                    entry("ADDRESS=%s", channelConf->ipaddr.c_str()),
                    entry("GATEWAY=%s", channelConf->gateway.c_str()),
                    entry("VLAN=%d", channelConf->vlanID));

                if (!networkTimer)
                {
                    log<level::ERR>("Network timer is not instantiated");
                    return IPMI_CC_UNSPECIFIED_ERROR;
                }

                // start/restart the timer
                networkTimer->startTimer(networkTimeout);
            }
            else if (reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
            {
                channelConf->lan_set_in_progress = SET_IN_PROGRESS;
                channelConf->flush = true;
            }
        }
        break;

        default:
        {
            rc = IPMI_CC_PARM_NOT_SUPPORTED;
        }
    }

    return rc;
}

struct get_lan_t
{
    uint8_t rev_channel;
    uint8_t parameter;
    uint8_t parameter_set;
    uint8_t parameter_block;
} __attribute__((packed));

ipmi_ret_t ipmi_transport_get_lan(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)
{
    ipmi_ret_t rc = IPMI_CC_OK;
    *data_len = 0;
    const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0

    get_lan_t* reqptr = (get_lan_t*)request;
    // channel number is the lower nibble
    int channel = reqptr->rev_channel & CHANNEL_MASK;

    if (reqptr->rev_channel & 0x80) // Revision is bit 7
    {
        // Only current revision was requested
        *data_len = sizeof(current_revision);
        memcpy(response, &current_revision, *data_len);
        return IPMI_CC_OK;
    }

    static std::vector<uint8_t> cipherList;
    static auto listInit = false;

    if (!listInit)
    {
        try
        {
            cipherList = cipher::getCipherList();
            listInit = true;
        }
        catch (const std::exception& e)
        {
            return IPMI_CC_UNSPECIFIED_ERROR;
        }
    }

    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
    if (ethdevice.empty())
    {
        return IPMI_CC_INVALID_FIELD_REQUEST;
    }
    auto channelConf = getChannelConfig(channel);

    if (reqptr->parameter == LAN_PARM_INPROGRESS)
    {
        uint8_t buf[] = {current_revision, channelConf->lan_set_in_progress};
        *data_len = sizeof(buf);
        memcpy(response, &buf, *data_len);
    }
    else if (reqptr->parameter == LAN_PARM_AUTHSUPPORT)
    {
        uint8_t buf[] = {current_revision, 0x04};
        *data_len = sizeof(buf);
        memcpy(response, &buf, *data_len);
    }
    else if (reqptr->parameter == LAN_PARM_AUTHENABLES)
    {
        uint8_t buf[] = {current_revision, 0x04, 0x04, 0x04, 0x04, 0x04};
        *data_len = sizeof(buf);
        memcpy(response, &buf, *data_len);
    }
    else if ((reqptr->parameter == LAN_PARM_IP) ||
             (reqptr->parameter == LAN_PARM_SUBNET) ||
             (reqptr->parameter == LAN_PARM_GATEWAY) ||
             (reqptr->parameter == LAN_PARM_MAC))
    {
        uint8_t buf[ipmi::network::MAC_ADDRESS_SIZE_BYTE + 1] = {};

        *data_len = sizeof(current_revision);
        memcpy(buf, &current_revision, *data_len);

        if (getNetworkData(reqptr->parameter, &buf[1], channel) == IPMI_CC_OK)
        {
            if (reqptr->parameter == LAN_PARM_MAC)
            {
                *data_len = sizeof(buf);
            }
            else
            {
                *data_len = ipmi::network::IPV4_ADDRESS_SIZE_BYTE + 1;
            }
            memcpy(response, &buf, *data_len);
        }
        else
        {
            rc = IPMI_CC_UNSPECIFIED_ERROR;
        }
    }
    else if (reqptr->parameter == LAN_PARM_VLAN)
    {
        uint8_t buf[ipmi::network::VLAN_SIZE_BYTE + 1] = {};

        *data_len = sizeof(current_revision);
        memcpy(buf, &current_revision, *data_len);
        if (getNetworkData(reqptr->parameter, &buf[1], channel) == IPMI_CC_OK)
        {
            *data_len = sizeof(buf);
            memcpy(response, &buf, *data_len);
        }
    }
    else if (reqptr->parameter == LAN_PARM_IPSRC)
    {
        uint8_t buff[ipmi::network::IPSRC_SIZE_BYTE + 1] = {};
        *data_len = sizeof(current_revision);
        memcpy(buff, &current_revision, *data_len);
        if (getNetworkData(reqptr->parameter, &buff[1], channel) == IPMI_CC_OK)
        {
            *data_len = sizeof(buff);
            memcpy(response, &buff, *data_len);
        }
    }
    else if (reqptr->parameter == CIPHER_SUITE_COUNT)
    {
        *(static_cast<uint8_t*>(response)) = current_revision;
        // Byte 1 is reserved byte and does not indicate a cipher suite ID, so
        // no of cipher suite entry count is one less than the size of the
        // vector
        auto count = static_cast<uint8_t>(cipherList.size() - 1);
        *(static_cast<uint8_t*>(response) + 1) = count;
        *data_len = sizeof(current_revision) + sizeof(count);
    }
    else if (reqptr->parameter == CIPHER_SUITE_ENTRIES)
    {
        *(static_cast<uint8_t*>(response)) = current_revision;
        // Byte 1 is reserved
        std::copy_n(cipherList.data(), cipherList.size(),
                    static_cast<uint8_t*>(response) + 1);
        *data_len =
            sizeof(current_revision) + static_cast<uint8_t>(cipherList.size());
    }
    else
    {
        log<level::ERR>("Unsupported parameter",
                        entry("PARAMETER=0x%x", reqptr->parameter));
        rc = IPMI_CC_PARM_NOT_SUPPORTED;
    }

    return rc;
}

void applyChanges(int channel)
{
    std::string ipaddress;
    std::string gateway;
    uint8_t prefix{};
    uint32_t vlanID{};
    std::string networkInterfacePath;
    ipmi::DbusObjectInfo ipObject;
    ipmi::DbusObjectInfo systemObject;

    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
    if (ethdevice.empty())
    {
        log<level::ERR>("Unable to get the interface name",
                        entry("CHANNEL=%d", channel));
        return;
    }
    auto ethIp = ethdevice + "/" + ipmi::network::IP_TYPE;
    auto channelConf = getChannelConfig(channel);

    try
    {
        sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());

        log<level::INFO>("Network data from Cache",
                         entry("PREFIX=%s", channelConf->netmask.c_str()),
                         entry("ADDRESS=%s", channelConf->ipaddr.c_str()),
                         entry("GATEWAY=%s", channelConf->gateway.c_str()),
                         entry("VLAN=%d", channelConf->vlanID),
                         entry("IPSRC=%d", channelConf->ipsrc));
        if (channelConf->vlanID != ipmi::network::VLAN_ID_MASK)
        {
            // get the first twelve bits which is vlan id
            // not interested in rest of the bits.
            channelConf->vlanID = le32toh(channelConf->vlanID);
            vlanID = channelConf->vlanID & ipmi::network::VLAN_ID_MASK;
        }

        // if the asked ip src is DHCP then not interested in
        // any given data except vlan.
        if (channelConf->ipsrc != ipmi::network::IPOrigin::DHCP)
        {
            // always get the system object
            systemObject =
                ipmi::getDbusObject(bus, ipmi::network::SYSTEMCONFIG_INTERFACE,
                                    ipmi::network::ROOT);

            // the below code is to determine the mode of the interface
            // as the handling is same, if the system is configured with
            // DHCP or user has given all the data.
            try
            {
                ipmi::ObjectTree ancestorMap;

                ipmi::InterfaceList interfaces{
                    ipmi::network::ETHERNET_INTERFACE};

                // if the system is having ip object,then
                // get the IP object.
                ipObject = ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE,
                                             ipmi::network::ROOT, ethIp);

                // Get the parent interface of the IP object.
                try
                {
                    ancestorMap = ipmi::getAllAncestors(bus, ipObject.first,
                                                        std::move(interfaces));
                }
                catch (InternalFailure& e)
                {
                    // if unable to get the parent interface
                    // then commit the error and return.
                    log<level::ERR>("Unable to get the parent interface",
                                    entry("PATH=%s", ipObject.first.c_str()),
                                    entry("INTERFACE=%s",
                                          ipmi::network::ETHERNET_INTERFACE));
                    commit<InternalFailure>();
                    channelConf->clear();
                    return;
                }

                networkInterfacePath = ancestorMap.begin()->first;
            }
            catch (InternalFailure& e)
            {
                // TODO Currently IPMI supports single interface,need to handle
                // Multiple interface through
                // https://github.com/openbmc/openbmc/issues/2138

                // if there is no ip configured on the system,then
                // get the network interface object.
                auto networkInterfaceObject =
                    ipmi::getDbusObject(bus, ipmi::network::ETHERNET_INTERFACE,
                                        ipmi::network::ROOT, ethdevice);

                networkInterfacePath = std::move(networkInterfaceObject.first);
            }

            // get the configured mode on the system.
            auto enableDHCP =
                ipmi::getDbusProperty(
                    bus, ipmi::network::SERVICE, networkInterfacePath,
                    ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled")
                    .get<bool>();

            // if ip address source is not given then get the ip source mode
            // from the system so that it can be applied later.
            if (channelConf->ipsrc == ipmi::network::IPOrigin::UNSPECIFIED)
            {
                channelConf->ipsrc = (enableDHCP)
                                         ? ipmi::network::IPOrigin::DHCP
                                         : ipmi::network::IPOrigin::STATIC;
            }

            // check whether user has given all the data
            // or the configured system interface is dhcp enabled,
            // in both of the cases get the values from the cache.
            if ((!channelConf->ipaddr.empty() &&
                 !channelConf->netmask.empty() &&
                 !channelConf->gateway.empty()) ||
                (enableDHCP)) // configured system interface mode = DHCP
            {
                // convert mask into prefix
                ipaddress = channelConf->ipaddr;
                prefix = ipmi::network::toPrefix(AF_INET, channelConf->netmask);
                gateway = channelConf->gateway;
            }
            else // asked ip src = static and configured system src = static
                 // or partially given data.
            {
                // We have partial filled cache so get the remaining
                // info from the system.

                // Get the network data from the system as user has
                // not given all the data then use the data fetched from the
                // system but it is implementation dependent,IPMI spec doesn't
                // force it.

                // if system is not having any ip object don't throw error,
                try
                {
                    auto properties = ipmi::getAllDbusProperties(
                        bus, ipObject.second, ipObject.first,
                        ipmi::network::IP_INTERFACE);

                    ipaddress = channelConf->ipaddr.empty()
                                    ? properties["Address"].get<std::string>()
                                    : channelConf->ipaddr;

                    prefix = channelConf->netmask.empty()
                                 ? properties["PrefixLength"].get<uint8_t>()
                                 : ipmi::network::toPrefix(
                                       AF_INET, channelConf->netmask);
                }
                catch (InternalFailure& e)
                {
                    log<level::INFO>(
                        "Failed to get IP object which matches",
                        entry("INTERFACE=%s", ipmi::network::IP_INTERFACE),
                        entry("MATCH=%s", ethIp.c_str()));
                }

                auto systemProperties = ipmi::getAllDbusProperties(
                    bus, systemObject.second, systemObject.first,
                    ipmi::network::SYSTEMCONFIG_INTERFACE);

                gateway =
                    channelConf->gateway.empty()
                        ? systemProperties["DefaultGateway"].get<std::string>()
                        : channelConf->gateway;
            }
        }

        // Currently network manager doesn't support purging of all the
        // ip addresses and the vlan interfaces from the parent interface,
        // TODO once the support is there, will make the change here.
        // https://github.com/openbmc/openbmc/issues/2141.

        // TODO Currently IPMI supports single interface,need to handle
        // Multiple interface through
        // https://github.com/openbmc/openbmc/issues/2138

        // instead of deleting all the vlan interfaces and
        // all the ipv4 address,we will call reset method.
        // delete all the vlan interfaces

        ipmi::deleteAllDbusObjects(bus, ipmi::network::ROOT,
                                   ipmi::network::VLAN_INTERFACE);

        // set the interface mode  to static
        auto networkInterfaceObject =
            ipmi::getDbusObject(bus, ipmi::network::ETHERNET_INTERFACE,
                                ipmi::network::ROOT, ethdevice);

        // setting the physical interface mode to static.
        ipmi::setDbusProperty(
            bus, ipmi::network::SERVICE, networkInterfaceObject.first,
            ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled", false);

        networkInterfacePath = networkInterfaceObject.first;

        // delete all the ipv4 addresses
        ipmi::deleteAllDbusObjects(bus, ipmi::network::ROOT,
                                   ipmi::network::IP_INTERFACE, ethIp);

        if (vlanID)
        {
            ipmi::network::createVLAN(bus, ipmi::network::SERVICE,
                                      ipmi::network::ROOT, ethdevice, vlanID);

            auto networkInterfaceObject = ipmi::getDbusObject(
                bus, ipmi::network::VLAN_INTERFACE, ipmi::network::ROOT);

            networkInterfacePath = networkInterfaceObject.first;
        }

        if (channelConf->ipsrc == ipmi::network::IPOrigin::DHCP)
        {
            ipmi::setDbusProperty(
                bus, ipmi::network::SERVICE, networkInterfacePath,
                ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled", true);
        }
        else
        {
            // change the mode to static
            ipmi::setDbusProperty(
                bus, ipmi::network::SERVICE, networkInterfacePath,
                ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled", false);

            if (!ipaddress.empty())
            {
                ipmi::network::createIP(bus, ipmi::network::SERVICE,
                                        networkInterfacePath, ipv4Protocol,
                                        ipaddress, prefix);
            }

            if (!gateway.empty())
            {
                ipmi::setDbusProperty(bus, systemObject.second,
                                      systemObject.first,
                                      ipmi::network::SYSTEMCONFIG_INTERFACE,
                                      "DefaultGateway", std::string(gateway));
            }
        }
    }
    catch (InternalFailure& e)
    {
        log<level::ERR>(
            "Failed to set network data", entry("PREFIX=%d", prefix),
            entry("ADDRESS=%s", ipaddress.c_str()),
            entry("GATEWAY=%s", gateway.c_str()), entry("VLANID=%d", vlanID),
            entry("IPSRC=%d", channelConf->ipsrc));

        commit<InternalFailure>();
    }

    channelConf->clear();
}

void commitNetworkChanges()
{
    for (const auto& channel : channelConfig)
    {
        if (channel.second->flush)
        {
            applyChanges(channel.first);
        }
    }
}

void createNetworkTimer()
{
    if (!networkTimer)
    {
        std::function<void()> networkTimerCallback(
            std::bind(&commitNetworkChanges));

        networkTimer = std::make_unique<phosphor::ipmi::Timer>(
            ipmid_get_sd_event_connection(), networkTimerCallback);
    }
}

void register_netfn_transport_functions()
{
    // As this timer is only for transport handler
    // so creating it here.
    createNetworkTimer();
    // <Wildcard Command>
    ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_WILDCARD, NULL,
                           ipmi_transport_wildcard, PRIVILEGE_USER);

    // <Set LAN Configuration Parameters>
    ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_SET_LAN, NULL,
                           ipmi_transport_set_lan, PRIVILEGE_ADMIN);

    // <Get LAN Configuration Parameters>
    ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_GET_LAN, NULL,
                           ipmi_transport_get_lan, PRIVILEGE_OPERATOR);

    return;
}
