/*****************************************************************
 *****************************************************************
 ***                                                            **
 ***    (C)Copyright 2005-2006, American Megatrends Inc.        **
 ***                                                            **
 ***            All Rights Reserved.                            **
 ***                                                            **
 ***        6145-F, Northbelt Parkway, Norcross,                **
 ***                                                            **
 ***        Georgia - 30071, USA. Phone-(770)-246-8600.         **
 ***                                                            **
 *****************************************************************
 *****************************************************************
 *
 * AMIConf.c
 * AMI specific configuration commands related implementation.
 *
 * Author: Benson Chuang <bensonchuang@ami.com.tw>
 *****************************************************************/

#include "Debug.h"
#include "Support.h"
#include "IPMIDefs.h"
#include "AMIRestoreDefaults.h"
#include "flshfiles.h"
#include "flashlib.h"
#include "PendTask.h"
#include <sys/reboot.h>
#include <linux/reboot.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <linux/if.h>
//#include "OSPort.h"
#include "NVRData.h"
#include "NVRAccess.h"
#include "PMConfig.h"
#include "IPMI_AMIConf.h"
#include "AMIConf.h"
#include "nwcfg.h"
#include "Ethaddr.h"
#include "MsgHndlr.h"
#include "ncml.h"
//#include "IPMIConf.h"
#include "hostname.h"
#include <dlfcn.h>
#include "stunnel_cfg.h"
#include "unix.h"
#include "Sensor.h"
#include "SDR.h"
#include <flashlib.h>
#include "featuredef.h"
#include "SEL.h"
#include "blowfish.h"
#include "vmedia_cfg.h"
#include <netdb.h>
#include "AppDevice.h"
#include "userprivilege.h"
#include "Extendedpriv.h"
#include "Platform.h"
#include "safesystem.h"
#include "LANConfig.h"
#include "bmc_type.h"

#define MAX_FULL_SEL_ENTRIES 0x4000

#define SNMP_LIBS "/usr/local/lib/libsnmpusers.so"
#define RMS_SET  "rms_set"
#define DNS_PARAM_LENGTH 0x6
/*
 * Service commands
 */
char *ServiceNameList[MAX_SERVICE_NUM] = { 
                                              WEB_SERVICE_NAME,    
                                              KVM_SERVICE_NAME,    
                                              CDMEDIA_SERVICE_NAME,
                                              FDMEDIA_SERVICE_NAME,
                                              HDMEDIA_SERVICE_NAME,
                                              SSH_SERVICE_NAME,    
                                              TELNET_SERVICE_NAME,
                                              SOLSSH_SERVICE_NAME,
                                          };


/**
 * @brief IPTABLES Firewall configuration request parameter lengths
**/
static const INT8U FirewallConfigParamLength [] = {
					4+1,  /* IP Address block*/
					8+1,  /* IP Address Range block*/
                    2+1+1,  /* Port No block*/
                    4+1+1,  /* Port Range block*/
					4+1,  /* IP Address unblock*/
					8+1,  /* IP Address Range unblock*/
                    2+1+1,  /* Port No unblock*/
                    4+1+1,  /* Port Range unblock*/                    
                    0,	/* Flushing iptables */
                    1+1,	/* Block all */
                    1+1,  /* remove Block all */
                                       
};

/**
 * @brief IPTABLES Get Firewall configuration request parameter lengths
**/
static const INT8U GetFirewallConfigParamLength [] = {
					0,  /* Get No Of Entries*/
					1,  /* Get A Entry Info */
};

/*
 * @brief Network Interface Configuration request parameter length
 */
static const INT8U NwIfcStateConfigParamLenght [] = {
                            2, /*Eth Interface*/
                            7, /*Bond Interface*/
};

/*
 * @brief DNS configuration Request parameter length
 */
static const INT8U NwDNSConfigParamLength[] = {
                            66,
                            0xFF,
                            4,
                            64,
                            3,
};

/**
 * @brief UDS Session Information request parameter lengths
**/
static const INT8U UDSSessionInfoParamLength[]={
                                1,
                                5,
                                2,
                                2,
                                5,
                                2,
                                1,
};

/*
 * RIS Configuration commands
 */
char *ServiceList[4] = {
                              RMS_CD_SECTION_NAME,
                              RMS_FD_SECTION_NAME,
                              RMS_HD_SECTION_NAME,
                              RMS_SET,
};
/*
 * RIS Configuration commands length
 */
static const INT8U ServiceLen[] = {
                              3,
                              3,
                              3,
                              2,
};
/**
 * @brief RIS Configuration commands request parameter lengths
**/
static const INT32U ServiceParamLength [] = {
                              64,  /*Image Name Length */
                              64,  /* Shared Path length*/
                              63,  /* IP Address Range block*/
                              64,  /* User Name*/
                              32,  /* Password*/
                              6,   /* share Type */
                              64,  /* Domain name*/
};

/**
 * @brief RIS media selection
**/
static const INT8U ServiceParam[] = {
                              1,/*CD MEDIA */
                              2,  /* FD MEDIA*/
                              4,  /* HD MEDIA*/
 };

//extern IfcName_T Ifcnametable[MAX_LAN_CHANNELS];
/*
 * DNS related commands
 */

INT8U CheckSlaveVLANInterface(INT8U Slaves, INT8U *VLANID, int BMCInst)
{
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    char IfcName[16];
    int i, j, isFirstIndex = 1;
    
    if (VLANID == NULL)
        return (CC_UNSPECIFIED_ERR);
        
    (*VLANID) = 0;
    /*Check Slaves Entry*/
    for(i = 0; i < BOND_MAX_SLAVE; i++)
    {
        if( (Slaves >> i) & IFACE_ENABLED)
        {
            if(CheckIfcEntry( i, ETH_IFACE_TYPE) != 0)
            {
                IPMI_WARNING("Slave Entry %d is not presented in interface table\n",i);
                return (CC_INV_DATA_FIELD);
            }
            
            memset(IfcName, 0, sizeof(IfcName));
            sprintf(IfcName,"eth%d", i);
            
            for(j = 0; j < sizeof(pBMCInfo->LanIfcConfig)/sizeof(LANIFCConfig_T); j++)
            {
                if(strcmp(IfcName, pBMCInfo->LanIfcConfig[j].ifname) == 0)
                {
                    TDBG ("VLANID for %s : %d\n", IfcName, pBMCInfo->LANConfig.VLANID[j]);
                    if (isFirstIndex == 1)
                    {
                        (*VLANID) = pBMCInfo->LANConfig.VLANID[j];
                        isFirstIndex = 0;
                    }
                    else
                    {
                        if(pBMCInfo->LANConfig.VLANID[j] != (*VLANID))
                        {
                            return OEMCC_VLAN_ENABLED_ON_SLAVE;
                        }
                    }
                }
            }
        }
    }
    return 0;
}

/*
 @fn CheckVLANInterface
 @brief This function is used to check VLAN interface presence
 @params Ifcname[in] - interface name BMCInst[in] BMC instance
 @returns 1 on VLAN Enabled, 0 on VLAN Disabled
 */
int CheckVLANInterface(char* Ifcname,int BMCInst)
{
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    int i;

    for(i=0;i<sizeof(pBMCInfo->LanIfcConfig)/sizeof(LANIFCConfig_T);i++)
    {
        if(strcmp(Ifcname,pBMCInfo->LanIfcConfig[i].ifname) == 0)
        {
            if(pBMCInfo->LANConfig.VLANID[i] != 0)
                return 1;
        }
    }

    return 0;
}

/*
 @fn ValidateDomainName
 @brief This function is used to validate the DNS Domain Name
 @params hostname - Domain Name to be validated
 @returns 1 on valid domain name , 0 on invalid domain name
 */
int ValidateDomainName(const char *hostname)
{
    int   count = 0;
    const char *c, *domain;
    static char *invaliddomainname = "()<>@,;:\\\"[]";
	
    /* Here we validate the domain*/
    if (!*(domain = c = hostname))
        return 0;
	
    do
    {
	  if (*c == '.')
	  {
		if (c == domain || *(c - 1) == '.')
			return 0;
		count++;
	  }
	  if (*c <= ' ' || *c >= 127)
		  return 0;
	
	  if (strchr(invaliddomainname, *c))
		  return 0;
    } while (*++c);
	
    return (count >= 1);
}

/*
 @fn ValidateDNSReqInfo
 @brief This function is used to validate the DNS Request params DomainIndex and Domainpriority depending on DomainDHCP
 @params DomainDHCP - Domain DHCP/static
 @params DomainIndex - Domain Index
 @params Domainpriority - Domain Prioriry IPV4/IPV6 
 @returns  0 on valid set DNS conf requested, others - error codes
 */
int ValidateDNSReqInfo(INT8U DomainDHCP, INT8U DomainIndex, INT8U Domainpriority)
{
	int Ifccount=0,retValue,ifcslaved=0,i;
	if(DomainDHCP)
	{
            Ifccount = g_coremacros.global_nic_count;
	    if(g_corefeatures.bond_support == ENABLED)
	    {
		for(i = 0; i < Ifccount; i++)    // loop to check if bonding is configured
		{
	            retValue = -1;
		    retValue = CheckBondSlave(i);
		    if(retValue == -1)
		    {
			return CC_UNSPECIFIED_ERR;
		    }
				  
		    if(retValue == 1)
		    {
			ifcslaved = 1;
			if(i == DomainIndex)
			{
		            return CC_IFC_ALREADY_SLAVEDTO_BOND;
			}
			break;
		    }

		    if(retValue != 0)
    		    {
    		        TDBG("Error in reading network configuration.\n");	 
    		        return CC_UNSPECIFIED_ERR;
    		    }
		}
	    }

	    switch(ifcslaved)
	    {
		case BONDING_ACTIVE:
			if(Domainpriority != 1)  // Currently IPV6 is not supported for Bonding, so filtering IPV6 request
			{
			  return CC_DNS_CURRENTLY_NOT_SUPPORTED_FOR_IPV6;
			}
			break;
		case BONDING_NOTACTIVE:
			for(i=0;i<(sizeof(Ifcnametable)/sizeof(Ifcnametable[0]));i++)
			{
	                    if(strstr(Ifcnametable[i].Ifcname,"bond"))
			    {
				if(Ifcnametable[i].Index == DomainIndex)
				{
	                            return CC_INV_DATA_FIELD;							
				}
			    }
			}
			if((Domainpriority != 1) && (Domainpriority != 2)) // filter domain priorities other then ipv4 and ipv6
			{
			    return CC_INV_DATA_FIELD;
			}
			break;
		default:
			TCRIT("Unable to read the interface state of bonding\n");					
	    }
	}
	else
	{
		if(DomainIndex || Domainpriority)
		{
			return  CC_INV_DATA_FIELD;
		}
	}
	return 0;
}

int
AMIGetDNSConf( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMIGetDNSConfReq_T* pAMIGetDNSConfReq = (_NEAR_ AMIGetDNSConfReq_T*) pReq;
    _NEAR_  AMIGetDNSConfRes_T*  pAMIGetDNSConfRes = (_NEAR_ AMIGetDNSConfRes_T*) pRes;
    HOSTNAMECONF HostnameConfig;
    DOMAINCONF DomainConfig;
    DNSCONF DnsIPConfig;
    INT8U regBMC_FQDN[MAX_LAN_CHANNELS];
    INT8U Ifccount;

    memset(&HostnameConfig, 0, sizeof(HostnameConfig));
    memset(&DomainConfig, 0, sizeof(DomainConfig));
    memset(&DnsIPConfig, 0, sizeof(DnsIPConfig));
    memset(regBMC_FQDN, 0, sizeof(regBMC_FQDN));

    /*Validate the Block selector*/
    if( 0 != pAMIGetDNSConfReq->Blockselect 
                && (pAMIGetDNSConfReq->Param != AMI_DNS_CONF_DOMAIN_NAME )
                && (pAMIGetDNSConfReq->Param != AMI_DNS_CONF_DNS_IP))
    {
        *pRes = CC_INV_DATA_FIELD;
        return sizeof(INT8U);
    }

    nwGetAllDNSConf( &HostnameConfig, &DomainConfig, &DnsIPConfig,regBMC_FQDN );
    pAMIGetDNSConfRes->CompletionCode = CC_SUCCESS;

    switch(pAMIGetDNSConfReq->Param)
    {
        case AMI_DNS_CONF_HOST_NAME:
            memset(&pAMIGetDNSConfRes->DNSCfg.HName,0,sizeof(HOSTNAMECONF));
            pAMIGetDNSConfRes->DNSCfg.HName.HostSetting = HostnameConfig.HostSetting;
            pAMIGetDNSConfRes->DNSCfg.HName.HostNameLen= HostnameConfig.HostNameLen;
            memcpy(pAMIGetDNSConfRes->DNSCfg.HName.HostName,HostnameConfig.HostName,HostnameConfig.HostNameLen);
            return sizeof(INT8U) + sizeof(HOSTNAMECONF);

            break;
        case AMI_DNS_CONF_REGISTER:
	    if(g_corefeatures.bond_support == ENABLED)
	    {
		 Ifccount = g_coremacros.global_nic_count + 1; //count for bond interface
	    }
	    else
	    {
		  Ifccount = g_coremacros.global_nic_count;
	    }

            memcpy(pAMIGetDNSConfRes->DNSCfg.RegDNSConf,regBMC_FQDN,Ifccount);
            return sizeof(INT8U) + Ifccount;

            break;
        case AMI_DNS_CONF_DOMAIN_SETTINGS:

            pAMIGetDNSConfRes->DNSCfg.DomainConf.DomainDHCP = DomainConfig.dhcpEnable;
            pAMIGetDNSConfRes->DNSCfg.DomainConf.DomainIndex = DomainConfig.EthIndex;
            pAMIGetDNSConfRes->DNSCfg.DomainConf.Domainpriority= DomainConfig.v4v6;
            pAMIGetDNSConfRes->DNSCfg.DomainConf.DomainLen= DomainConfig.domainnamelen;

            return sizeof(INT8U) + sizeof(DomainSetting);

            break;
        case AMI_DNS_CONF_DOMAIN_NAME:

            if(pAMIGetDNSConfReq->Blockselect > MAX_BLOCK || pAMIGetDNSConfReq->Blockselect == 0)
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            memcpy(pAMIGetDNSConfRes->DNSCfg.DomainName,&DomainConfig.domainname[MAX_DOMAIN_BLOCK_SIZE * (pAMIGetDNSConfReq->Blockselect -1)],MAX_DOMAIN_BLOCK_SIZE);
            return sizeof(INT8U) + MAX_DOMAIN_BLOCK_SIZE;
            break;

        case AMI_DNS_CONF_DNS_SETTING:
            pAMIGetDNSConfRes->DNSCfg.DNSConf.IPPriority = DnsIPConfig.IPPriority;
            pAMIGetDNSConfRes->DNSCfg.DNSConf.DNSDHCP = DnsIPConfig.DNSDHCP;
            pAMIGetDNSConfRes->DNSCfg.DNSConf.DNSIndex = DnsIPConfig.DNSIndex;
            return sizeof(INT8U) + sizeof(DNSSetting);
            break;

        case AMI_DNS_CONF_DNS_IP:
            if(pAMIGetDNSConfReq->Blockselect == 1)
            {
                if(IN6_IS_ADDR_V4MAPPED(&DnsIPConfig.DNSIP1))
                {
                    memcpy(pAMIGetDNSConfRes->DNSCfg.DNSIPAddr,&DnsIPConfig.DNSIP1[IP6_ADDR_LEN - IP_ADDR_LEN],IP_ADDR_LEN);
                    return sizeof(INT8U) + IP_ADDR_LEN;
                }
                else
                {
                    memcpy(pAMIGetDNSConfRes->DNSCfg.DNSIPAddr,DnsIPConfig.DNSIP1,IP6_ADDR_LEN);
                    return sizeof(INT8U) + IP6_ADDR_LEN;
                }
            }
            else if(pAMIGetDNSConfReq->Blockselect == 2)
            {
                if(IN6_IS_ADDR_V4MAPPED(&DnsIPConfig.DNSIP2))
                {
                    memcpy(pAMIGetDNSConfRes->DNSCfg.DNSIPAddr,&DnsIPConfig.DNSIP2[IP6_ADDR_LEN - IP_ADDR_LEN],IP_ADDR_LEN);
                    return sizeof(INT8U) + IP_ADDR_LEN;
                }
                else
                {
                    memcpy(pAMIGetDNSConfRes->DNSCfg.DNSIPAddr,DnsIPConfig.DNSIP2,IP6_ADDR_LEN);
                    return sizeof(INT8U) + IP6_ADDR_LEN;
                }
            }
            else if(pAMIGetDNSConfReq->Blockselect == 3)
            {
                if(IN6_IS_ADDR_V4MAPPED(&DnsIPConfig.DNSIP3))
                {
                    memcpy(pAMIGetDNSConfRes->DNSCfg.DNSIPAddr,&DnsIPConfig.DNSIP3[IP6_ADDR_LEN - IP_ADDR_LEN],IP_ADDR_LEN);
                    return sizeof(INT8U) + IP_ADDR_LEN;
                }
                else
                {
                    memcpy(pAMIGetDNSConfRes->DNSCfg.DNSIPAddr,DnsIPConfig.DNSIP3,IP6_ADDR_LEN);
                    return sizeof(INT8U) + IP6_ADDR_LEN;
                }
            }
            else
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            break;
        case AMI_DNS_CONF_DNS_RESTART:
            *pRes = OEMCC_ATTEMPT_TO_GET_WO_PARAM;
            return sizeof(INT8U);
            break;

        case AMI_DNS_CONF_DNS_ENABLE:
            pAMIGetDNSConfRes->DNSCfg.DNSEnable = DnsIPConfig.DNSEnable;
            return sizeof(INT8U) + sizeof(INT8U);
            break;

        default:
            *pRes = CC_PARAM_NOT_SUPPORTED;
            return sizeof(INT8U);
            break;
    }

    return(sizeof(AMIGetDNSConfRes_T));
}


int
AMISetDNSConf( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_ AMISetDNSConfRes_T *pAMISetDNSConfRes = (_NEAR_ AMISetDNSConfRes_T *)pRes;
    _NEAR_ AMISetDNSConfReq_T *pAMISetDNSConfReq = (_NEAR_ AMISetDNSConfReq_T*)pReq;
//        _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    int i,domainnamelength=0;
    INT8U Ifccount, retValue, ifcslaved=0,status=-1,*curchannel;
    char *ptr = NULL;

    UINT8 reservedBit = REG_BMC_RESERVED;
    int sizeWritten = 0;
    FILE *fp = NULL;
    char tsigprivate[255] = {0};

    if(ReqLen >= 2)
    {
        ReqLen -= 2;
    }
    else
    {
        *pRes = CC_REQ_INV_LEN;
        return sizeof(INT8U);
    }

    if(g_corefeatures.online_flashing_support == ENABLED)
    {
        if(IsCardInFlashMode())
        {
            IPMI_WARNING("Card in Active flash mode, Not safe to set any of network configurations...\n");
            *pRes = CC_DEV_IN_FIRMWARE_UPDATE_MODE;
            return sizeof(INT8U);
        }
    }
    if(DNS_PARAM_LENGTH > pAMISetDNSConfReq->ParamSelect)
    {
        if( (ReqLen != NwDNSConfigParamLength[pAMISetDNSConfReq->ParamSelect - 1])
                && ((NwDNSConfigParamLength[pAMISetDNSConfReq->ParamSelect - 1])!=0xFF) )   
        {
            TDBG("ReqLen %ld\n",ReqLen);
            *pRes = CC_REQ_INV_LEN;
            return sizeof(INT8U);
        }
    }

    /*Validate the Block selector*/
    if( 0 != pAMISetDNSConfReq->Blockselector
                && (pAMISetDNSConfReq->ParamSelect != AMI_DNS_CONF_DOMAIN_NAME )
                && (pAMISetDNSConfReq->ParamSelect != AMI_DNS_CONF_DNS_IP))
    {
        *pRes = CC_INV_DATA_FIELD;
        return sizeof(INT8U);
    }

    switch(pAMISetDNSConfReq->ParamSelect)
    {
        case AMI_DNS_CONF_HOST_NAME:
            /*Reserved bit checking*/
            if(pAMISetDNSConfReq->DnsConfig.HName.HostSetting > 0x1)
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            /*Check the Maximum host name length i.e user can send 63 bytes and last one is null character*/
            if(pAMISetDNSConfReq->DnsConfig.HName.HostNameLen > MAX_HOSTNAME_LEN - 1)
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            TDBG("HostName Setting %d and Length %d\n",pAMISetDNSConfReq->DnsConfig.HName.HostSetting,pAMISetDNSConfReq->DnsConfig.HName.HostNameLen);
            LOCK_BMC_SHARED_MEM(BMCInst);
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.HostSetting = pAMISetDNSConfReq->DnsConfig.HName.HostSetting;
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.HostNameLen = pAMISetDNSConfReq->DnsConfig.HName.HostNameLen;
            memcpy(BMC_GET_SHARED_MEM (BMCInst)->DNSconf.HostName,pAMISetDNSConfReq->DnsConfig.HName.HostName,pAMISetDNSConfReq->DnsConfig.HName.HostNameLen);
            UNLOCK_BMC_SHARED_MEM(BMCInst);

            break;

        case AMI_DNS_CONF_REGISTER:
        	
            /*Added the validation to check the request data when the NIC count is 2. This check will be removed once we support 4 NIC*/	
            if((g_coremacros.global_nic_count < MAX_LAN_CHANNELS) && (ReqLen!=3))
            {
                 *pRes = CC_REQ_INV_LEN ;
                 return sizeof(INT8U);
            }

            // Allow setting this parameter only if DNS Service is enabled
            if(BMC_GET_SHARED_MEM(BMCInst)->DNSconf.DNSEnable == 0)
            {
                TCRIT("DNS is currently disabled. Dissallowing to set the dns configurations...\n");
                *pRes = CC_DNS_CURRENTLY_NOT_ENABLED;
                return sizeof(INT8U);
            }
           if(g_corefeatures.bond_support == ENABLED)
           {
                if(g_coremacros.global_nic_count < MAX_LAN_CHANNELS)
                Ifccount = g_coremacros.global_nic_count + 1; //count for bond interface
                else
                Ifccount = g_coremacros.global_nic_count; // for  4 NIC supported BMC

                for(i = 0; i < Ifccount; i++)
                {
                     retValue = -1;
                     retValue = CheckBondSlave(i);

                    if(retValue == -1)
                    {
                        *pRes = CC_UNSPECIFIED_ERR;
                        return sizeof(INT8U);
                    }
                    if(retValue == 1)
                    {
                        ifcslaved = 1;
                        if(pAMISetDNSConfReq->DnsConfig.RegDNSConf[i])
                        {
                             *pRes = CC_IFC_ALREADY_SLAVEDTO_BOND;
                             return sizeof(INT8U);
                        }
                    }
                    if(retValue != 0)
                        TDBG("Error in reading network configuration.\n");	  

                    if((i == (Ifccount-1)) && (ifcslaved == 0))
                    {
                         if( Ifccount != MAX_LAN_CHANNELS)
                         {
                             if (pAMISetDNSConfReq->DnsConfig.RegDNSConf[g_coremacros.global_nic_count])
                             {
                                 TDBG("Attempted to set DNS Conf for Bonding Interface, which is inactive\n");
                                 *pRes = CC_BOND_DISABLED_TOCONF_DNS;
                                 return sizeof(INT8U);
                             }
                         } 
                    }
                }
            }
            else
            {
                 Ifccount = g_coremacros.global_nic_count;
                 if(Ifccount < MAX_LAN_CHANNELS)
                 {
                      if (pAMISetDNSConfReq->DnsConfig.RegDNSConf[Ifccount])
                      {
                           TDBG("Attempted to set DNS Conf for Bonding Interface, which is inactive\n");
                           *pRes = CC_BOND_DISABLED_TOCONF_DNS;
                           return sizeof(INT8U);
                      }
                  }
            }

            if (g_corefeatures.tsig_support == ENABLED) {
                reservedBit = reservedBit & REG_BMC_RESERVED_TSIG;
            }

            for(i = 0; i < Ifccount; i++)
            {
                if(pAMISetDNSConfReq->DnsConfig.RegDNSConf[i] & reservedBit)
                {
                     TDBG("Register value %d\n",pAMISetDNSConfReq->DnsConfig.RegDNSConf[i]);
                     *pRes = CC_INV_DATA_FIELD;
                     return sizeof(INT8U);
                }
                if (((pAMISetDNSConfReq->DnsConfig.RegDNSConf[i] & REG_BMC_FQDN) == REG_BMC_FQDN) &&
                    ((pAMISetDNSConfReq->DnsConfig.RegDNSConf[i] & REG_BMC_TSIG) == REG_BMC_TSIG))
                {
                    TCRIT("TSIG can't be enabled with FQDN support");
                    *pRes = CC_INV_DATA_FIELD;
                    return sizeof(INT8U);
                }
                if(((pAMISetDNSConfReq->DnsConfig.RegDNSConf[i] & REG_BMC_FQDN) == REG_BMC_FQDN) &&
                    ((pAMISetDNSConfReq->DnsConfig.RegDNSConf[i] & REG_BMC_HOSTNAME) == REG_BMC_HOSTNAME))
                {
                    TCRIT("AMISetDNSConf(): Enabling both FQDN and Hostname options is not allowable as these are options of DHCP");
                    *pRes = CC_INV_DATA_FIELD;
                    return sizeof(INT8U);
                }
            }

            TDBG("DNS Register Settings %d %d %d\n",pAMISetDNSConfReq->DnsConfig.RegDNSConf[0],pAMISetDNSConfReq->DnsConfig.RegDNSConf[1],pAMISetDNSConfReq->DnsConfig.RegDNSConf[2]);
            LOCK_BMC_SHARED_MEM(BMCInst);
            memcpy(BMC_GET_SHARED_MEM (BMCInst)->DNSconf.RegisterBMC,pAMISetDNSConfReq->DnsConfig.RegDNSConf,Ifccount);
            UNLOCK_BMC_SHARED_MEM(BMCInst);
            break;

        case AMI_DNS_CONF_TSIG_UPLOAD:
            if (g_corefeatures.tsig_support == ENABLED) {
                /* Check Requested Length */
                if ((ReqLen > MAX_TSIG_PRIVKEY_SIZE) || (ReqLen <= 0))
                {
                    TCRIT("Invalid Request Length\n");
                    *pRes = CC_REQ_INV_LEN;
                    return sizeof(INT8U);
                }
                fp = fopen(TEMP_TSIG_PRIVATE_FILE, "wb");
                if (fp == NULL)
                {
                    TCRIT("Error in Opening File\n");
                    *pRes = CC_UNSPECIFIED_ERR;
                    return sizeof(INT8U);
                }
                sizeWritten = fwrite(&pAMISetDNSConfReq->DnsConfig.PrivateKey[0], 1, ReqLen, fp);
                if (sizeWritten != ReqLen)
                {
                    TCRIT("Error in writing into the file\n");
                    fclose(fp);
                    *pRes = CC_UNSPECIFIED_ERR;
                    return sizeof(INT8U);
                }
                fclose(fp);
                /* Now Open the File for validation */
                fp = fopen(TEMP_TSIG_PRIVATE_FILE, "rb");
                if(fp == NULL)
                {
                    TCRIT("Error in Opening File\n");
                    unlink(TEMP_TSIG_PRIVATE_FILE);
                    *pRes = CC_UNSPECIFIED_ERR;
                    return sizeof(INT8U);
                }
                //HMAC-MD5 Algorithm type check
                ptr = fgets(tsigprivate, sizeof(tsigprivate)-1, fp);//read 1st line
                ptr = fgets(tsigprivate, sizeof(tsigprivate)-1, fp);

                if (strcmp(tsigprivate, TSIG_ALG_TYPE_HMAC_MD5) != 0)
                {
                    TCRIT("The private key's algorithm is not HMAC-MD5.");
                    fclose(fp);
                    unlink(TEMP_TSIG_PRIVATE_FILE);
                    *pRes = CC_TSIGPRIVATEKEY_VALIDATION_FAILED;
                    return sizeof(INT8U);
                }
                fclose(fp);
                if(moveFile(TEMP_TSIG_PRIVATE_FILE, CONF_TSIG_PRIVATE_FILE) != 0)
                {
                    TCRIT("Error in moving TSIG private key file.");
                    *pRes = CC_UNSPECIFIED_ERR;
                    return sizeof(INT8U);
                }
            }
            else
            {
                *pRes = CC_PARAM_NOT_SUPPORTED;
                return sizeof(INT8U);
            }
        break;

        case AMI_DNS_CONF_DOMAIN_SETTINGS:

            /*Check the reserve bit*/
            if(pAMISetDNSConfReq->DnsConfig.DomainConf.DomainDHCP > 1)
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            status = ValidateDNSReqInfo(pAMISetDNSConfReq->DnsConfig.DomainConf.DomainDHCP, pAMISetDNSConfReq->DnsConfig.DomainConf.DomainIndex,pAMISetDNSConfReq->DnsConfig.DomainConf.Domainpriority);
	    if(status !=0)
	    {
	        *pRes = status;
		return sizeof(INT8U);
	    }
            TDBG("Domain DHCP %d\nDomainIndex %d\nDomainLen %d\nDomainpriority%d\n",
                                                                                    pAMISetDNSConfReq->DnsConfig.DomainConf.DomainDHCP,
                                                                                    pAMISetDNSConfReq->DnsConfig.DomainConf.DomainIndex,
                                                                                    pAMISetDNSConfReq->DnsConfig.DomainConf.DomainLen,
                                                                                    pAMISetDNSConfReq->DnsConfig.DomainConf.Domainpriority);
            LOCK_BMC_SHARED_MEM(BMCInst);
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainDHCP = pAMISetDNSConfReq->DnsConfig.DomainConf.DomainDHCP;
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainIndex = pAMISetDNSConfReq->DnsConfig.DomainConf.DomainIndex;
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainLen = pAMISetDNSConfReq->DnsConfig.DomainConf.DomainLen;
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.Domainpriority = pAMISetDNSConfReq->DnsConfig.DomainConf.Domainpriority;
            UNLOCK_BMC_SHARED_MEM(BMCInst);

            break;
        case AMI_DNS_CONF_DOMAIN_NAME:

            if( pAMISetDNSConfReq->Blockselector == 0x0 || pAMISetDNSConfReq->Blockselector > MAX_BLOCK)
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
		    }
			ptr = malloc(sizeof(BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName));
			domainnamelength = sizeof(BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName);
			strncpy(ptr ,(char *)BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName, domainnamelength);
                        LOCK_BMC_SHARED_MEM(BMCInst);
			if(pAMISetDNSConfReq->Blockselector == 0x01)
				memset(&BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName,0,(MAX_BLOCK * MAX_DOMAIN_BLOCK_SIZE));
		
                        memcpy(&BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName[ MAX_DOMAIN_BLOCK_SIZE * (pAMISetDNSConfReq->Blockselector - 1)],pAMISetDNSConfReq->DnsConfig.DomainName,MAX_DOMAIN_BLOCK_SIZE);
                        // Validate the Domain Name if the domain name is of length DomainLen, which is set by user
			if(strlen((char *)BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName) >= BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainLen)
			{
				if((ValidateDomainName((char *)BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName)) == INVALID_DOMAIN_NAME)
				{
					strncpy((char *)BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName, ptr, domainnamelength);
					UNLOCK_BMC_SHARED_MEM(BMCInst);
					free(ptr);
					ptr = NULL;
					TDBG("Validating Domain name has fialed\n");
	                                *pRes = CC_INV_DOMAIN_NAME;
	                                return sizeof(INT8U);
				}
			}
			else if(strlen((char *)BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName) > BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainLen)
		        { 
     		            strncpy((char *)BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DomainName, ptr, domainnamelength);
			    UNLOCK_BMC_SHARED_MEM(BMCInst);
			    free(ptr);
			    ptr = NULL;
			    TDBG("Domain Name Length is Greater than the preset param DomainLen(set for Domain Name)\n");
                            *pRes = CC_INV_DATA_FIELD;
                            return sizeof(INT8U);
                        }
                        UNLOCK_BMC_SHARED_MEM(BMCInst);
			
			free(ptr);
			ptr = NULL;

            break;

        case AMI_DNS_CONF_DNS_SETTING:
            /*Check the reserve bits*/
            if((pAMISetDNSConfReq->DnsConfig.DNSConf.DNSDHCP > 1) || (pAMISetDNSConfReq->DnsConfig.DNSConf.IPPriority > 2))
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            status = ValidateDNSReqInfo(pAMISetDNSConfReq->DnsConfig.DNSConf.DNSDHCP, pAMISetDNSConfReq->DnsConfig.DNSConf.DNSIndex, pAMISetDNSConfReq->DnsConfig.DNSConf.IPPriority);
	    if(status !=0)
	    {
		*pRes = status;
		return sizeof(INT8U);
	    }

            TDBG("IPPriority %d\n",pAMISetDNSConfReq->DnsConfig.DNSConf.IPPriority);
            LOCK_BMC_SHARED_MEM(BMCInst);
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.IPPriority = pAMISetDNSConfReq->DnsConfig.DNSConf.IPPriority;
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSDHCP = pAMISetDNSConfReq->DnsConfig.DNSConf.DNSDHCP;
            BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIndex = pAMISetDNSConfReq->DnsConfig.DNSConf.DNSIndex;
            UNLOCK_BMC_SHARED_MEM(BMCInst);


            break;
        case AMI_DNS_CONF_DNS_IP:

            if( pAMISetDNSConfReq->Blockselector == 0x0 || pAMISetDNSConfReq->Blockselector > MAX_DNS_IP_ADDRESS)
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            if((ReqLen != IP_ADDR_LEN) && (ReqLen != IP6_ADDR_LEN))
            {
                TDBG("Reqlen %ld\n",ReqLen);
                *pRes = CC_REQ_INV_LEN;
                return sizeof(INT8U);
            }

			/*Validate the IPv6 address*/
            if(ReqLen == IP6_ADDR_LEN && 0 != IsValidGlobalIPv6Addr((struct in6_addr*)&pAMISetDNSConfReq->DnsConfig.DNSIPAddr))
            {
                TCRIT("Invalid Global IPv6 Address\n");
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            TDBG("Block Selector %d\n",pAMISetDNSConfReq->Blockselector);
            LOCK_BMC_SHARED_MEM(BMCInst);
            if(pAMISetDNSConfReq->Blockselector == 1)
            {
                memset(&BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr1,0,IP6_ADDR_LEN);
                if(ReqLen == IP_ADDR_LEN)
                {
                    BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr1[10] = 0xFF;
                    BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr1[11] = 0xFF;
                    memcpy(&BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr1[12],pAMISetDNSConfReq->DnsConfig.DNSIPAddr,ReqLen);
                    TDBG("DNS ipv4 address %d %d %d %d\n",pAMISetDNSConfReq->DnsConfig.DNSIPAddr[0],pAMISetDNSConfReq->DnsConfig.DNSIPAddr[1],
                                                                                    pAMISetDNSConfReq->DnsConfig.DNSIPAddr[2],pAMISetDNSConfReq->DnsConfig.DNSIPAddr[3]);
                }
                else
                {
                    memcpy(BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr1,pAMISetDNSConfReq->DnsConfig.DNSIPAddr,ReqLen);
                }
            }
            else if(pAMISetDNSConfReq->Blockselector == 2)
            {
                memset(&BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr2,0,IP6_ADDR_LEN);
                if(ReqLen == IP_ADDR_LEN)
                {
                    BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr2[10] = 0xFF;
                    BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr2[11] = 0xFF;
                    memcpy(&BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr2[12],pAMISetDNSConfReq->DnsConfig.DNSIPAddr,ReqLen);
                }
                else
                {
                    memcpy(BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr2,pAMISetDNSConfReq->DnsConfig.DNSIPAddr,ReqLen);
                }
            }
            else if(pAMISetDNSConfReq->Blockselector == 3)
            {
                memset(&BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr3,0,IP6_ADDR_LEN);
                if(ReqLen == IP_ADDR_LEN)
                {
                    BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr3[10] = 0xFF;
                    BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr3[11] = 0xFF;
                    memcpy(&BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr3[12],pAMISetDNSConfReq->DnsConfig.DNSIPAddr,ReqLen);
                    TDBG("DNS ipv4 address %d %d %d %d\n",pAMISetDNSConfReq->DnsConfig.DNSIPAddr[0],pAMISetDNSConfReq->DnsConfig.DNSIPAddr[1],
                                                                                    pAMISetDNSConfReq->DnsConfig.DNSIPAddr[2],pAMISetDNSConfReq->DnsConfig.DNSIPAddr[3]);
                }
                else
                {
                    memcpy(BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSIPAddr3,pAMISetDNSConfReq->DnsConfig.DNSIPAddr,ReqLen);
                }
            }
            UNLOCK_BMC_SHARED_MEM(BMCInst);
            break;
        case AMI_DNS_CONF_DNS_RESTART:

            if(ReqLen != 0)
            {
                *pRes = CC_REQ_INV_LEN;
                return sizeof(INT8U);
            }

            SetPendStatus(PEND_OP_SET_ALL_DNS_CFG,PEND_STATUS_PENDING);
            OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel);
            PostPendTask(PEND_OP_SET_ALL_DNS_CFG, 0, 0,*curchannel & 0xF,BMCInst);
            break;

        case AMI_DNS_CONF_DNS_ENABLE:
            /* Validate the request byte */
            if(pAMISetDNSConfReq->DnsConfig.DNSEnable > 1)
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            /* Update the shared memory */
            LOCK_BMC_SHARED_MEM(BMCInst);
                BMC_GET_SHARED_MEM (BMCInst)->DNSconf.DNSEnable = pAMISetDNSConfReq->DnsConfig.DNSEnable;
            UNLOCK_BMC_SHARED_MEM(BMCInst);

            /* If we disable the DNS service, disable the registrations of BMC hostname too... */
            if(pAMISetDNSConfReq->DnsConfig.DNSEnable == 0)
            {
                LOCK_BMC_SHARED_MEM(BMCInst);
                for(i = 0; i < MAX_LAN_CHANNELS; i++)
                    BMC_GET_SHARED_MEM(BMCInst)->DNSconf.RegisterBMC[i] = 0;
                UNLOCK_BMC_SHARED_MEM(BMCInst);
            }
            break;

        default:
            *pRes = CC_PARAM_NOT_SUPPORTED;
            return sizeof(INT8U);
            break;
    }

    pAMISetDNSConfRes->CompletionCode = CC_SUCCESS;

    return(sizeof(AMISetDNSConfRes_T));
}


/*
*@fn GetINT32UBitsNum
*@brief This function will check which bit number is "1" in a value with INT32 type, 
*       but only one bit number will be allowed to be "1".
*@param value - The input value 
*@param bitnum - Which bit number is "1". 
*@return Returns -1 on failure
*        Returns 0 on success
*/
static int GetINT32UBitsNum (INT32U value, INT8U *bitnum)
{
    const INT8U startbit = 0;
    const INT8U endbit = 31;                                    
    INT32U mask = 0x00000000;
    INT32U count = 0;     
    INT8U i = 0;
                
    for(i=startbit;i<=endbit;i++)
    {
        mask = (1<<i);
        if(value & mask)
        {
            (*bitnum) = i;
            count++;
        }  
    }

    if(count != 1) //Only one bit should be enabled
    {
        return -1;
    }
    return 0;
} 

/*
*@fn RestartService
*@brief This function will restart the target service according to parameter service_bit, 
*@param service_bit - refer service id field for details
*@return Returns 0 on success    
*/
/* service id field
 * Bit31-Bit5 |Bit4  | Bit3 | Bit2 | Bit1 | Bit0
 * Reserved   |TELNET| SSH  | MEDIA| KVM  | WEB
 */

static int RestartService(INT8U service_bit,int BMCInst)
{
	struct stat buf;

    if ((service_bit > 0) && (service_bit <= HDMEDIA_SERVICE_ID_BIT))
    {
	      /* Update the stunnel configuration when ports change for kvm & media services */
	      UpdateStunnelEntry(ServiceNameList[service_bit]);

	      if (send_signal_by_name("Adviserd", SIGALRM) != 0)
	      {
            TDBG ("Unable to send the signal to the requested process\n");
	      }
    }

    switch (service_bit)
    {
        case WEB_SERVICE_ID_BIT:
            if(stat("/etc/init.d/webgo.sh",&buf) == 0)
            {
                safe_system("/etc/init.d/webgo.sh restart &");
            }
            else if(stat("/etc/init.d/lighttpd.sh",&buf) == 0)
            {
                safe_system("/etc/init.d/lighttpd.sh restart &");
            }
            break;

        case KVM_SERVICE_ID_BIT:
            safe_system("/etc/init.d/adviserd.sh restart &");
            break;

        case CDMEDIA_SERVICE_ID_BIT:
            safe_system("/etc/init.d/cdserver restart &");
	    break;

        case FDMEDIA_SERVICE_ID_BIT:
            safe_system("/etc/init.d/fdserver restart &");
	    break;

        case HDMEDIA_SERVICE_ID_BIT:
            safe_system("/etc/init.d/hdserver restart &");
            break;

        case SSH_SERVICE_ID_BIT:
            safe_system("/etc/init.d/ssh stop");
            safe_system("/etc/init.d/ssh start");
            break;

        case TELNET_SERVICE_ID_BIT:
            safe_system("/etc/init.d/telnetd stop");
            safe_system("/etc/init.d/telnetd start &");
            break;

        default :
            break;
    }
        
    return 0;
}

int
AMIGetServiceConf( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{

    _NEAR_  AMIGetServiceConfReq_T*  pAMIGetServiceConfReq = (_NEAR_ AMIGetServiceConfReq_T*) pReq;
    _NEAR_  AMIGetServiceConfRes_T*  pAMIGetServiceConfRes = (_NEAR_ AMIGetServiceConfRes_T*) pRes;
    SERVICE_CONF_STRUCT conf;
    INT32U  Value = 0;
    INT8U  ServiceIDBit = 0;
    int ServiceErr = 0;

    /* Match the service_id byte with ServiceName */

    Value = (pAMIGetServiceConfReq->ServiceID);

    ServiceErr = GetINT32UBitsNum (Value, &ServiceIDBit);
    if(ServiceErr < 0)
    {
        TCRIT("Error in getting bit number from service_id\n");
        *pRes = CC_INV_DATA_FIELD;
        return sizeof (INT8U);
    } 

    if(ServiceNameList[ServiceIDBit] == NULL)
    {
        TCRIT("ServiceName is not found in ServiceNameList\n");
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    } 
    
    ServiceErr = get_service_configurations(ServiceNameList[ServiceIDBit], &conf);
    if(ServiceErr < 0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
    memset(pAMIGetServiceConfRes, 0, sizeof(AMIGetServiceConfRes_T)); 
    pAMIGetServiceConfRes->ServiceID =                pAMIGetServiceConfReq->ServiceID;
    pAMIGetServiceConfRes->Enable    =                conf.CurrentState;
    strcpy(pAMIGetServiceConfRes->InterfaceName,      conf.InterfaceName);
    pAMIGetServiceConfRes->InterfaceName [MAX_SERVICE_IFACE_NAME_SIZE] = '\0';
    pAMIGetServiceConfRes->NonSecureAccessPort =      conf.NonSecureAccessPort;              
    pAMIGetServiceConfRes->SecureAccessPort =         conf.SecureAccessPort;                        
    pAMIGetServiceConfRes->SessionInactivityTimeout = conf.SessionInactivityTimeout;           
    pAMIGetServiceConfRes->MaxAllowSession =          conf.MaxAllowSession;                  
    pAMIGetServiceConfRes->CurrentActiveSession =     conf.CurrentActiveSession;
    pAMIGetServiceConfRes->MaxSessionInactivityTimeout=	conf.MaxSessionInactivityTimeout;
    pAMIGetServiceConfRes->MinSessionInactivityTimeout=	conf.MinSessionInactivityTimeout;

    TDBG( "AMIGETSERVICE: ServiceID=%lu, Enable=%d, Name=%s,\n"
            "port=%d, port=%d, timeout=%d, maxsession=%d, activesession=%d\n, "
        	"MaxSessionInactivityTimeout=%d, MinSessionInactivityTimeout=%d",
                pAMIGetServiceConfRes->ServiceID,
                pAMIGetServiceConfRes->Enable,
                pAMIGetServiceConfRes->InterfaceName,
                pAMIGetServiceConfRes->NonSecureAccessPort,               
                pAMIGetServiceConfRes->SecureAccessPort,                                     
                pAMIGetServiceConfRes->SessionInactivityTimeout,            
                pAMIGetServiceConfRes->MaxAllowSession,                  
                pAMIGetServiceConfRes->CurrentActiveSession,
            pAMIGetServiceConfRes->MaxSessionInactivityTimeout,
            pAMIGetServiceConfRes->MinSessionInactivityTimeout);


    pAMIGetServiceConfRes->CompletionCode = CC_SUCCESS;

    return(sizeof(AMIGetServiceConfRes_T));
}



int
AMISetServiceConf( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMISetServiceConfReq_T*  pAMISetServiceConfReq = (_NEAR_ AMISetServiceConfReq_T*) pReq;
    _NEAR_  AMISetServiceConfRes_T*  pAMISetServiceConfRes = (_NEAR_ AMISetServiceConfRes_T*) pRes;

    SERVICE_CONF_STRUCT conf,ReqConf;
    INT32U  Value = 0;
    INT8U   ServiceIDBit = 0;
    int     ServiceErr = 0,i;
    int	    RebootService = 0;

    if ( '\0' != pAMISetServiceConfReq->InterfaceName[MAX_SERVICE_IFACE_NAME_SIZE])
    {
        TCRIT("Error : The last byte must be null in Interface name \n");
        *pRes = CC_INV_DATA_FIELD;
        return sizeof (INT8U);
    }

    /* Match the service_id byte with ServiceName */         
    Value = (pAMISetServiceConfReq->ServiceID);
   
    ServiceErr = GetINT32UBitsNum (Value, &ServiceIDBit);
    if(ServiceErr < 0)
    {
        TCRIT("Error in Getting Bit Number from Service ID\n");
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    } 

    if(ServiceNameList[ServiceIDBit] == NULL)
    {
        TCRIT("Service Name Not Available for the Requested Service ID\n");
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
    
    memset(&ReqConf,0,sizeof(SERVICE_CONF_STRUCT));

    memcpy(&ReqConf.ServiceName[0],ServiceNameList[ServiceIDBit],sizeof(ReqConf.ServiceName));
    memcpy(&ReqConf.InterfaceName[0],&pAMISetServiceConfReq->InterfaceName[0],sizeof(pAMISetServiceConfReq->InterfaceName));
    ReqConf.CurrentState = pAMISetServiceConfReq->Enable;
    ReqConf.MaxAllowSession = pAMISetServiceConfReq->MaxAllowSession;
    ReqConf.SessionInactivityTimeout = pAMISetServiceConfReq->SessionInactivityTimeout;
    ReqConf.SecureAccessPort = pAMISetServiceConfReq->SecureAccessPort;
    ReqConf.NonSecureAccessPort = pAMISetServiceConfReq->NonSecureAccessPort;
    ReqConf.CurrentActiveSession = pAMISetServiceConfReq->CurrentActiveSession;

    if(g_corefeatures.bond_support == ENABLED)
    {
         for(i = 0; i < sizeof(Ifcnametable)/sizeof(IfcName_T); i++)
         {
            if(strcmp(Ifcnametable[i].Ifcname,ReqConf.InterfaceName) == 0 )
            {
                if(CheckBondSlave(Ifcnametable[i].Index) == 1)
                {
                    *pRes = NCML_ERR_INVALID_INTERFACE_NAME;
                    return sizeof(INT8U);
                }
                else
                {
                    break;
                }
            }
         }
    }

    ServiceErr=Validate_SetServiceConfiguration(&ReqConf);
    if(ServiceErr !=CC_NORMAL)
    {
        *pRes=ServiceErr;
        TCRIT("Validate_SetServiceConfiguration Failed %d\n",ServiceErr);
        return sizeof(INT8U);
    }
        
    ServiceErr = get_service_configurations(ReqConf.ServiceName, &conf);
    if (ServiceErr < 0)
    {
        TCRIT("Error in Getting the Configuration for the Requested Service\n");
	*pRes = CC_UNSPECIFIED_ERR;
	return sizeof (INT8U);
    }

    if ((conf.CurrentState != ReqConf.CurrentState) ||
    	(memcmp(conf.InterfaceName, ReqConf.InterfaceName, strlen(conf.InterfaceName)) != 0) ||
   	(conf.NonSecureAccessPort != ReqConf.NonSecureAccessPort) ||
    	(conf.SecureAccessPort != ReqConf.SecureAccessPort) ||                        
    	(conf.SessionInactivityTimeout != ReqConf.SessionInactivityTimeout) ||           
    	(conf.MaxAllowSession != ReqConf.MaxAllowSession))
    {
        RebootService = 1;
    }

    memset(&conf, 0, sizeof(SERVICE_CONF_STRUCT));
    
    memcpy(&conf.ServiceName[0],&ReqConf.ServiceName[0],sizeof(ReqConf.ServiceName));
    conf.CurrentState =             ReqConf.CurrentState;
    strcpy(conf.InterfaceName,      ReqConf.InterfaceName);
    conf.NonSecureAccessPort =      ReqConf.NonSecureAccessPort;              
    conf.SecureAccessPort  =        ReqConf.SecureAccessPort;                        
    conf.SessionInactivityTimeout = ReqConf.SessionInactivityTimeout;           
    conf.MaxAllowSession =          ReqConf.MaxAllowSession;                  
    conf.CurrentActiveSession =     ReqConf.CurrentActiveSession;

    ServiceErr = set_service_configurations(ServiceNameList[ServiceIDBit], &conf,g_corefeatures.timeoutd_sess_timeout);
    if(ServiceErr < 0)
    {
        TCRIT("Error in Setting the Configuration for the Requested Service\n");
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }

    if (RebootService) {
    	RestartService(ServiceIDBit,BMCInst);
	RebootService = 0;
    }

    pAMISetServiceConfRes->CompletionCode = CC_SUCCESS;

    return(sizeof(AMISetServiceConfRes_T));
}

int AMILinkDownResilent( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMILinkDownResilentReq_T*  pAMILinkDownResilentReq = (_NEAR_ AMILinkDownResilentReq_T*) pReq;
    _NEAR_  AMILinkDownResilentRes_T* pAMILinkDownResilentRes = (_NEAR_ AMILinkDownResilentRes_T *) pRes;
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    pAMILinkDownResilentRes->CompletionCode = CC_SUCCESS;

    if(pAMILinkDownResilentReq->LinkDownEnable== 1)
    {
        pBMCInfo->IpmiConfig.LinkDownResilentSupport = 1;
        pAMILinkDownResilentRes->LinkEnableStatus = pBMCInfo->IpmiConfig.LinkDownResilentSupport;
    }
    else if(pAMILinkDownResilentReq->LinkDownEnable == 0)
    {
        pBMCInfo->IpmiConfig.LinkDownResilentSupport = 0;
        pAMILinkDownResilentRes->LinkEnableStatus =  pBMCInfo->IpmiConfig.LinkDownResilentSupport;
    }
    else if(pAMILinkDownResilentReq->LinkDownEnable == 0xFF)
    {
        pAMILinkDownResilentRes->LinkEnableStatus =  pBMCInfo->IpmiConfig.LinkDownResilentSupport;
    }
    else
    {
        *pRes = CC_INV_DATA_FIELD;
    }
    
    return sizeof(AMILinkDownResilentRes_T);
}

/*
 * @fn ValidateSetIfaceStateBond
 * @brief Validate the SetIface State Bond Command inupt
 * @param[in] pReq - Request Structure.
 * @param[out] pRes - Response Structure.
 * @param[out] VLANID - VLANID of the slave interfaces (if any, otherwise return 0).
 * @param[in] CheckBondDisable - Validate the Bond disable feature.
 * @param[in] BMCInst - Instance of the BMC.
 * @return 
 */
int ValidateSetIfaceStateBond (INT8U *pReq, INT8U *pRes, INT8U *VLANID, int CheckBondDisable, int BMCInst)
{
    AMISetIfaceStateReq_T *pAMIIfaceStateReq = (AMISetIfaceStateReq_T *)pReq;
    AMISetIfaceStateRes_T *pAMIIfaceStateRes = (AMISetIfaceStateRes_T *)pRes;
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    int Ifccount = 0, i;
    char IfcName[16];

    if(g_corefeatures.bond_support != ENABLED)
    {
        *pRes = CC_PARAM_NOT_SUPPORTED;
        return sizeof(INT8U);
    }
    if((pAMIIfaceStateReq->ConfigData.BondIface.AutoConf & ENABLE_DISABLE_MASK)!= 0)
    {
        *pRes = CC_INV_DATA_FIELD;
        return sizeof(INT8U);
    }
    if( pAMIIfaceStateReq->ConfigData.BondIface.Slaves == 0)
    {
        *pRes = CC_INSUFFICIENT_SLAVE_COUNT;
        return sizeof(INT8U);
    }
    
    /*Get the no of LAN interface count*/
    if(get_network_interface_count(&Ifccount) < 0)
    {
        pAMIIfaceStateRes->CompletionCode = CC_UNSPECIFIED_ERR;
        return sizeof(INT8U);
    }

    if(Ifccount <= 1)
    {
        *pRes = OEMCC_INSUFFIENT_LANIFC_COUNT;
        return sizeof(INT8U);
    }

    if(pAMIIfaceStateReq->ConfigData.BondIface.BondIndex== 0xff)
    {
        IPMI_WARNING("\nInvalid EthIndex number :%x", pAMIIfaceStateReq->ConfigData.BondIface.BondIndex);
        *pRes = CC_INV_DATA_FIELD;
        return sizeof (INT8U);
    }

    if (CheckBondDisable == 1)
    {
        if(g_corefeatures.delayed_lan_restart_support)
        {
            if((!pBMCInfo->BondConfig.Enable) && (pAMIIfaceStateReq->ConfigData.BondIface.Enable == IFACE_DISABLED))
            {
                *pRes = OEMCC_BOND_ALREADY_DISABLED;
                return sizeof(INT8U);
            }
        }
        else
        {
            GetNoofInterface();
    
            memset(IfcName,0,sizeof(IfcName));
            sprintf(IfcName,"bond%d",pAMIIfaceStateReq->ConfigData.BondIface.BondIndex);
            for(i=0;i<sizeof(Ifcnametable)/sizeof(IfcName_T);i++)
            {
                if(Ifcnametable[i].Ifcname[0] == 0)
                    continue;
        
                if((strcmp(IfcName,Ifcnametable[i].Ifcname) == 0 ))
                {
                    if((Ifcnametable[i].Enabled == IFACE_DISABLED ) && (pAMIIfaceStateReq->ConfigData.BondIface.Enable == IFACE_DISABLED))
                    {
                        *pRes = OEMCC_BOND_ALREADY_DISABLED;
                        return sizeof(INT8U);
                    }
                    break;
                }
            }
    
            if(i == sizeof(Ifcnametable)/sizeof(IfcName_T))
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }
        }
    }

    TDBG("Enable:%d\nBondIndex:%d\nBondMode:%d\nmiiinterval:%d\nSlave:%d\nAutoConf:%d\n",
                                                    pAMIIfaceStateReq->ConfigData.BondIface.Enable,
                                                    pAMIIfaceStateReq->ConfigData.BondIface.BondIndex,
                                                    pAMIIfaceStateReq->ConfigData.BondIface.BondMode,
                                                    pAMIIfaceStateReq->ConfigData.BondIface.MiiInterval,
                                                    pAMIIfaceStateReq->ConfigData.BondIface.Slaves,
                                                    pAMIIfaceStateReq->ConfigData.BondIface.AutoConf);
    /*Validate the bonding mode*/
    if( pAMIIfaceStateReq->ConfigData.BondIface.BondMode > MAX_BOND_MODE)
    {
        IPMI_WARNING("Bond Mode is exceeded\n");
        *pRes = CC_INV_DATA_FIELD;
        return (sizeof(INT8U));
    }

    /*Validate the supported bonding modes*/
    if( pAMIIfaceStateReq->ConfigData.BondIface.BondMode == MAX_BOND_MODE )
    {
        IPMI_WARNING("Bond Mode %d is not supported\n",pAMIIfaceStateReq->ConfigData.BondIface.BondMode);
        *pRes = OEMCC_UNSUPPORTED_BOND_MODE;
        return (sizeof(INT8U));
    }

    /*Validate the miiinterval*/
    if(pAMIIfaceStateReq->ConfigData.BondIface.MiiInterval < DEFAULT_MII_INTERVAL)
    {
        IPMI_WARNING("Mii interval should be greater than 100\n");
        *pRes = CC_INV_DATA_FIELD;
        return (sizeof(INT8U));
    }

    *pRes = CheckSlaveVLANInterface(pAMIIfaceStateReq->ConfigData.BondIface.Slaves, VLANID, BMCInst);
    if ((*pRes) != 0)
    {
        return (sizeof(INT8U));
    }
    return 0;
    
}


/**
 * @fn AMISetIfaceState
 * @brief This function sets the status of interfaces
 * @param Request message and BMC instance
 * @return success completion code 
 */
int AMISetIfaceState( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMISetIfaceStateReq_T*  pAMIIfaceStateReq = (_NEAR_ AMISetIfaceStateReq_T *) pReq;
    _NEAR_  AMISetIfaceStateRes_T*  pAMIIfaceStateRes = (_NEAR_ AMISetIfaceStateRes_T *) pRes;
    NWCFG_STRUCT cfg;
    NWCFG6_STRUCT cfg6;
    int retValue = 0;
    char IfcName[16],tmpstr[16];
    int EthIndex = 0,i,ethcount=0;
    INT8U CurrentIfaceState = 0x00, VLANID = 0,*curchannel;
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    BondIface   bond;
    int Ifccount = 0;
    memset(&bond,0,sizeof(BondIface));
	INT8U netch = 0;

    if ( ReqLen >= 1 )
    {
        ReqLen -= 1;
    }
    else
    {
        *pRes = CC_REQ_INV_LEN;
        return sizeof (INT8U);
    }
    if(IsBMCNFSMode() != 0)
    {
         IPMI_WARNING("Card in NFS mode, Not safe to set any of interface configurations...\n");
         *pRes = CC_CMD_UNSUPPORTED_UNCONFIGURABLE;
         return sizeof(INT8U);
    }

    if(g_corefeatures.online_flashing_support == ENABLED)
    {
        if(IsCardInFlashMode())
        {
            IPMI_WARNING("Card in Active flash mode, Not safe to set any of network configurations...\n");
            *pRes = CC_DEV_IN_FIRMWARE_UPDATE_MODE;
            return sizeof(INT8U);
        }
    }
    if( 0x02 >pAMIIfaceStateReq->Params)
    {
        if(ReqLen != NwIfcStateConfigParamLenght[pAMIIfaceStateReq->Params])
        {
            TCRIT("params:%d reqLen:%ld\n",pAMIIfaceStateReq->Params,ReqLen);
            *pRes = CC_REQ_INV_LEN;
            return sizeof(INT8U);
        }
    }
    
    if (g_PDKHandle[PDK_BEFORESETIFACESTATE] != NULL )
    {
        retValue = ((int(*)(INT8U *, INT8U, INT8U *,int))
                (g_PDKHandle[PDK_BEFORESETIFACESTATE]))(pReq, ReqLen, pRes, BMCInst);
        if(retValue != 0)
        {
              return retValue;
        }
    }

    OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel);
    switch(pAMIIfaceStateReq->Params)
    {
        case AMI_IFACE_STATE_ETH:

            if(pAMIIfaceStateReq->ConfigData.EthIface.EthIndex == 0xff)
            {
                IPMI_WARNING("\nInvalid EthIndex number :%x", pAMIIfaceStateReq->ConfigData.EthIface.EthIndex);
                *pRes = CC_INV_DATA_FIELD;
                return sizeof (INT8U);
            }

            //Checking for valid EnableState
            if(  (pAMIIfaceStateReq->ConfigData.EthIface.EnableState != DISABLE_V4_V6)
                 && (pAMIIfaceStateReq->ConfigData.EthIface.EnableState != ENABLE_V4)
                 && (pAMIIfaceStateReq->ConfigData.EthIface.EnableState != ENABLE_V6)
                 && (pAMIIfaceStateReq->ConfigData.EthIface.EnableState != ENABLE_V4_V6)
              )
            {
                IPMI_WARNING("\nInvalid EnableState :%x", pAMIIfaceStateReq->ConfigData.EthIface.EnableState);
                *pRes = CC_INV_DATA_FIELD;
                return sizeof (INT8U);
            }

            /*Ethindex to be enabled*/
            EthIndex = pAMIIfaceStateReq->ConfigData.EthIface.EthIndex;

            /*Compare the bonding and eth interfaces */
            if(GetIfcNameByIndex(EthIndex, IfcName) != 0)
            {
                IPMI_WARNING("Invalid EthIndex number %d\n",EthIndex);
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            sprintf(tmpstr,"bond");
            if(strstr(IfcName,tmpstr) != NULL)
            {
                IPMI_WARNING("Given EthIndex %d  is specific to bonding interface. Use specific parameter for bonding\n",EthIndex);
                *pRes = OEMCC_INV_PARAM_ONLY_FOR_NON_BONDING;
                return sizeof(INT8U);
            }
            if(!((g_corefeatures.delayed_lan_restart_support) && !(pBMCInfo->BondConfig.Enable)))
            {
                /*Check if the given Interface is the slave of any Bond interfaces*/
                retValue= CheckBondSlave(pAMIIfaceStateReq->ConfigData.EthIface.EthIndex);
                if(retValue == -1)
                {
                    *pRes = CC_UNSPECIFIED_ERR;
                    return sizeof(INT8U);
                }

                if(retValue == 1)
                {
                    *pRes = CC_PARAM_NOT_SUP_IN_CUR_STATE;
                    return sizeof(INT8U);
                }
            }
            /*Update the interface status*/
            GetNoofInterface();
            for(i=0;i<sizeof(Ifcnametable)/sizeof(IfcName_T);i++)
            {
                if(Ifcnametable[i].Ifcname[0] == 0)
                    continue;

                if(Ifcnametable[i].Enabled == 1)
                    ethcount++;
            }

            memset(&cfg, 0, sizeof(NWCFG_STRUCT));
            memset(&cfg6, 0, sizeof(NWCFG6_STRUCT));

            retValue = nwReadNWCfg_v4_v6(&cfg, &cfg6, EthIndex,g_corefeatures.global_ipv6);
            if(retValue != 0)
                TCRIT("Error in reading network configuration.\n");     

            CurrentIfaceState = ((cfg6.enable<<1) | cfg.enable);

            if(CurrentIfaceState == pAMIIfaceStateReq->ConfigData.EthIface.EnableState)
            {
                TCRIT("Iface state is the same, do nothing\n");         
                *pRes = CC_SUCCESS;
                return sizeof(AMISetIfaceStateRes_T); 
            }
            if(ENABLE_V6 == pAMIIfaceStateReq->ConfigData.EthIface.EnableState)
            {
                if(g_corefeatures.global_ipv6  == ENABLED)
                {
                    TDBG("IPv6 only enabled");
                }
                else
                {
                   TCRIT("IPMI support for IPv6 is Disabled...\n");
                   *pRes = OEMCC_INV_IP4_NOT_ENABLED;
                   return sizeof (INT8U);
                }
            }
            if((ethcount == 1) && pAMIIfaceStateReq->ConfigData.EthIface.EnableState == 0x0)
            {
                *pRes =OEMCC_INV_MIN_IFC_COUNT_DISABLED;
                return sizeof(INT8U);
            }
            
            pBMCInfo->LANCfs[EthIndex].IPv6_Enable = (pAMIIfaceStateReq->ConfigData.EthIface.EnableState & ENABLE_V6) ? 1 : 0;
            pBMCInfo->LANCfs[EthIndex].IPv4_Enable= (pAMIIfaceStateReq->ConfigData.EthIface.EnableState & ENABLE_V4) ? 1 : 0;
            SetPendStatus(PEND_OP_SET_ETH_IFACE_STATE,PEND_STATUS_PENDING);
            PostPendTask(PEND_OP_SET_ETH_IFACE_STATE, (INT8U *)&pAMIIfaceStateReq->ConfigData.EthIface, sizeof(EthIfaceState),*curchannel & 0xF,BMCInst);
            
            FlushIPMI((INT8U*)&pBMCInfo->LANCfs[0], (INT8U*)&pBMCInfo->LANCfs[EthIndex], 
                    pBMCInfo->IPMIConfLoc.LANCfsAddr, sizeof(LANConfig_T),BMCInst);
            break;
        case AMI_IFACE_BOND_ENABLED:
            *pRes = CC_ATTEMPT_TO_SET_RO_PARAM;
            return sizeof (*pRes);

            break;
        case AMI_GET_IFACE_COUNT:
            *pRes = CC_ATTEMPT_TO_SET_RO_PARAM;
            return sizeof (*pRes);

            break;
        case AMI_GET_IFACE_CHANNEL:
            *pRes = CC_ATTEMPT_TO_SET_RO_PARAM;
            return sizeof (*pRes);

            break;
        case AMI_GET_IFACE_NAME:
            *pRes = CC_ATTEMPT_TO_SET_RO_PARAM;
            return sizeof (*pRes);

            break;
        case AMI_IFACE_STATE_BOND:
            
            retValue = ValidateSetIfaceStateBond (pReq, pRes, &VLANID, 1, BMCInst);
            if (retValue != 0)
            {
                return retValue;
            }
			sprintf(IfcName,"bond%d",pAMIIfaceStateReq->ConfigData.BondIface.BondIndex);

            for(i=0;i<MAX_LAN_CHANNELS;i++)
            {
                if(strcmp(pBMCInfo->LanIfcConfig[i].ifname,IfcName) == 0)
                {
                    EthIndex=pBMCInfo->LanIfcConfig[i].Ethindex;
					netch = pBMCInfo->LanIfcConfig[i].Chnum ;
                    break;
                }
            }
            if (pAMIIfaceStateReq->ConfigData.BondIface.Enable == 1)
            {
                memset(&cfg, 0, sizeof(NWCFG_STRUCT));
                memset(&cfg6, 0, sizeof(NWCFG6_STRUCT));
                memset(IfcName,0,sizeof(IfcName));

                if(g_corefeatures.delayed_lan_restart_support)
                {
                    if((pBMCInfo->LANCfs[EthIndex].IPv4_Enable == 0) && (pBMCInfo->LANCfs[EthIndex].IPv6_Enable == 0))
                    {
                        *pRes = OEMCC_ETH_IFACE_DISABLED;
                        return sizeof(INT8U);
                    }
                }
                else
                {
                    retValue = nwReadNWCfg_v4_v6(&cfg, &cfg6,EthIndex,g_corefeatures.global_ipv6);
                    if(retValue != 0)
                        TCRIT("Error in reading network configuration.\n");

                    if ((cfg.enable == 0) && (cfg6.enable == 0))
                    {
                        *pRes = OEMCC_ETH_IFACE_DISABLED;
                        return sizeof(INT8U);
                    }
                }
            }
            _fmemcpy (&pBMCInfo->BondConfig,
                                  &(pAMIIfaceStateReq->ConfigData.BondIface), sizeof(BondIface));
            SetPendStatus(PEND_OP_SET_BOND_IFACE_STATE,PEND_STATUS_PENDING);
            PostPendTask(PEND_OP_SET_BOND_IFACE_STATE, (INT8U *)&pAMIIfaceStateReq->ConfigData.BondIface, sizeof(BondIface),netch & 0xF,BMCInst);
            
            if (VLANID != 0)
            {
                cfg.VLANID = VLANID;
                SetPendStatus(PEND_OP_SET_VLAN_ID, PEND_STATUS_PENDING);
                PostPendTask(PEND_OP_SET_VLAN_ID, (INT8U*)&cfg, sizeof(cfg), (*curchannel & 0x0F), BMCInst );
            }
            FlushIPMI((INT8U*)&pBMCInfo->BondConfig, (INT8U*)&pBMCInfo->BondConfig, 
                    pBMCInfo->IPMIConfLoc.BONDConfigAddr, sizeof(BondIface),BMCInst);
            break;
        case AMI_BOND_ACTIVE_SLAVE:
            if(g_corefeatures.bond_support != ENABLED)
            {
                *pRes = CC_PARAM_NOT_SUPPORTED;
                return sizeof(INT8U);
            }
            memset(IfcName,0,sizeof(IfcName));
            sprintf(IfcName,"bond%d",pAMIIfaceStateReq->ConfigData.ActiveSlave.BondIndex);
            for(i=0;i<sizeof(Ifcnametable)/sizeof(IfcName_T);i++)
            {
                if((strcmp(IfcName,Ifcnametable[i].Ifcname) == 0 ) )
                {
                    break;
                }
            }

            /*Bond index is Invalid*/
            if(i == sizeof(Ifcnametable)/sizeof(IfcName_T))
            {
                *pRes = OEMCC_BOND_NOT_ENABLED;
                return sizeof(INT8U);
            }

            if(pAMIIfaceStateReq->ConfigData.ActiveSlave.ActiveIndex == 0x0)
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            /*Index value 0xff will enable both eth0 and eth1 interface*/
            if(pAMIIfaceStateReq->ConfigData.ActiveSlave.ActiveIndex != 0xff )
            {
                for(i=0;i<BOND_MAX_SLAVE;i++)
                {
                    if((pAMIIfaceStateReq->ConfigData.ActiveSlave.ActiveIndex >> i) & IFACE_ENABLED)
                    {
                        Ifccount++;
                        /*Check Slave Entry presence*/
                        if(CheckIfcEntry(i,ETH_IFACE_TYPE) != 0)
                        {
                            *pRes = CC_INV_DATA_FIELD;
                            return sizeof(INT8U);
                        }
                    }
                }
            }

            if (nwGetBondConf( &bond, pAMIIfaceStateReq->ConfigData.ActiveSlave.BondIndex) != 0)
            {
                TDBG("Error in getting Bonding Configurations\n");
            }

            if((bond.BondMode == BOND_ACTIVE_BACKUP) && ((pAMIIfaceStateReq->ConfigData.ActiveSlave.ActiveIndex == 0xff) || (Ifccount > 1)))
            {
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

            if(bond.BondMode == BOND_ACTIVE_BACKUP)
            {
                for(i=0;i<BOND_MAX_SLAVE;i++)
                {
                    if((pAMIIfaceStateReq->ConfigData.ActiveSlave.ActiveIndex >> i) & IFACE_ENABLED)
                    {
                        if(CheckIfcLinkStatus(i) != 1)
                        {
                            *pRes = OEMCC_ACTIVE_SLAVE_LINK_DOWN;
                            return sizeof(INT8U);
                        }
                        break;
                    }
                }
            }

            SetPendStatus(PEND_OP_SET_ACTIVE_SLAVE,PEND_STATUS_PENDING);
            PostPendTask(PEND_OP_SET_ACTIVE_SLAVE, (INT8U *)&pAMIIfaceStateReq->ConfigData.ActiveSlave, sizeof(ActiveSlave_T),*curchannel & 0xF,BMCInst);
            break;
        case AMI_BOND_VLAN_ENABLED:
            if(g_corefeatures.bond_support == ENABLED)
            {
                *pRes = CC_ATTEMPT_TO_SET_RO_PARAM;
            }
            else
            {
                *pRes = CC_PARAM_NOT_SUPPORTED;
            }
            return sizeof (*pRes);

            break;
        default:
            pAMIIfaceStateRes->CompletionCode = CC_PARAM_NOT_SUPPORTED;
            return sizeof(INT8U);

    }
    pAMIIfaceStateRes->CompletionCode = CC_SUCCESS;
    return sizeof(AMISetIfaceStateRes_T);
}

/**
 * @fn AMIGetIfaceState
 * @brief This function returns the status of interfaces
 * @param Request message and BMC instance
 * @return status of interfaces 
 */
int AMIGetIfaceState( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{

    _NEAR_  AMIGetIfaceStateReq_T*  pAMIIfaceStateReq = (_NEAR_ AMIGetIfaceStateReq_T *) pReq;
    _NEAR_  AMIGetIfaceStateRes_T*  pAMIIfaceStateRes = (_NEAR_ AMIGetIfaceStateRes_T *) pRes;
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    NWCFG_STRUCT cfg;
    NWCFG6_STRUCT cfg6;
    BondIface   bond;
    char tmpstr[16];

    char IfcName[16],EthIfcname[MAX_ETHIFC_LEN * MAX_LAN_CHANNELS];
    int retValue = 0,i,Ifccount = 0,j,count=0;
    int EthIndex = 0,NIC_Count = 0,netindex = 0;
    INT8U CurrentIfaceState = 0x00;

    if(0 != pAMIIfaceStateReq->BlockSelect)
    {
        IPMI_WARNING("Invalid BlockSelect :%x\n", pAMIIfaceStateReq->BlockSelect);
        *pRes = CC_INV_DATA_FIELD;
        return sizeof (INT8U);
    }
    if (g_PDKHandle[PDK_BEFOREGETIFACESTATE] != NULL )
    {
        retValue = ((int(*)(INT8U *, INT8U, INT8U *,int))
                (g_PDKHandle[PDK_BEFOREGETIFACESTATE]))(pReq, ReqLen, pRes, BMCInst);
        if(retValue != 0)
        {
              return retValue;
        }
    }

    GetNoofInterface();
    switch(pAMIIfaceStateReq->Params)
    {
        case AMI_IFACE_STATE_ETH:
            if(pAMIIfaceStateReq->SetSelect== 0xff)
            {
                IPMI_WARNING("\nInvalid EthIndex number :%x", pAMIIfaceStateReq->SetSelect);
                *pRes = CC_INV_DATA_FIELD;
                return sizeof (INT8U);
            }
            EthIndex = pAMIIfaceStateReq->SetSelect;

            if(GetIfcNameByIndex(EthIndex, IfcName) != 0)
            {
                IPMI_WARNING("Invalid EthIndex number %d\n",EthIndex);
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }

/*            sprintf(tmpstr,"bond0");
            if(strcmp(tmpstr,IfcName) == 0)
            {
                IPMI_WARNING("Given EthIndex %d  is specific to bonding interface. Use specific parameter for bonding\n",EthIndex);
                *pRes = CC_INV_DATA_FIELD;
                return sizeof(INT8U);
            }*/

            memset(&cfg, 0, sizeof(NWCFG_STRUCT));
            memset(&cfg6, 0, sizeof(NWCFG6_STRUCT));
               
            if((g_corefeatures.delayed_lan_restart_support))
            {
                netindex = EthIndex;
                if(pBMCInfo->BondConfig.Enable == 1)
                {
                    sprintf(tmpstr,"bond0");
                    for(i=0; i < MAX_LAN_CHANNELS; i++)
                    {
                        if(strcmp(tmpstr, pBMCInfo->LanIfcConfig[i].ifname) == 0)
                        {
                            netindex = pBMCInfo->LanIfcConfig[i].Ethindex;
                        }
                    }
                }
                cfg6.enable = pBMCInfo->LANCfs[netindex].IPv6_Enable;
                cfg.enable = pBMCInfo->LANCfs[netindex].IPv4_Enable;
            }
            else
            {
                retValue = nwReadNWCfg_v4_v6(&cfg, &cfg6, EthIndex,g_corefeatures.global_ipv6);
                if(retValue != 0)
                    TCRIT("Error in reading network configuration.\n"); 
            }
            pAMIIfaceStateRes->ConfigData.EthIface.EthIndex = EthIndex;
            CurrentIfaceState = ((cfg6.enable<<1) | cfg.enable);
            pAMIIfaceStateRes->ConfigData.EthIface.EnableState = CurrentIfaceState;
            pAMIIfaceStateRes->CompletionCode = CC_NORMAL;
            return sizeof(INT8U) + sizeof(EthIfaceState);
            break;
        case AMI_IFACE_STATE_BOND:
            if(g_corefeatures.bond_support == ENABLED)
            {
                if(pAMIIfaceStateReq->SetSelect== 0xff)
                {
                    IPMI_WARNING("\nInvalid EthIndex number :%x", pAMIIfaceStateReq->SetSelect);
                    *pRes = CC_INV_DATA_FIELD;
                    return sizeof (INT8U);
                }
                EthIndex = pAMIIfaceStateReq->SetSelect;
    
                memset(&bond,0,sizeof(BondIface));
    
                if(g_corefeatures.delayed_lan_restart_support)
                {
                   if(EthIndex == pBMCInfo->BondConfig.BondIndex)
                   {
                        memcpy(&bond, &pBMCInfo->BondConfig, sizeof(BondIface)); 
                   }
                }
                else
                {
                    if (nwGetBondConf( &bond, EthIndex) != 0)
                    {
                        TDBG("Error in getting Bonding Configurations\n");
                    }
                }
                pAMIIfaceStateRes->CompletionCode = CC_NORMAL;
                pAMIIfaceStateRes->ConfigData.BondIface.Enable = bond.Enable;
                pAMIIfaceStateRes->ConfigData.BondIface.BondIndex = bond.BondIndex;
                pAMIIfaceStateRes->ConfigData.BondIface.BondMode = bond.BondMode;
                pAMIIfaceStateRes->ConfigData.BondIface.MiiInterval = bond.MiiInterval;
                pAMIIfaceStateRes->ConfigData.BondIface.Slaves = bond.Slaves;
                pAMIIfaceStateRes->ConfigData.BondIface.AutoConf = bond.AutoConf;
                return sizeof(INT8U) +sizeof(BondIface);
            }
            else
            {
                *pRes = CC_PARAM_NOT_SUPPORTED;
                return sizeof(INT8U);
            }
            break;
        case AMI_IFACE_BOND_ENABLED:
             if(pAMIIfaceStateReq->SetSelect != 0)
            {
                IPMI_WARNING("\nInvalid BondIndex number :%x", pAMIIfaceStateReq->SetSelect);
                *pRes = CC_INV_DATA_FIELD;
                return sizeof (INT8U);
            }
            memset(IfcName,0,sizeof(IfcName));
            sprintf(IfcName,"bond%d",pAMIIfaceStateReq->SetSelect);
            for(i=0;i<sizeof(pBMCInfo->LanIfcConfig)/sizeof(LANIFCConfig_T);i++)
            {
                if((strcmp(IfcName,pBMCInfo->LanIfcConfig[i].ifname) == 0 ) && 
                    (pBMCInfo->LanIfcConfig[i].Up_Status == 1))
                {
                    pAMIIfaceStateRes->ConfigData.BondEnable.Enabled = 1;
                    break;
                }
                else
                {
                    pAMIIfaceStateRes->ConfigData.BondEnable.Enabled = 0;
                    pAMIIfaceStateRes->ConfigData.BondEnable.BondIndex = 0;
                }
            }

            for(i=0;i< sizeof(Ifcnametable)/sizeof(IfcName_T);i++)
            {
                if(Ifcnametable[i].Ifcname[0] == 0)
                    continue;

                if( (strcmp(IfcName,Ifcnametable[i].Ifcname) == 0) && 
                    (pAMIIfaceStateRes->ConfigData.BondEnable.Enabled == 1))
                {
                    pAMIIfaceStateRes->ConfigData.BondEnable.BondIndex = Ifcnametable[i].Index;
                    break;
                }
            }
            pAMIIfaceStateRes->CompletionCode = CC_NORMAL;
            return sizeof(INT8U)+sizeof(BondEnabled_T);
            break;
        case AMI_GET_IFACE_COUNT:
            /*Get the no of LAN interface count support for IPMI*/
            if( NULL != g_PDKHandle[PDK_GETIFACECOUNT])
            {
                if( 0xFF != (((INT8U(*)(INT8U *, INT8U *, int))(g_PDKHandle[PDK_GETIFACECOUNT]))
                        (pAMIIfaceStateRes->ConfigData.LANCount.EthIndex, 
                         &pAMIIfaceStateRes->ConfigData.LANCount.Count, BMCInst)))
                {
                    pAMIIfaceStateRes->CompletionCode = CC_NORMAL;
                    return sizeof (AMIGetIfaceStateRes_T);
                }
            }
            
            if(get_network_interface_count(&Ifccount) < 0)
            {
                pAMIIfaceStateRes->CompletionCode = CC_UNSPECIFIED_ERR;
                return sizeof(INT8U);
            }
            memset(EthIfcname,0,MAX_ETHIFC_LEN * MAX_LAN_CHANNELS);
            memset(pAMIIfaceStateRes->ConfigData.LANCount.EthIndex,0,MAX_LAN_CHANNEL);

            if(get_network_interfaces_name(EthIfcname,Ifccount) < 0)
            {
                pAMIIfaceStateRes->CompletionCode = CC_UNSPECIFIED_ERR;
                return sizeof(INT8U);
            }
            
            count = 0;
            /*Get the Index value of each LAN Interface*/
            for(i=0;i<sizeof(Ifcnametable)/sizeof(IfcName_T);i++)
            {
                if(Ifcnametable[i].Ifcname[0] == 0)
                    continue;

                for(j=0;j <Ifccount;j++)
                {
                    if((strcmp(Ifcnametable[i].Ifcname,&EthIfcname[j*MAX_ETHIFC_LEN]) == 0)
                      && (strlen(Ifcnametable[i].Ifcname) != 0))
                        {
                            pAMIIfaceStateRes->ConfigData.LANCount.EthIndex[count] = Ifcnametable[i].Index;
                            count++;
                        }
                }
            }
            
            /* force count value to match CONFIG_SPX_FEATURE_GLOBAL_NIC_COUNT */
            NIC_Count =g_coremacros.global_nic_count;
            if(count > NIC_Count)
            {
                count = NIC_Count;
            }

            pAMIIfaceStateRes->CompletionCode = CC_NORMAL;
            pAMIIfaceStateRes->ConfigData.LANCount.Count = count;
            return sizeof(INT8U)+sizeof(LANIfcCount_T);
            break;
        case AMI_GET_IFACE_CHANNEL:
            pAMIIfaceStateRes->ConfigData.IfcChannel.Channel = 0;
            for(i=0;i<sizeof(Ifcnametable)/sizeof(IfcName_T);i++)
            {
                if(Ifcnametable[i].Ifcname[0] == 0)
                    continue;

                if(Ifcnametable[i].Index== pAMIIfaceStateReq->SetSelect)
                {
                    for(j=0;j<MAX_LAN_CHANNELS;j++)
                    {
                        if(strcmp(Ifcnametable[i].Ifcname,pBMCInfo->LanIfcConfig[j].ifname) == 0)
                        {
                            pAMIIfaceStateRes->ConfigData.IfcChannel.Channel = pBMCInfo->LanIfcConfig[j].Chnum;
                            pAMIIfaceStateRes->CompletionCode = CC_SUCCESS;
                            return sizeof(INT8U)+sizeof(GetIfcChannel_T);
                        }
                    }
                }
            }
            *pRes = CC_INV_DATA_FIELD;
            return sizeof(INT8U);
            break;
        case AMI_GET_IFACE_NAME:

            memset(&pAMIIfaceStateRes->ConfigData.IfcName.IfcName,0,sizeof(MAX_IFACE_NAME));
            for(i=0;i<sizeof(Ifcnametable)/sizeof(IfcName_T);i++)
            {
                if(Ifcnametable[i].Ifcname[0] == 0)
                    continue;

                if(Ifcnametable[i].Index== pAMIIfaceStateReq->SetSelect)
                {
                    memcpy(&pAMIIfaceStateRes->ConfigData.IfcName.IfcName,&Ifcnametable[i].Ifcname,MAX_IFACE_NAME);
                    pAMIIfaceStateRes->CompletionCode = CC_SUCCESS;
                    return sizeof(INT8U)+sizeof(GetIfcName_T);
                }
            }
            *pRes = CC_INV_DATA_FIELD;
            return sizeof(INT8U);
            break;
        case AMI_BOND_ACTIVE_SLAVE:
            if(g_corefeatures.bond_support == ENABLED)
            {
                memset(IfcName,0,sizeof(IfcName));
                sprintf(IfcName,"bond%d",pAMIIfaceStateReq->SetSelect);
                for(i=0;i<sizeof(Ifcnametable)/sizeof(IfcName_T);i++)
                {
                    if(Ifcnametable[i].Ifcname[0] == 0)
                        continue;
    
                    if((strcmp(IfcName,Ifcnametable[i].Ifcname) == 0 ))
                    {
                        pAMIIfaceStateRes->ConfigData.ActiveSlave.BondIndex = pAMIIfaceStateReq->SetSelect;
                        break;
                    }
                }
    
                /*Bond index is Invalid*/
                if(i == sizeof(Ifcnametable)/sizeof(IfcName_T))
                {
                    *pRes = OEMCC_BOND_NOT_ENABLED;
                    return sizeof(INT8U);
                }
    
                /*Get the active slave configuration*/
                nwGetActiveSlave(pAMIIfaceStateReq->SetSelect,&pAMIIfaceStateRes->ConfigData.ActiveSlave.ActiveIndex);
                pAMIIfaceStateRes->CompletionCode = CC_NORMAL;
                return sizeof(INT8U)+sizeof(ActiveSlave_T);
            }
            else
            {
                *pRes = CC_PARAM_NOT_SUPPORTED;
                return sizeof(INT8U);
            }
            break;
        case AMI_BOND_VLAN_ENABLED:
            if(g_corefeatures.bond_support == ENABLED)
            {
                memset(IfcName,0,sizeof(IfcName));
                sprintf(IfcName,"bond%d",pAMIIfaceStateReq->SetSelect);
    
                if(CheckVLANInterface(IfcName, BMCInst) == 1)
                    pAMIIfaceStateRes->ConfigData.BondVLAN.Enabled = 1;
                else
                    pAMIIfaceStateRes->ConfigData.BondVLAN.Enabled = 0;
    
                pAMIIfaceStateRes->CompletionCode = CC_SUCCESS;
                return sizeof(INT8U)+sizeof(BondVLAN_T);
            }
            else
            {
                *pRes = CC_PARAM_NOT_SUPPORTED;
                return sizeof(INT8U);
            }
            break;
        default:
            pAMIIfaceStateRes->CompletionCode = CC_PARAM_NOT_SUPPORTED;
            return sizeof(INT8U);
    }
    pAMIIfaceStateRes->CompletionCode = CC_SUCCESS;
    return sizeof (AMIGetIfaceStateRes_T);
}

/**
 * @fn AMISetFirewall
 * @brief This function sets the iptables Firewall
 * @param Request message and Iptables State 
 */
int AMISetFirewall ( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes ,int BMCInst )
{
	_NEAR_ AMISetFirewallReq_T *pAMISetFirewallReq = ( _NEAR_ AMISetFirewallReq_T *) pReq;
	_NEAR_ AMISetFirewallRes_T *pAMISetFirewallRes = ( _NEAR_ AMISetFirewallRes_T *) pRes;
	INT8U *curchannel;

       if(g_corefeatures.system_firewall_support != CORE_FEATURE_ENABLED)
       {
           pAMISetFirewallRes->CompletionCode = CC_INV_CMD;
           return sizeof(INT8U);
       }

	if(0x0b > pAMISetFirewallReq->Param  )   //Max known Firewall paramter
	{
        if ((ReqLen-1) != FirewallConfigParamLength [pAMISetFirewallReq->Param ])
	    {	    	
	        *pRes = CC_REQ_INV_LEN;
	        TDBG("Your entered Parameter %d is not a valid data \n",pAMISetFirewallReq->Param);
	        return sizeof (INT8U);
	    }
	    else
	    {
	    	TDBG("Your entered Parameter %d is a valid data... \n",pAMISetFirewallReq->Param);
	    }
	 }
	
	void *dl_handle = NULL;
	void ( *dl_func )( void *, void * );
	void ( *dl_block )( void * );
	
	dl_handle = NULL;
	dl_handle = dlopen ( "/usr/local/lib/libiptables.so", RTLD_NOW ); 
	
	
	if(NULL == dl_handle)
	{
		IPMI_ERROR("Error in loading libiptables.so library %s\n", dlerror() );
		return 0;
	}
		
	switch ( pAMISetFirewallReq->Param )
	{
		case IP_IPV4:	
            dl_func =  dlsym( dl_handle, "block_ip_ipv4" );
			if(NULL == dl_func)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}

			dl_func ( (void *)&pAMISetFirewallReq->State,(void *) pAMISetFirewallReq->CMD_INFO.IPAddr_ipv4 );
			break;
					
		case IPS_IPV4:		
			dl_func =  dlsym( dl_handle, "block_ip_range_ipv4" );
			if(NULL == dl_func)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}
			dl_func ( (void *)&pAMISetFirewallReq->State,(void *) &pAMISetFirewallReq->CMD_INFO.IPRange_ipv4 );
			break;

		case PORT:	
			dl_func =  dlsym( dl_handle, "block_port" );
			if(NULL == dl_func)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}

			dl_func ( (void *)&pAMISetFirewallReq->State,(void *) &pAMISetFirewallReq->CMD_INFO.Port_Data);		
			break;

		case PORT_RANGE: 
			dl_func = dlsym ( dl_handle, "block_range_ports" );
			if(NULL == dl_func)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}

			dl_func ( (void *)&pAMISetFirewallReq->State,(void *) &pAMISetFirewallReq->CMD_INFO.Port_Range);
			break;

		case IP_IPV4_Unlock:
			dl_func =  dlsym( dl_handle, "release_ip_ipv4" );
			if(NULL == dl_func)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}

			dl_func ( (void *)&pAMISetFirewallReq->State,(void *) pAMISetFirewallReq->CMD_INFO.IPAddr_ipv4 );
			break;

		case IPS_IPV4_Unlock:
			dl_func =  dlsym( dl_handle, "release_range_ip_ipv4" );
			if(NULL == dl_func)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}

			dl_func ( (void *)&pAMISetFirewallReq->State,(void *) &pAMISetFirewallReq->CMD_INFO.IPRange_ipv4 );
			break;
	
		case PORT_Release:	
			dl_func =  dlsym( dl_handle, "release_port" );
			if(NULL == dl_func)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}
							
			dl_func ( (void *)&pAMISetFirewallReq->State,(void *) &pAMISetFirewallReq->CMD_INFO.Port_Data );		
			break;
			
		case PORT_RANGE_Release: 
			dl_func =  dlsym( dl_handle, "release_range_port" );
			if(NULL == dl_func)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}
			
			dl_func ( (void *)&pAMISetFirewallReq->State,(void *) &pAMISetFirewallReq->CMD_INFO.Port_Range);
			break;
			
		case FLUSH:
			dl_func = dlsym (dl_handle, "flush_iptables");
			if ( NULL == dl_func )
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}
			
			dl_func ( (void *) NULL, (void *)NULL );
			break;
/*			
		case ENABLE_ALL:
			dl_func = dlsym (dl_handle, "enable_all");
			if ( NULL == dl_func )
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}
			dl_func ( (void *) NULL );
			break;
*/			
		case DISABLE_ALL:
			if ( pAMISetFirewallReq->CMD_INFO.Block > 3 || pAMISetFirewallReq->CMD_INFO.Block == 0)
			{
				IPMI_ERROR("Invalid data\n");
				*pRes = CC_INV_DATA_FIELD;
				dlclose(dl_handle);
				return sizeof(INT8U);
			}

            OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel);
			SetPendStatus(PEND_OP_SET_BLOCK_ALL,PEND_STATUS_PENDING);
			PostPendTask(PEND_OP_SET_BLOCK_ALL, (INT8U *)&pAMISetFirewallReq->CMD_INFO.Block, sizeof(INT8U),*curchannel & 0xF,BMCInst);
			break;

		case REMOVE_DISABLE_ALL:
			if ( pAMISetFirewallReq->CMD_INFO.Unblock > 3 || pAMISetFirewallReq->CMD_INFO.Unblock == 0)
			{
				IPMI_ERROR("Invalid data\n");
				*pRes = CC_INV_DATA_FIELD;
				dlclose(dl_handle);
				return sizeof(INT8U);
			}

			dl_block = dlsym (dl_handle, "remove_block_all");
			if ( NULL == dl_block)
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(dl_handle);
				return 0;
			}
			dl_block ( (void *)&pAMISetFirewallReq->CMD_INFO.Unblock);
			break;

		default:	
			pAMISetFirewallRes->CompletionCode = CC_PARAM_NOT_SUPPORTED;
	}

    dlclose (dl_handle);

    pAMISetFirewallRes->CompletionCode = CC_SUCCESS;

    return sizeof(AMISetFirewallRes_T);
}


/**
 * @fn AMIGetFirewall
 * @brief This function is used to Get the iptables rules
 * @param Request message and Command Info 
 */
int AMIGetFirewall ( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes ,int BMCInst )
{
	_NEAR_ AMIGetFirewallReq_T *pAMIGetFirewallReq = ( _NEAR_ AMIGetFirewallReq_T *) pReq;
	_NEAR_ AMIGetFirewallRes_T *pAMIGetFirewallRes = ( _NEAR_ AMIGetFirewallRes_T *) pRes;

	int retVal=0;

        if(g_corefeatures.system_firewall_support != CORE_FEATURE_ENABLED)
        {
            pAMIGetFirewallRes->CCParam.CompletionCode = CC_INV_CMD;
            return sizeof(INT8U);
        }

	if(0x02 > pAMIGetFirewallReq->Param  )   //Max known Firewall paramter
	{
	    if ((ReqLen-1) != GetFirewallConfigParamLength [pAMIGetFirewallReq->Param ])
	    {	    	
	        *pRes = CC_REQ_INV_LEN;
	        TDBG("Your entered Parameter %d is not a valid data \n",pAMIGetFirewallReq->Param);
	        return sizeof (INT8U);
	    }
	    else
	    {
	    	TDBG("Your entered Parameter %d is a valid data... \n",pAMIGetFirewallReq->Param);
	    }
    }
	
    void *dl_handle = NULL;
    int ( *dl_func )( void * ,void * )=NULL;
    int ( *dl_func0 )()=NULL;    
	
	dl_handle = dlopen ( "/usr/local/lib/libiptables.so", RTLD_NOW ); 
	if(NULL == dl_handle)
	{
		IPMI_ERROR("Error in loading libiptables.so library %s\n", dlerror() );
		return -1;
	}
		
	switch( pAMIGetFirewallReq->Param )
	{
	
		case GET_IPTABLE_COUNT: 
			
			dl_func0 = dlsym (dl_handle, "get_iptable_count");
			if ( NULL == dl_func0 )
			{
			    IPMI_ERROR("Error in getting symbol %s \n", dlerror());
			    dlclose(pAMIGetFirewallRes);
			    return -1;
			}
			pAMIGetFirewallRes->FWInfo.TotalCount= dl_func0 ();
			break;
		
		case GET_ENTRY_INFO:
			
			dl_func = dlsym (dl_handle, "get_iptable_entry");
			if ( NULL == dl_func )
			{
				IPMI_ERROR("Error in getting symbol %s \n", dlerror());
				dlclose(pAMIGetFirewallRes);
				return CC_PARAM_NOT_SUPPORTED;
			}
			retVal = dl_func ( (INT8U *)&pAMIGetFirewallReq->EntryNo, (INT8U *)&pAMIGetFirewallRes->FWInfo.Info );
		    if(retVal == -1)
			{
                pAMIGetFirewallRes->CCParam.CompletionCode = CC_INV_DATA_FIELD;
                return sizeof(INT8U); 
            }
			break;
			
        case IS_BLOCK_ALL:
			dl_func0 = dlsym (dl_handle, "IsBlockAllEnabled");
			if ( NULL == dl_func0 )
			{
			    IPMI_ERROR("Error in getting symbol %s \n", dlerror());
			    dlclose(pAMIGetFirewallRes);
			    return -1;
			}
			retVal = dl_func0();
			if(retVal != -1)
			{
			    pAMIGetFirewallRes->FWInfo.IsBlockAll=retVal; 
			}
			else
			{
			    pAMIGetFirewallRes->FWInfo.IsBlockAll=0; 
			}
            break;
				
		default:
			pAMIGetFirewallRes->CCParam.CompletionCode = CC_PARAM_NOT_SUPPORTED;
			return sizeof(INT8U); 
	}
	
	dlclose (dl_handle);
	pAMIGetFirewallRes->CCParam.CompletionCode = CC_SUCCESS;
	
	if( pAMIGetFirewallReq->Param == GET_IPTABLE_COUNT)
	{
		return sizeof(GetFWCC_T)+sizeof(INT8U);
	}
	else if( pAMIGetFirewallReq->Param == IS_BLOCK_ALL)
	{
		return sizeof(GetFWCC_T)+sizeof(INT8U);
	}    
	else
	{
	    return sizeof(GetFWCC_T) + sizeof(pAMIGetFirewallRes->FWInfo.Info.TYPE) + FirewallConfigParamLength[pAMIGetFirewallRes->FWInfo.Info.TYPE];
    }
}


int
AMISetSNMPConf( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_ AMISetSNMPConfRes_T *pAMISetSNMPConfRes = (_NEAR_ AMISetSNMPConfRes_T *)pRes;
    _NEAR_ AMISetSNMPConfReq_T * snmpcfg = (_NEAR_ AMISetSNMPConfReq_T*)pReq;
    void *dl_snmphandle = NULL;
    int ( *dl_snmpadduser )( char*,char*,INT8U,INT8U,INT8U)=NULL;
    int ( *dl_snmpdeluser)()=NULL;
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    _FAR_   UserInfo_T*             pUserInfo;	
    INT8U    PwdEncKey[MAX_SIZE_KEY] = {0};
    char Tmp_UserName[MAX_USERNAME_LEN+1]={0};
    char User_password[MAX_PASSWORD_LEN]={0};
    char Tmp_Password[MAX_PASSWORD_LEN+1]={0};
    memset(Tmp_UserName,0,sizeof(Tmp_UserName));
    memset(Tmp_Password,0,sizeof(Tmp_Password));
    
    if (snmpcfg->UserID == 0)
    {
        pAMISetSNMPConfRes->CompletionCode = CC_INV_DATA_FIELD ;
        return  sizeof (*pRes);
    }

    pUserInfo = getUserIdInfo(snmpcfg->UserID, BMCInst);
    if(pUserInfo == NULL)
    {
	 pAMISetSNMPConfRes->CompletionCode = CC_INV_DATA_FIELD ;
        return  sizeof (*pRes);
    }
    
    if(snmpcfg->UserID != pUserInfo->UserId)
    {
         pAMISetSNMPConfRes->CompletionCode = CC_INV_DATA_FIELD ;
         return  sizeof (*pRes);   	
    }
    
    memcpy(Tmp_UserName,pUserInfo->UserName,MAX_USERNAME_LEN);
    Tmp_UserName[strlen(Tmp_UserName)] = '\0';

    if(*Tmp_UserName == '\0')
    {
    	pAMISetSNMPConfRes->CompletionCode = CC_NULL_USERID_NOT_SUPPORTED ;
        return  sizeof (*pRes);
    } 
    
    if (g_corefeatures.userpswd_encryption == ENABLED)
    {
        /* Get Encryption Key from the MBMCInfo_t structure */
        LOCK_BMC_SHARED_MEM(BMCInst);
            memcpy(PwdEncKey, &(g_MBMCInfo.PwdEncKey), MAX_SIZE_KEY);
        UNLOCK_BMC_SHARED_MEM(BMCInst);

        if(DecryptPassword((INT8S *)(pBMCInfo->EncryptedUserInfo[snmpcfg->UserID - 1].EncryptedPswd), MAX_PASSWORD_LEN, User_password, MAX_PASSWORD_LEN, PwdEncKey))
        {
            *pRes = CC_UNSPECIFIED_ERR;
            return sizeof(*pRes);
        }		
	    memcpy(Tmp_Password,User_password,MAX_PASSWORD_LEN);
        Tmp_Password[strlen(Tmp_Password)] = '\0';
    }
    else
    {
	    memcpy(Tmp_Password,pUserInfo->UserPassword,MAX_PASSWORD_LEN);
        Tmp_Password[strlen(Tmp_Password)] = '\0';
    }	

    if(g_corefeatures.snmp_support == ENABLED)
    {
        dl_snmphandle = dlopen (SNMP_LIBS,RTLD_NOW);
        if(NULL == dl_snmphandle)
        {
            IPMI_ERROR("Error in loading libsnmpuser.so library %s\n", dlerror() );
            return -1;
        }
        //only add to SNMP Config if snmp is enabled for the user
        if (snmpcfg->snmp_enable == 1){
            dl_snmpadduser = dlsym (dl_snmphandle, "SNMPAddUser");
            if ( NULL == dl_snmpadduser)
            {
                IPMI_ERROR("Error in getting symbol %s \n", dlerror());
                dlclose(dl_snmphandle);
            return -1;
            }
            if((dl_snmpadduser)((char *)Tmp_UserName,(char *)Tmp_Password, snmpcfg->snmp_access_type, snmpcfg->snmp_enc_type_1, snmpcfg->snmp_enc_type_2)!=0) 
            {
                *pRes = CC_INV_DATA_FIELD;
                 return sizeof(*pRes);
            }
        } else if (snmpcfg->snmp_enable == 0){
            dl_snmpdeluser = dlsym (dl_snmphandle, "SNMPDelUser");
            if ( NULL == dl_snmpdeluser)
            {
                IPMI_ERROR("Error in getting symbol %s \n", dlerror());
                dlclose(dl_snmphandle);
                return -1;
            }
            (dl_snmpdeluser)((char *)Tmp_UserName);//if the username exists in the snmpcfg, needs to be deleted
        } else {
            *pRes = CC_INV_DATA_FIELD;
             return sizeof(*pRes);
        }
        pAMISetSNMPConfRes->CompletionCode = CC_SUCCESS;
        dlclose(dl_snmphandle);

        return(sizeof(AMISetSNMPConfRes_T));
    }
    else
    {
        *pRes = CC_INV_CMD;
        return sizeof(*pRes);
    }
}

int AMIGetSNMPConf( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    _NEAR_ AMIGetSNMPConfRes_T *pAMIGetSNMPConfRes = (_NEAR_ AMIGetSNMPConfRes_T *)pRes;
    _NEAR_ AMIGetSNMPConfReq_T * snmpcfg = (_NEAR_ AMIGetSNMPConfReq_T*)pReq;
    void *dl_snmphandle = NULL;
    int ( *dl_snmpgetuser)(char *,INT8U *,INT8U *,INT8U *,INT8U *)=NULL;
    INT8U snmp_enable,snmp_access_type,snmp_enc_type_1,snmp_enc_type_2;
    _FAR_   UserInfo_T*             pUserInfo;
    char Tmp_UserName[MAX_USERNAME_LEN+1]={0};
    memset(Tmp_UserName,0,sizeof(Tmp_UserName));
    
    if (snmpcfg->UserID == 0)
    {
        pAMIGetSNMPConfRes->CompletionCode = CC_INV_DATA_FIELD ;
        return  sizeof (*pRes);
    }

    pUserInfo = getUserIdInfo(snmpcfg->UserID, BMCInst);
    if(pUserInfo == NULL)
    {
	    pAMIGetSNMPConfRes->CompletionCode = CC_INV_DATA_FIELD ;
        return  sizeof (*pRes);
    }

    if(snmpcfg->UserID != pUserInfo->UserId)
    {
         pAMIGetSNMPConfRes->CompletionCode = CC_INV_DATA_FIELD ;
         return  sizeof (*pRes);   	
    }
	
    memcpy(Tmp_UserName,pUserInfo->UserName,MAX_USERNAME_LEN);
    Tmp_UserName[strlen(Tmp_UserName)] = '\0';

    if(*Tmp_UserName == '\0')
    {
    	pAMIGetSNMPConfRes->CompletionCode = CC_NULL_USERID_NOT_SUPPORTED ;
        return  sizeof (*pRes);
    } 

    if(g_corefeatures.snmp_support == ENABLED)
    {
        dl_snmphandle = dlopen (SNMP_LIBS,RTLD_NOW);
        if(NULL == dl_snmphandle)
        {
            IPMI_ERROR("Error in loading libsnmpuser.so library %s\n", dlerror() );
            return -1;
        }

        dl_snmpgetuser = dlsym (dl_snmphandle,"SNMPGetUser");
        if ( NULL == dl_snmpgetuser)
        {
           IPMI_ERROR("Error in getting symbol %s \n", dlerror());
           dlclose(dl_snmphandle);
           return -1;
        }

        dl_snmpgetuser((char *)Tmp_UserName, &snmp_enable, &snmp_access_type, &snmp_enc_type_1, &snmp_enc_type_2);
        pAMIGetSNMPConfRes->CompletionCode = CC_SUCCESS;
        pAMIGetSNMPConfRes->UserID = snmpcfg->UserID;
        pAMIGetSNMPConfRes->snmp_enable = snmp_enable;
        pAMIGetSNMPConfRes->snmp_access_type = snmp_access_type;
        pAMIGetSNMPConfRes->snmp_enc_type_1 = snmp_enc_type_1;
        pAMIGetSNMPConfRes->snmp_enc_type_2 = snmp_enc_type_2;

        dlclose(dl_snmphandle);
        return(sizeof(AMIGetSNMPConfRes_T));
    }
    else
    {
        *pRes = CC_INV_CMD;
        return sizeof(*pRes);
    }
}


/**
 * @fn AMIGetSELPolicy
 * @brief This function returns current SEL policy.
 * @param Request message and BMC instance
 * @return Current SEL policy
 */
int
AMIGetSELPolicy (_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    _NEAR_ AMIGetSELPolicyRes_T* pAMIGetSELPolicyRes = (_NEAR_ AMIGetSELPolicyRes_T*)pRes;
    BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];

    OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SELConfig.SELMutex, WAIT_INFINITE);
    pAMIGetSELPolicyRes->CompletionCode = CC_NORMAL;
    pAMIGetSELPolicyRes->SELPolicy = pBMCInfo->AMIConfig.CircularSEL;
    OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SELConfig.SELMutex);

    return sizeof(AMIGetSELPolicyRes_T);
}


/**
 * @fn AMISetSELPolicy
 * @brief This function sets current SEL policy.
 * @param Request message and BMC instance
 * @return Success completion code
 */
int
AMISetSELPolicy (_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    _NEAR_ AMISetSELPolicyRes_T* pAMISetSELPolicyRes = (_NEAR_ AMISetSELPolicyRes_T*)pRes;
    BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];

    if(g_corefeatures.circular_sel == ENABLED)
    {
        _NEAR_ AMISetSELPolicyReq_T* pAMISetSELPolicyReq = (_NEAR_ AMISetSELPolicyReq_T*)pReq;

        OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SELConfig.SELMutex, WAIT_INFINITE);
        /* Validate SEL policy */
        if (pAMISetSELPolicyReq->SELPolicy != LINEAR_SEL && pAMISetSELPolicyReq->SELPolicy != CIRCULAR_SEL)
        {
            pAMISetSELPolicyRes->CompletionCode = CC_INV_DATA_FIELD;
            OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SELConfig.SELMutex);
            return sizeof(*pRes);
        }
    
        SetSELPolicy(pAMISetSELPolicyReq->SELPolicy, BMCInst);
    
        pAMISetSELPolicyRes->CompletionCode = CC_NORMAL;
        OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SELConfig.SELMutex);
        return sizeof(AMISetSELPolicyRes_T);
    }
    else
    {
        /* If Circular SEL feature is disabled in Project Configuration, return Not Support In Current State code. */
        pAMISetSELPolicyRes->CompletionCode = CC_PARAM_NOT_SUP_IN_CUR_STATE;
        return sizeof(*pRes);
    }
}


/*
*@fn AMIGetSELEntires
*@param This function retrieves the SEL entries
*@return Returns CC_NORMAL
*/
int AMIGetSELEntires(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    AMIGetSELEntriesReq_T *pAMIGetSelEntriesReq = (AMIGetSELEntriesReq_T *)pReq;
    AMIGetSELEntriesRes_T *pAMIGetSelEntiresRes = (AMIGetSELEntriesRes_T *)pRes;
    BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];
    SELRepository_T *m_sel = NULL;
    INT16U NumRecords = 0;

    if(g_corefeatures.del_sel_reclaim_support != ENABLED)
    {
         m_sel = (SELRepository_T*)GetSDRSELNVRAddr((pBMCInfo->IpmiConfig.SDRAllocationSize * 1024), BMCInst);
         NumRecords = m_sel->NumRecords;
    }
    else
    {
         NumRecords = pBMCInfo->SELReclaimRepos.pSELReclaimInfo->NumRecords;
    }

    OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SELConfig.SELMutex, WAIT_INFINITE);
    if(((NumRecords - pAMIGetSelEntriesReq->Noofentretrieved) * sizeof(SELRec_T)) < MAX_FULL_SEL_ENTRIES)
    {
        pAMIGetSelEntiresRes->Status = FULL_SEL_ENTRIES;
        pAMIGetSelEntiresRes->Noofentries = NumRecords - pAMIGetSelEntriesReq->Noofentretrieved;
    }
    else if(NumRecords == SEL_EMPTY_REPOSITORY)
    {
        pAMIGetSelEntiresRes->CompletionCode = OEMCC_SEL_EMPTY_REPOSITORY;
        OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SELConfig.SELMutex);
        return sizeof(*pRes);
    }
    else if (NumRecords < pAMIGetSelEntriesReq->Noofentretrieved)
    {
        pAMIGetSelEntiresRes->CompletionCode = OEMCC_SEL_CLEARED;
        OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SELConfig.SELMutex);
        return sizeof(*pRes);
    }
    else
    {
        pAMIGetSelEntiresRes->Status = PARTIAL_SEL_ENTRIES;
        pAMIGetSelEntiresRes->Noofentries = ((MAX_FULL_SEL_ENTRIES - sizeof(AMIGetSELEntriesRes_T))/sizeof(SELRec_T));
    }


   if(g_corefeatures.del_sel_reclaim_support != ENABLED)
   {
        memcpy((INT8U*)(pAMIGetSelEntiresRes + 1),(INT8U*)&m_sel->SELRecord[pAMIGetSelEntriesReq->Noofentretrieved],
                  sizeof(SELRec_T)*pAMIGetSelEntiresRes->Noofentries);
   }
   else
   {

      CopySELReclaimEntries(&(SEL_RECLAIM_HEAD_NODE(BMCInst)),(INT8U *)(pAMIGetSelEntiresRes+1),
                                              pAMIGetSelEntriesReq->Noofentretrieved,pAMIGetSelEntiresRes->Noofentries,BMCInst);
   }

    pAMIGetSelEntiresRes->LastRecID = BMC_GET_SHARED_MEM(BMCInst)->m_LastRecID;

    pAMIGetSelEntiresRes->CompletionCode = CC_NORMAL;
    OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SELConfig.SELMutex);

    return sizeof(AMIGetSELEntriesRes_T) + (sizeof(SELRec_T) * pAMIGetSelEntiresRes->Noofentries);
}

/**
 * @fn AMIGetSensorInfo
 * @brief This function Gets all the Sensor Info needed for Web.
 * @param Request message and BMC instance
 * @return Proper completion code
 */
int AMIGetSenforInfo(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    AMIGetSensorInfoRes_T *pAMIGetSensorInfoRes = (AMIGetSensorInfoRes_T *)pRes;
    BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];
    INT8U*   pValidSensor = NULL;
    INT16U       SensorIndex = 0;
    SensorInfo_T    pSensor ;
    SenInfo_T       SensorInfo;
    BOOL SensorIsSigned = FALSE;
    INT16U SensorReading = 0;
    SensorSharedMem_T*    pSMSharedMem;
    _FAR_  SDRRecHdr_T*     pSDRRec;
    _FAR_ FullSensorRec_T*      FullSDR;
    _FAR_ CompactSensorRec_T*   CompSDR;
    int i = 0;

    /* Get the Sensor Shared Memory */
    pSMSharedMem = (_FAR_ SensorSharedMem_T*)&pBMCInfo->SensorSharedMem;

    if(pBMCInfo->SenConfig.ValidSensorCnt == 0)
    {
        pAMIGetSensorInfoRes->CompletionCode = OEMCC_SENSOR_INFO_EMPTY;
        return sizeof(*pRes);
    }

    OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->m_hSMSharedMemMutex, SHARED_MEM_TIMEOUT);
    pValidSensor = (INT8U*)(pAMIGetSensorInfoRes+1);
    for(i = 0; i < pBMCInfo->SenConfig.ValidSensorCnt; i++)
    {
        SensorIndex = pBMCInfo->SenConfig.ValidSensorList[i];
        pSensor = pSMSharedMem->SensorInfo[SensorIndex];

        /*Copy the SDR Header*/
        memcpy(&SensorInfo.hdr,pSensor.SDRRec,sizeof(SDRRecHdr_T));

        SensorInfo.SensorNumber = pSensor.SensorNumber;
        SensorInfo.SensorTypeCode = pSensor.SensorTypeCode;
        SensorInfo.EventTypeCode = pSensor.EventTypeCode;

        SensorInfo.Units1 = pSensor.Units1;
        SensorInfo.Units2 = pSensor.Units2;
        SensorInfo.Units3 = pSensor.Units3;

        SensorInfo.M_LSB = pSensor.M_LSB;
        SensorInfo.M_MSB_Tolerance = pSensor.M_MSB_Tolerance;
        SensorInfo.B_LSB = pSensor.B_LSB;
        SensorInfo.B_MSB_Accuracy = pSensor.B_MSB_Accuracy;
        SensorInfo.Accuracy_MSB_Exp = pSensor.Accuracy_MSB_Exp;
        SensorInfo.RExp_BExp = pSensor.RExp_BExp;

        SensorInfo.LowerNonCritical = pSensor.LowerNonCritical;
        SensorInfo.LowerCritical = pSensor.LowerCritical;
        SensorInfo.LowerNonRecoverable = pSensor.LowerNonRecoverable;
        SensorInfo.UpperNonCritical = pSensor.UpperNonCritical;
        SensorInfo.UpperCritical = pSensor.UpperCritical;
        SensorInfo.UpperNonRecoverable= pSensor.UpperNonRecoverable;
        SensorInfo.Settable_Readable_ThreshMask= pSensor.SettableThreshMask;

        SensorInfo.Flags = pSensor.EventFlags & 0xe0;
        if((pSensor.EventFlags & BIT5) != 0)
        {
            SensorInfo.SensorReading = 0;
        }

        SensorReading = pSensor.SensorReading;
        SensorInfo.SensorReading = 0;
        SensorIsSigned = ( 0 != (pSensor.InternalFlags & BIT1));

        if (THRESHOLD_SENSOR_CLASS  == pSensor.EventTypeCode)
        {
            SensorInfo.SensorReading = (SensorReading & 0x00FF);
            SensorInfo.ComparisonStatus = 0;
            if((pSensor.DeassertionEventEnablesByte2 & BIT6) == BIT6 )
            {
                if (CompareValues(SensorIsSigned, SensorInfo.SensorReading, pSensor.UpperNonRecoverable) >= 0)
                {
                    SensorInfo.ComparisonStatus |= BIT5;
                }
            }
            if((pSensor.DeassertionEventEnablesByte2 & BIT5) == BIT5 )
            {
                if (CompareValues(SensorIsSigned, SensorInfo.SensorReading, pSensor.UpperCritical) >= 0)
                {
                    SensorInfo.ComparisonStatus |= BIT4;
                }
            }
            if((pSensor.DeassertionEventEnablesByte2 & BIT4) == BIT4 )
            {
                if (CompareValues(SensorIsSigned, SensorInfo.SensorReading, pSensor.UpperNonCritical) >= 0)
                {
                    SensorInfo.ComparisonStatus |= BIT3;
                }
            }
            if((pSensor.AssertionEventEnablesByte2 & BIT6) == BIT6 )
            {
                if (CompareValues(SensorIsSigned, SensorInfo.SensorReading, pSensor.LowerNonRecoverable) <= 0)
                {
                    SensorInfo.ComparisonStatus |= BIT2;
                }
            }
            if((pSensor.AssertionEventEnablesByte2 & BIT5) == BIT5 )
            {
                if (CompareValues(SensorIsSigned, SensorInfo.SensorReading, pSensor.LowerCritical) <= 0)
                {
                    SensorInfo.ComparisonStatus |= BIT1;
                }
            }
            if((pSensor.AssertionEventEnablesByte2 & BIT4) == BIT4 )
            {
                if (CompareValues(SensorIsSigned, SensorInfo.SensorReading, pSensor.LowerNonCritical) <= 0)
                {
                    SensorInfo.ComparisonStatus |= BIT0;
                }
            }

            SensorInfo.ComparisonStatus &= ((pSensor.SettableThreshMask >>  8) & 0xFF);
            SensorInfo.OptionalStatus = 0;
            // For Threshold sensor, [7:6] - reserved. Returned as 1b. Ignore on read.
            SensorInfo.ComparisonStatus |= THRESHOLD_RESERVED_BIT;
        }
        else
        {
            SensorInfo.ComparisonStatus = (((INT8U) (SensorReading & 0x00FF)) & ((INT8U) (pSensor.SettableThreshMask & 0x00FF)) );
            SensorInfo.OptionalStatus   = (((INT8U) (SensorReading >> 8)) & ((INT8U) (pSensor.SettableThreshMask >> 8)) );
            // For Discrete sensor, [7] - reserved. Returned as 1b. Ignore on read.
            SensorInfo.OptionalStatus  |= DISCRETE_RESERVED_BIT;
        }

        if((pSensor.EventFlags & BIT7) == 0)
        {
            SensorInfo.AssertionEventByte1 = 0;
            SensorInfo.AssertionEventByte2 = 0;
            SensorInfo.DeassertionEventByte1 = 0;
            SensorInfo.DeassertionEventByte2 = 0;
        }
        if((pSensor.SensorCaps & BIT6) == 0)
        {
             SensorInfo.AssertionEventByte1    = (pSensor.AssertionHistoryByte1 & pSensor.AssertionEventEnablesByte1);
             SensorInfo.AssertionEventByte2    = (pSensor.AssertionHistoryByte2 & pSensor.AssertionEventEnablesByte2);
             SensorInfo.DeassertionEventByte1    = (pSensor.DeassertionHistoryByte1 & pSensor.DeassertionEventEnablesByte1);
             SensorInfo.DeassertionEventByte2    = (pSensor.DeassertionHistoryByte2 & pSensor.DeassertionEventEnablesByte2);
        }
        else
        {
             SensorInfo.AssertionEventByte1    = (pSensor.AssertionEventOccuredByte1 & pSensor.AssertionEventEnablesByte1);
             SensorInfo.AssertionEventByte2    = (pSensor.AssertionEventOccuredByte2 & pSensor.AssertionEventEnablesByte2);
             SensorInfo.DeassertionEventByte1    = (pSensor.DeassertionEventOccuredByte1 & pSensor.DeassertionEventEnablesByte1);
             SensorInfo.DeassertionEventByte2    = (pSensor.DeassertionEventOccuredByte2 & pSensor.DeassertionEventEnablesByte2);
        }
        pSDRRec = GetSDRRec(pSensor.SDRRec->ID,BMCInst);
        if(pSensor.SDRRec->Type  == FULL_SDR_REC)       /*Full SDR*/
        {
            FullSDR = (_FAR_ FullSensorRec_T *)pSDRRec;
            SensorInfo.OwnerID = FullSDR->OwnerID;
            SensorInfo.OwnerLUN= FullSDR->OwnerLUN;
            SensorInfo.MaxReading = FullSDR->MaxReading;
            SensorInfo.MinReading = FullSDR->MinReading;
            SensorInfo.Linearization = FullSDR->Linearization;
            memset(SensorInfo.SensorName,0,MAX_ID_STR_LEN);
            strncpy(SensorInfo.SensorName,FullSDR->IDStr, MAX_ID_STR_LEN - (sizeof(FullSensorRec_T) - sizeof(SDRRecHdr_T) - FullSDR->hdr.Len));
        }
        else if(pSensor.SDRRec->Type == COMPACT_SDR_REC)   /*Compact SDR*/
        {
            CompSDR = (_FAR_ CompactSensorRec_T *)pSDRRec;
            SensorInfo.OwnerID = CompSDR->OwnerID;
            SensorInfo.OwnerLUN= CompSDR->OwnerLUN;
            SensorInfo.MaxReading = 0;
            SensorInfo.MinReading = 0;
            SensorInfo.Linearization = 0;
            memset(SensorInfo.SensorName,0,MAX_ID_STR_LEN);
            strncpy(SensorInfo.SensorName,CompSDR->IDStr, MAX_ID_STR_LEN - (sizeof(CompactSensorRec_T) - sizeof(SDRRecHdr_T) - CompSDR->hdr.Len));
        }
        memcpy(pValidSensor,(INT8U *)&SensorInfo,sizeof(SenInfo_T));
        pValidSensor = pValidSensor + sizeof(SenInfo_T);
    }
    OS_THREAD_MUTEX_RELEASE(&pBMCInfo->m_hSMSharedMemMutex);

    pAMIGetSensorInfoRes->CompletionCode = CC_NORMAL;
    pAMIGetSensorInfoRes->Noofentries = pBMCInfo->SenConfig.ValidSensorCnt;

    return sizeof(AMIGetSensorInfoRes_T) + (sizeof(SenInfo_T) * pBMCInfo->SenConfig.ValidSensorCnt);

}

/**
 * @fn AMIGetIPMISessionTimeOut
 * @brief This function Gets IPMI session timeout.
 * @param Request message and BMC instance
 * @return Proper completion code
 */
int AMIGetIPMISessionTimeOut(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    AMIGetIPMISessionTimeOutRes_T * pAMIGetIPMISessionTimeOutRes = (AMIGetIPMISessionTimeOutRes_T *)pRes;
    /* Chk request Length */
    if( ReqLen != 0 )
    {
        *pRes = CC_REQ_INV_LEN;
        return sizeof (INT8U);
    }
    BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];
    pAMIGetIPMISessionTimeOutRes->IPMISessionTimeOut = pBMCInfo->IpmiConfig.SessionTimeOut;
    pAMIGetIPMISessionTimeOutRes->CompletionCode = CC_NORMAL;
    return sizeof( AMIGetIPMISessionTimeOutRes_T );
}

/**
 * @fn AMIGetUDSInfo
 * @brief This function Gets UDS Info for Requesting IP's.
 * @param IPV4/IPV6 Address and BMC instance
 * @return Channel Number,BMC Instance and Completion Code
 */
int AMIGetUDSInfo(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    AMIGetUDSInfoReq_T *pAMIGetUDSInfoReq = (AMIGetUDSInfoReq_T *)pReq;
    AMIGetUDSInfoRes_T *pAMIGetUDSInfoRes = (AMIGetUDSInfoRes_T *)pRes;
    int ChannelNum = -1;
    INT8U NoofBMC = 1;
    _FAR_   ChannelInfo_T*          pChannelInfo;

    for(NoofBMC = 1;NoofBMC <= MAX_NUM_BMC; NoofBMC++)
    {
         ChannelNum = GetChannelByAddr((char *)&pAMIGetUDSInfoReq->SessionIPAddr[0],NoofBMC);
         if(ChannelNum == -1)
         {
             if(g_corefeatures.global_ipv6  == ENABLED)
             {
                 ChannelNum = GetChannelByIPv6Addr((char *)&pAMIGetUDSInfoReq->SessionIPAddr[0], NoofBMC);
                 if(ChannelNum != -1)
                 {
                     TDBG("IPV6 Address Found and Channel Number is %x\n",ChannelNum);
                     break;
                 }
             }
         }
         else
         {
             TDBG("IPV4 Address Found and Channel Number is %d\n",ChannelNum);
             break;
         }
    }

    if(ChannelNum != -1)
    {
        pChannelInfo = getChannelInfo(ChannelNum,NoofBMC);
        if(NULL == pChannelInfo)
        {
            *pRes = CC_INV_DATA_FIELD;
            return  sizeof (*pRes);
        }

        pAMIGetUDSInfoRes->CompletionCode = CC_NORMAL;
        pAMIGetUDSInfoRes->ChannelNum = ChannelNum;
        pAMIGetUDSInfoRes->ChannelType = pChannelInfo->ChannelType;
        pAMIGetUDSInfoRes->BMCInstance = NoofBMC;
    }
    else 
    {    
        pAMIGetUDSInfoRes->CompletionCode = CC_INV_DATA_FIELD;
        return sizeof(INT8U);
    }        
    return sizeof(AMIGetUDSInfoRes_T);
}   

/**
 * @fn AMIGetUDSSessionInfo
 * @brief This function Gets UDS Session Info for Requesting Session Handle
 *        /Session Index/Session ID.
 * @param Parameter Selector and BMC instance
 * @return UDS Session Information and Completion Code
 */
int AMIGetUDSSessionInfo(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    AMIGetUDSSessionInfoReq_T *pAMIGetUDSSessionInfoReq = (AMIGetUDSSessionInfoReq_T *)pReq;
    AMIGetUDSSessionInfoRes_T *pAMIGetUDSSessionInfoRes = ( AMIGetUDSSessionInfoRes_T *)pRes;
    UDSSessionTbl_T *pUDSSessionTblInfo = NULL;
    INT8U ArgType =0xFF;
    BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];
    INT8U Index,ResLen;

    if( ReqLen != UDSSessionInfoParamLength[pAMIGetUDSSessionInfoReq->UDSSessionParam])
    {
        *pRes = CC_REQ_INV_LEN;
         return sizeof(*pRes);
    }

    pAMIGetUDSSessionInfoRes->CompletionCode = CC_NORMAL;

    switch(pAMIGetUDSSessionInfoReq->UDSSessionParam)
    {

        case UDS_SESSION_COUNT_INFO:
            pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSSessionCountInfo.MaxAllowedSession = pBMCInfo->IpmiConfig.MaxSession;
            pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSSessionCountInfo.ActiveSessionCount = pBMCInfo->UDSSessionTblInfo.SessionCount;
            return sizeof(INT8U )+sizeof(UDSSessionCount_T);

        case UDS_SESSION_ID_INFO:
            ArgType = UDS_SESSION_ID_INFO;
            break;

        case UDS_SESSION_HANDLE_INFO:
            ArgType = UDS_SESSION_HANDLE_INFO;
            break;

        case UDS_SESSION_INDEX_INFO:
            ArgType = UDS_SESSION_INDEX_INFO;
            break;

         case UDS_SOCKET_ID_INFO:
            ArgType = UDS_SOCKET_ID_INFO;
            break;

         case UDS_SESSION_PID_INFO:
             ArgType = UDS_SESSION_INDEX_INFO;
             pUDSSessionTblInfo = GetUDSSessionInfo(ArgType,(void *)&pAMIGetUDSSessionInfoReq->UDSSessionHandleOrIDOrIndex[0],BMCInst);
             if(NULL == pUDSSessionTblInfo)
             {
                 *pRes =CC_INV_DATA_FIELD;
                 return sizeof(*pRes);
             }
             pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSSessionPIDInfo.ProcessID = ipmitoh_u32(pUDSSessionTblInfo->ProcessID);
             pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSSessionPIDInfo.ThreadID = ipmitoh_u32(pUDSSessionTblInfo->ThreadID);
             return sizeof(INT8U )+sizeof(UDSSessionPIDInfo_T);
             break;

         case UDS_ACTIVE_SESSION_INDEX_LIST:
             pRes[0] = CC_NORMAL;
             for(Index = 0, ResLen = 1; Index < pBMCInfo->IpmiConfig.MaxSession; Index++)
             {
                 if(FALSE == pBMCInfo->UDSSessionTblInfo.UDSSessionTbl[Index].Activated)
                 {
                     continue;
                 }
                 pRes[ResLen] = Index;
                 ResLen++;
             }
             return ResLen;
             break;

         default:
            *pRes=CC_INV_DATA_FIELD;
            return sizeof (*pRes);

     }

     pUDSSessionTblInfo = GetUDSSessionInfo(ArgType,(void *)&pAMIGetUDSSessionInfoReq->UDSSessionHandleOrIDOrIndex[0],BMCInst);
     if(NULL == pUDSSessionTblInfo)
     {
         *pRes =CC_INV_DATA_FIELD;
         return sizeof(*pRes);
     }

     /* Filling up the required Session Related Response for the requested Session ID/Session Handle/Session Index */
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.LoggedInSessionID = pUDSSessionTblInfo->SessionID;
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.LoggedInSessionHandle = pUDSSessionTblInfo->LoggedInSessionHandle;
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.LoggedInTime = pUDSSessionTblInfo->LoggedInTime;
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.LoggedInUserID = pUDSSessionTblInfo->LoggedInUserID;
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.LoggedInPrivilege = pUDSSessionTblInfo->LoggedInPrivilege;
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.AuthenticationMechanism = pUDSSessionTblInfo->AuthenticationMechanism;
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.UDSChannelNum = pUDSSessionTblInfo->UDSChannelNum;
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.ChannelNum = pUDSSessionTblInfo->LoggedInChannel;
     pAMIGetUDSSessionInfoRes->UDSLoggedInInfo.UDSLoggedInSessionInfo.SessionTimeoutValue = pUDSSessionTblInfo->SessionTimeoutValue;

     return sizeof(INT8U)+sizeof(UDSLoggedInSessionInfo_T);
}

/**
* @fn RISServiceStatus
 * @brief This function Gets Remote Image service feature supported and enable informations
 */
int 
RISServiceStatus()
{
    VMediaCfg_T media_cfg;
     int ServiceErr = 0;

     /*Check for Feature is supported*/
    if(ENABLED != g_corefeatures.rmedia_support )
    {
         TCRIT("Remote Images Service is Not Supported\n");
         return CC_INV_CMD;
    }

    memset(&media_cfg, 0, sizeof(VMediaCfg_T));
    ServiceErr = GetVMediaCfg(&media_cfg,g_corefeatures.lmedia_support,g_corefeatures.rmedia_support);
    if(ServiceErr < 0)
    {
        TCRIT("Error in Getting Vmedia Configuration\n");
        return CC_UNSPECIFIED_ERR;
    }
    /*Check for RIS Sevice is Enabled*/
    if(ENABLED != media_cfg.rmedia_enable )
    {
         TCRIT("Remote Images Service is Not Enabled\n");
         return CC_SERVICE_NOT_ENABLED;
    }
    return  CC_SUCCESS;

}

/**
* @fn RISSetServiceStatus
 * @brief This function Sets Remote Image service feature supported and enable informations
 */
int 
RISSetServiceStatus(INT8U Status)
{
    VMediaCfg_T media_cfg;
     int ServiceErr = 0;

     /*Check for Feature is supported*/
    if(ENABLED != g_corefeatures.rmedia_support )
    {
         TCRIT("Remote Images Service is Not Supported\n");
         return CC_INV_CMD;
    }

    memset(&media_cfg, 0, sizeof(VMediaCfg_T));
    ServiceErr = GetVMediaCfg(&media_cfg,g_corefeatures.lmedia_support,g_corefeatures.rmedia_support);
    if(ServiceErr < 0)
    {
        TCRIT("Error in Getting Vmedia Configuration\n");
        return CC_UNSPECIFIED_ERR;
    }
    /*Check for RIS Sevice Status*/
    if(Status != media_cfg.rmedia_enable )
    {
        media_cfg.rmedia_enable = Status;
        ServiceErr = SetVMediaCfg(&media_cfg,g_corefeatures.lmedia_support,g_corefeatures.rmedia_support);
        if(ServiceErr < 0)
        {
            TCRIT("Error in Getting Vmedia Configuration\n");
            return CC_UNSPECIFIED_ERR;
        }
    }
    return  CC_SUCCESS;

}
/**
 * @fn AMIGetRISConf
 * @brief This function Gets Remote Image service configuration Info for Requesting Session Handle
 *		  /Session Index/Session ID.
 * @param Parameter Selector
 * @return Remote Image service configuration Information and Completion Code
 */
int
AMIGetRISConf( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{

    _NEAR_  AMIGetRISConfReq_T*  pAMIGetRISConfReq = (_NEAR_ AMIGetRISConfReq_T*) pReq;
    _NEAR_  AMIGetRISConfRes_T*  pAMIGetRISConfRes = (_NEAR_ AMIGetRISConfRes_T*) pRes;
    MediaCfg_T conf;
    INT32U  Value = 0;
    INT8U  MediaTypeBit = 0;
    int ServiceErr = 0;

    /* Match the service_id byte with ServiceName */
    Value = (pAMIGetRISConfReq->MediaType);

    ServiceErr = GetINT32UBitsNum (Value, &MediaTypeBit);
    if(ServiceErr < 0)
    {
        TCRIT("Error in getting bit number from service_id\n");
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }

    if(ServiceList[MediaTypeBit] == NULL)
    {
        TCRIT("MediaName is not found in ServiceList\n");
        *pRes = CC_INVALID_MEDIA_TYPE;
        return sizeof (INT8U);
    }

     /*Check for Feature is supported*/ 
    if(ENABLED != g_corefeatures.rmedia_support )
    {
        TCRIT("Remote Images Service is Not Supported\n");
        *pRes = CC_INV_CMD;
        return sizeof (INT8U);
    }  
    ServiceErr = GetMediaCfg(&conf,ServiceList[MediaTypeBit]);
    if(ServiceErr < 0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
    memset(pAMIGetRISConfRes, 0, sizeof(AMIGetRISConfRes_T));
    pAMIGetRISConfRes->MediaType= pAMIGetRISConfReq->MediaType;
    pAMIGetRISConfRes->ParameterSelect= pAMIGetRISConfReq->ParameterSelect;
    pAMIGetRISConfRes->CompletionCode = CC_SUCCESS;
    switch(pAMIGetRISConfReq->ParameterSelect)
    {
        case RIS_IMAGE_NAME:
            _fmemcpy(pAMIGetRISConfRes->Config.ImageName, conf.Image_Name,MAX_IMAGE_NAME_LEN);
            return (sizeof(AMIGetRISConfRes_T) - sizeof(RISConfig_T) + MAX_IMAGE_NAME_LEN);
        case RIS_REMOTE_PATH:
            _fmemcpy(pAMIGetRISConfRes->Config.MountPath, conf.Image_Path,MAX_IMAGE_PATH_SIZE);
            return (sizeof(AMIGetRISConfRes_T) - sizeof(RISConfig_T) + MAX_IMAGE_PATH_SIZE);
        case RIS_IP_ADDR:
            _fmemcpy(pAMIGetRISConfRes->Config.RemoteIP, conf.Ip_Addr,MAX_IP_ADDR_LEN);
            return (sizeof(AMIGetRISConfRes_T) - sizeof(RISConfig_T) + MAX_IP_ADDR_LEN);
        case RIS_USER_NAME: 
            _fmemcpy(pAMIGetRISConfRes->Config.UserName, conf.Username,MAX_RMS_USERNAME_LEN);
            return (sizeof(AMIGetRISConfRes_T) - sizeof(RISConfig_T) + MAX_RMS_USERNAME_LEN);
        case RIS_PASSWORD:
        	// Should not expose password don't enable below line
            //_fmemcpy(pAMIGetRISConfRes->Config.Password, conf.Password,MAX_RMS_PASSWORD_LEN);
            return (sizeof(AMIGetRISConfRes_T) - sizeof(RISConfig_T) + MAX_RMS_PASSWORD_LEN);
        case RIS_SHARE_TYPE:
            _fmemcpy(pAMIGetRISConfRes->Config.ShareType, conf.Share_Type,MAX_SHARE_TYPE_LEN);
            return (sizeof(AMIGetRISConfRes_T) - sizeof(RISConfig_T) + MAX_SHARE_TYPE_LEN);
        case RIS_DOMAIN:
            _fmemcpy(pAMIGetRISConfRes->Config.Domain, conf.Domain,MAX_DOMAIN_LEN);
            return(MAX_DOMAIN_LEN+3);
        default:
        	pAMIGetRISConfRes->CompletionCode = CC_PARAM_NOT_SUPPORTED;
            return sizeof(INT8U);
    }
}
/**
 * @fn VerifyData
 * @brief This function checks for presence of multiple string in the given array
 * @param Data
 * @return 0 on success and -1 on failure
 */
int VerifyData(INT8S *Data)
{
	int trace;
	for( trace=MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK;trace>=0;trace--) /*Finds last Non-NULL Char from last*/
	{
		if(Data[trace]!='\0')
		break;
	}

	if(trace==-1)
	{
		TDBG("String does't have any NULL termination\n");
		return trace;
	}
	if(trace+1==strlen(Data))
	{
		return 0;
	}
	else
	{
		TDBG("First NULL at =%d, Last NULL at =%d,String =%s\n",strlen(Data),trace+1,Data);
		return -1;
	}
	
}

/**
 * @fn SetBlockData
 * @brief This function sets Block of data nad progress bit
 * @param Request message  BMCShared memory parameter bit , data , BMC instance  ,errcode, Datalen
 * @outparam ValidData
 * @return success completion code 
 */
int 
SetBlockData(AMISetRISConfReq_T*  Req,INT8U *SharedBit,INT8U *SharedData,int BMCInst,INT8U ErrCode,INT8S *ValidData, int Datalen)
{
    struct addrinfo *pResult;
    INT8U RetVal = CC_SUCCESS;
    /* Progress Bit From Shared Memory*/
    INT8U ProgressBit = *SharedBit ;

    /*If Blockselector is zero .its for setting ProgressBit*/
    if( 0x0 == Req->Blockselector  )
    {
        /*Validate ProgressBit*/
        if( ( SET_COMPLETE != Req->config.ProgressBit) && ( SET_IN_PROGRESS != Req->config.ProgressBit) )
        {
            RetVal = CC_INV_PROGRESS_BIT;
        }
        /* Valid Progress BIt .Process the request*/
        else
        {
            /*  ProgressBit  and request progressBit are equal*/
            if(Req->config.ProgressBit == ProgressBit)
            {
                /* ProgressBit is Already set as SET_IN_PROGRESS Dont allow to set data*/
                if(( SET_IN_PROGRESS == ProgressBit ) &&
                ( SET_IN_PROGRESS == Req->config.ProgressBit ))
                {
                    RetVal = CC_SET_IN_PROGRESS;
                }
                /* IF SET_COMPLETE Bit  is set already send success code as response*/
                else if(( SET_COMPLETE == ProgressBit ) &&
                ( SET_COMPLETE == Req->config.ProgressBit ))
                {
                    memset(SharedData,0,MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK);
                    RetVal = CC_SUCCESS;
                }
            }
            /* Allow ProgressBit to set if both are not equal*/
            else
            {
                /* Update the progress bit*/
                LOCK_BMC_SHARED_MEM(BMCInst);
                *SharedBit =  Req->config.ProgressBit;
                UNLOCK_BMC_SHARED_MEM(BMCInst);

                /* IF SET_COMPLETE Bit is set write data from shared memory to file*/
                if(SET_COMPLETE == Req->config.ProgressBit )
                {
                    _fmemcpy(ValidData,SharedData,(MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK)+1);
                    memset(SharedData,0,MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK);

                    if(0 != strlen(ValidData))
                    {
                        /*Validation Completed  Write data to file*/
                        RetVal =  WRITE_TO_FILE;

                        if(Req->ParameterSelect == RIS_DOMAIN)
                        {
                            if (0 != getaddrinfo((char *)ValidData, NULL, NULL, &pResult))
                            {
                                RetVal = CC_INVALID_DOMAIN;
                            }
                        }
                    }
                    else
                    {
                        RetVal = ErrCode ;
                    }
                }
                /* IF SET_IN_PROGRESS Bit is send success code as response*/
                else
                {
                    RetVal = CC_SUCCESS;
                }
            }
        }
    }
    /*If Blockselector is 1 to 4 .its for setting data*/
    else if(( Req->Blockselector  > 0x0) && ( Req->Blockselector  <= MAX_BLOCK) )
    {
        /* SET_IN_PROGRESS BIT is not set.Dont allow to set data*/
        if(SET_IN_PROGRESS != ProgressBit)
        {
            RetVal = CC_PROGRESS_BIT_NOT_SET;
        }
        /* SET_IN_PROGRESS BIT is set. Update data inShared memory*/
        else
        {
            LOCK_BMC_SHARED_MEM(BMCInst);
            memset(SharedData+(MAX_DOMAIN_BLOCK_SIZE * (Req->Blockselector - 1)), 0,MAX_DOMAIN_BLOCK_SIZE);
            switch(Req->ParameterSelect)
            {
                case RIS_IMAGE_NAME:
                    _fmemcpy( SharedData+(MAX_DOMAIN_BLOCK_SIZE * (Req->Blockselector - 1)),Req->config.ImageName,Datalen);
                    break;
				
                case RIS_REMOTE_PATH:
                    _fmemcpy( SharedData+(MAX_DOMAIN_BLOCK_SIZE * (Req->Blockselector - 1)),Req->config.MountPath,Datalen);
                    break;
                case RIS_USER_NAME:
                    _fmemcpy( SharedData+(MAX_DOMAIN_BLOCK_SIZE * (Req->Blockselector - 1)),Req->config.UserName,Datalen);
                    break;
                case RIS_DOMAIN:
                    _fmemcpy( SharedData+(MAX_DOMAIN_BLOCK_SIZE * (Req->Blockselector - 1)),Req->config.Domain,Datalen);
                    break;
                default:
                    break;
            }
            UNLOCK_BMC_SHARED_MEM(BMCInst);
        }
    }
    else 
    {
        RetVal = CC_INVALID_BLOCK_SELECTOR;
    }
    return RetVal;
}

/**
 * @fn AMISetRISConf
 * @brief This function sets the RIS configurations
 * @param Parameter selector and Request message and BMC instance
 * @return success completion code 
 */
int
AMISetRISConf( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMISetRISConfReq_T*  pAMISetRISConfReq = (_NEAR_ AMISetRISConfReq_T*) pReq;
    _NEAR_  AMISetRISConfRes_T*  pAMISetRISConfRes = (_NEAR_ AMISetRISConfRes_T*) pRes;

    MediaCfg_T      conf;
    INT32U  Value = 0;
    INT8U       ServiceTypeBit = 0;
    int ServiceErr = 0;
    int DataLen = 0;
    INT8U       MediaType = 0;
    INT8U       done = 0;
    INT8S       IPV4[sizeof(struct in_addr)];
    INT8        IPV6[sizeof(struct in6_addr)];
    INT8S       IPAddr[MAX_IP_ADDR_LEN];
    INT8U       ValidIP = 0;
    INT8S       *EndsWith = NULL;
    INT8U       EndsWithLen = 0;
    INT8U       ValidImage = 0;
    INT8S       ValidData[MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK+1];

    /* Match the service_id byte with ServiceName */
    Value = (pAMISetRISConfReq->MediaType);
    ServiceErr = GetINT32UBitsNum (Value, &ServiceTypeBit);
    if(ServiceErr < 0)
    {
        TCRIT("Error in Getting Bit Number from Service ID\n");
        if (ReqLen <=0)
            *pRes = CC_REQ_INV_LEN;
        else
            *pRes = CC_UNSPECIFIED_ERR;

        return sizeof (INT8U);
    }
    else
    {
        if ( ReqLen >=  ServiceLen[ServiceTypeBit])
        {
            DataLen = ReqLen -  ServiceLen[ServiceTypeBit];
        }
        else
        {
            *pRes = CC_REQ_INV_LEN;
            return sizeof (INT8U);
        }
    }

    if(ServiceList[ServiceTypeBit] == NULL)
    {
        TCRIT("Service Name Not Available for the Requested Service ID\n");
        *pRes = CC_INVALID_MEDIA_TYPE;
        return sizeof (INT8U);
    }

    /* Enable/Disable Remote Images Service*/
    if(0 == memcmp(ServiceList[ServiceTypeBit],RMS_SET,strlen(RMS_SET)))
    {
         /* Check For parameter Field length*/
        if(DataLen  > 0)
        {
            *pRes = CC_REQ_FIELD_LEN_EXCEEDED;
            return sizeof (INT8U);
        }

        /* Check for valid start/stop bit*/
        if ((pAMISetRISConfReq->ParameterSelect != RIS_START) && (pAMISetRISConfReq->ParameterSelect != RIS_STOP ))
        {
            *pRes = CC_INVALID_COMMAND;
            return sizeof (INT8U);
        }

         /* Set  RIS Status*/  
         ServiceErr = RISSetServiceStatus(pAMISetRISConfReq->ParameterSelect);
         *pRes = ServiceErr;
         return sizeof (INT8U);
    }

    /*Validate the Block selector*/
    if( 0 != pAMISetRISConfReq->Blockselector
                && (pAMISetRISConfReq->ParameterSelect != RIS_IMAGE_NAME )		
                && (pAMISetRISConfReq->ParameterSelect != RIS_REMOTE_PATH )
                && (pAMISetRISConfReq->ParameterSelect != RIS_USER_NAME)
                && (pAMISetRISConfReq->ParameterSelect != RIS_DOMAIN))
    {
        *pRes = CC_INV_DATA_FIELD;
        return sizeof(INT8U);
    }
    
    if((pAMISetRISConfReq->Blockselector==0)
        		    && (pAMISetRISConfReq->ParameterSelect != RIS_IP_ADDR )
        		    && (pAMISetRISConfReq->ParameterSelect != RIS_PASSWORD )
        		    && (pAMISetRISConfReq->ParameterSelect !=RIS_SHARE_TYPE )
        		    && (ReqLen!=4))
           {
           	*pRes = CC_REQ_INV_LEN;
               return sizeof (INT8U);
           }
    
    /* Check For RIS support*/  
    ServiceErr = RISServiceStatus();
    if(ServiceErr != 0)
    {
        *pRes = ServiceErr;
        return sizeof (INT8U);
    }

     /* Check For parameter Field length*/
    if(DataLen <=0)
    {
        *pRes = CC_REQ_INV_LEN;
        return sizeof (INT8U);
    }
    else if (DataLen > ServiceParamLength [pAMISetRISConfReq->ParameterSelect ])
    {
        *pRes = CC_REQ_FIELD_LEN_EXCEEDED;
        TDBG("Your entered Parameter %d is not a valid data \n",pAMISetRISConfReq->ParameterSelect);
        return sizeof (INT8U);
    }
    else
    {
        TDBG("Your entered Parameter %d is a valid data... \n",pAMISetRISConfReq->ParameterSelect);
    }

    //set image name to particular service structure
    if(pAMISetRISConfReq->ParameterSelect == RIS_IMAGE_NAME)
    {	
        memset(ValidData,0,(MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK) + 1);
        *pRes = SetBlockData(pAMISetRISConfReq, &(BMC_GET_SHARED_MEM (BMCInst)->RISconf.ImageNameBit),&BMC_GET_SHARED_MEM (BMCInst)->RISconf.ImageName[0], BMCInst,CC_INVALID_IMAGE_FILE_NAME,ValidData, DataLen);
        if(*pRes  != WRITE_TO_FILE)
        {
            return sizeof (INT8U);
        }
	if(VerifyData(ValidData)==-1)
        {	
		*pRes = CC_INVALID_IMAGE_FILE_NAME;
        	return sizeof (INT8U);
	    }
        EndsWith = strrchr(ValidData, '.');
        
        if( EndsWith != NULL )
        {
        	EndsWithLen = strlen(EndsWith); 

            if( EndsWithLen != strlen(".iso") )
            {
                  *pRes = CC_INVALID_IMAGE_FILE_NAME;
                  return sizeof (INT8U);
            }
            if(0 == memcmp(ServiceList[ServiceTypeBit],RMS_CD_SECTION_NAME,strlen(RMS_CD_SECTION_NAME)))
            {
                if((0 == memcmp(EndsWith, ".iso",EndsWithLen))  || ( 0 == memcmp(EndsWith, ".ISO",EndsWithLen)))
                    ValidImage = 1;
            }
            else
            {
                if((0 == memcmp(EndsWith, ".img",EndsWithLen))  || ( 0 == memcmp(EndsWith, ".IMG",EndsWithLen)))
                    ValidImage = 1;
            }
        }
        if ((EndsWith == NULL ) || ( !ValidImage ))
        {
            *pRes = CC_INVALID_IMAGE_FILE_NAME;
            return sizeof (INT8U);
        }

        MediaType = ServiceTypeBit;
        done = 1;
    }
    else if(pAMISetRISConfReq->ParameterSelect == RIS_REMOTE_PATH)
    {
        memset(ValidData,0,MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK);
        *pRes = SetBlockData(pAMISetRISConfReq, &(BMC_GET_SHARED_MEM (BMCInst)->RISconf.MountPathBit),&BMC_GET_SHARED_MEM (BMCInst)->RISconf.MountPath[0], BMCInst,CC_INVALID_IMG_PATH,ValidData, DataLen);
        if(*pRes  != WRITE_TO_FILE)
        {
            return sizeof (INT8U);
        }
	if(VerifyData(ValidData)==-1)
        {
		*pRes = CC_INVALID_IMG_PATH;
        	return sizeof (INT8U);
        }
    }
    else if(pAMISetRISConfReq->ParameterSelect == RIS_USER_NAME)
    {
        memset(ValidData,0,MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK);
        *pRes = SetBlockData(pAMISetRISConfReq, &(BMC_GET_SHARED_MEM (BMCInst)->RISconf.UserNameBit),&BMC_GET_SHARED_MEM (BMCInst)->RISconf.UserName[0], BMCInst,CC_INVALID_USR_NAME,ValidData, DataLen);
        if(*pRes  != WRITE_TO_FILE)
        {
            return sizeof (INT8U);
        }
	if(VerifyData(ValidData)==-1)
        {
		*pRes = CC_INVALID_USR_NAME;
        	return sizeof (INT8U);
        }
    }
    else if(pAMISetRISConfReq->ParameterSelect == RIS_PASSWORD)
    {
        pAMISetRISConfReq->config.Password[DataLen]='\0';
        if(0 == strlen(pAMISetRISConfReq->config.Password))
        {
            *pRes = CC_INVALID_PASSWD;
            return sizeof (INT8U);
        }
    }
    else if(pAMISetRISConfReq->ParameterSelect == RIS_SHARE_TYPE)
    {   
        pAMISetRISConfReq->config.ShareType[DataLen]='\0';
        if(0 == strlen(pAMISetRISConfReq->config.ShareType))
        {
            *pRes = CC_INVALID_SHARE_TYPE;
            return sizeof (INT8U);
        }

        if((strncmp(pAMISetRISConfReq->config.ShareType, SHARE_TYPE_NFS,DataLen) == 0) ||
            (strncmp(pAMISetRISConfReq->config.ShareType, SHARE_TYPE_CIFS,DataLen) == 0) )
        {

        }
        else
        {
            *pRes = CC_INVALID_SHARE_TYPE;
            return sizeof (INT8U);
        }
    }
    else if(pAMISetRISConfReq->ParameterSelect == RIS_IP_ADDR)
    {
	pAMISetRISConfReq->config.RemoteIP[DataLen]='\0';
	if(0 == strlen(pAMISetRISConfReq->config.RemoteIP))
        {
            *pRes = CC_INVALID_IP_ADDR;
            return sizeof (INT8U);
        }

        memset(IPAddr,0,MAX_IP_ADDR_LEN);
        _fmemcpy(IPAddr,pAMISetRISConfReq->config.RemoteIP,DataLen);
        
        if (inet_pton (AF_INET6, IPAddr, (char*)IPV6))
        {
            ValidIP ++;
        }

        if ( inet_pton (AF_INET, IPAddr, (char*)IPV4))
        {
            ValidIP ++;
        }

        if( !ValidIP)
        {
            *pRes = CC_INVALID_IP_ADDR;
            return sizeof (INT8U);
        }
    }
    else if(pAMISetRISConfReq->ParameterSelect == RIS_DOMAIN)
    {
        memset(ValidData,0,MAX_DOMAIN_BLOCK_SIZE*MAX_BLOCK);
        *pRes = SetBlockData(pAMISetRISConfReq, &(BMC_GET_SHARED_MEM (BMCInst)->RISconf.DomainNameBit),&BMC_GET_SHARED_MEM (BMCInst)->RISconf.DomainName[0], BMCInst,CC_INVALID_DOMAIN,ValidData, DataLen);
        if(*pRes  != WRITE_TO_FILE)
        {
            return sizeof (INT8U);
        }
	if(VerifyData(ValidData)==-1)
        {
		*pRes = CC_INVALID_DOMAIN;
        	return sizeof (INT8U);
	    }
    }

    pAMISetRISConfRes->CompletionCode = CC_SUCCESS;
    /*ParameterSelect is other then RIS_IMAGE_NAME need to set it for CD,FD,HD structure*/
    do
    {
        memset(&conf,0,sizeof(MediaCfg_T));
        ServiceErr = GetMediaCfg(&conf,ServiceList[MediaType]);
        if(ServiceErr < 0)
        {
            *pRes = CC_UNSPECIFIED_ERR;
            return sizeof (INT8U);
        }

        switch (pAMISetRISConfReq->ParameterSelect)
        {
            case RIS_IMAGE_NAME:
                memset(conf.Image_Name ,0,MAX_IMAGE_NAME_LEN);
                _fmemcpy(conf.Image_Name,ValidData,strlen(ValidData)+1);
                break;
            case RIS_REMOTE_PATH:
                memset(conf.Image_Path ,0,MAX_IMAGE_PATH_SIZE);
                _fmemcpy(conf.Image_Path,ValidData,strlen(ValidData)+1);
                break;
            case RIS_IP_ADDR:
                memset(conf.Ip_Addr,0,MAX_IP_ADDR_LEN );
                _fmemcpy(conf.Ip_Addr,pAMISetRISConfReq->config.RemoteIP,DataLen);
                break;
            case RIS_USER_NAME:
                memset(conf.Username,0,MAX_RMS_USERNAME_LEN );
                _fmemcpy(conf.Username,ValidData,strlen(ValidData)+1);
                break;
            case RIS_PASSWORD:
                memset(conf.Password,0,MAX_RMS_PASSWORD_LEN );
                _fmemcpy(conf.Password,pAMISetRISConfReq->config.Password,DataLen);
                break;
            case RIS_SHARE_TYPE:
                memset(conf.Share_Type,0,MAX_SHARE_TYPE_LEN );
                _fmemcpy(conf.Share_Type,pAMISetRISConfReq->config.ShareType,DataLen);
                break;
            case RIS_DOMAIN:
                memset(conf.Domain,0,MAX_DOMAIN_LEN);
                _fmemcpy(conf.Domain,ValidData,strlen(ValidData)+1);
                break;
            default:
                pAMISetRISConfRes->CompletionCode = CC_PARAM_NOT_SUPPORTED;
                return sizeof(INT8U);
        }

        ServiceErr = SetMediaCfg(&conf,ServiceList[MediaType]);
        if(ServiceErr < 0)
        {
            *pRes = CC_UNSPECIFIED_ERR;
            return sizeof (INT8U);
        }

        /*Stop the service only if its running*/    
        if(1 == conf.Start_Mount )
        {
            ServiceErr = RMediaStartAndStop(ServiceParam[MediaType], RIS_STOP );
            if(ServiceErr < 0)
            {
                *pRes = CC_UNSPECIFIED_ERR;
                return sizeof (INT8U);
            }
        }
        MediaType++;
    }while((MediaType  <  MAX_SERVICE_COUNT)  &&  (!done));

    return(sizeof(AMISetServiceConfRes_T));
}

int
AMIRISStartStop( _NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMIRISStartStopReq_T*  pAMIRISStartStopReq = (_NEAR_ AMIRISStartStopReq_T*) pReq;
    _NEAR_  AMIRISStartStopRes_T*  pAMIRISStartStopRes = (_NEAR_ AMIRISStartStopRes_T*) pRes;

    MediaCfg_T conf;
    INT32U Value = 0;
    INT8U MediaTypeBit = 0;
    int ServiceErr = 0;

    if ( ReqLen < 2 )
    {
        *pRes = CC_REQ_INV_LEN;
        return sizeof (INT8U);
    }

    /* Match the service_id byte with ServiceName */
    Value = (pAMIRISStartStopReq->MediaType);
    ServiceErr = GetINT32UBitsNum (Value, &MediaTypeBit);
    if(ServiceErr < 0)
    {
        TCRIT("Error in Getting Bit Number from Service ID\n");
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }

    if(ServiceList[MediaTypeBit] == NULL)
    {
        TCRIT("Service Name Not Available for the Requested Service ID\n");
        *pRes = CC_INVALID_MEDIA_TYPE;
        return sizeof (INT8U);
    }

    /* Check For RIS support*/
    ServiceErr = RISServiceStatus();
    if(ServiceErr != 0)
    {
        *pRes = ServiceErr;
        return sizeof (INT8U);
    }

    if ((pAMIRISStartStopReq->ParameterSelect != RIS_START) && (pAMIRISStartStopReq->ParameterSelect != RIS_STOP ))
    {
        *pRes = CC_INVALID_COMMAND;
        return sizeof (INT8U);
    }

    memset(&conf,0,sizeof(MediaCfg_T));
    ServiceErr = GetMediaCfg(&conf,ServiceList[MediaTypeBit]);
    if(ServiceErr < 0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }

    /*Return  incase  minumum configuration is not met*/
    if((0 ==strlen(conf.Image_Name)) ||( 0 == strlen(conf.Image_Path )) ||( 0 ==strlen( conf.Ip_Addr)) ||( 0 == strlen(conf.Share_Type )))
    {
        *pRes = CC_INVALID_CONFIGURATION;
        return sizeof (INT8U);
    }

    /*If Request command start/stop bit and configuration start/stop bit are same */     
    if(pAMIRISStartStopReq->ParameterSelect  == conf.Start_Mount )
    {
        *pRes = CC_SUCCESS;
        return sizeof (INT8U);
    }

    ServiceErr = RMediaStartAndStop(ServiceParam[MediaTypeBit],pAMIRISStartStopReq->ParameterSelect );
    if(ServiceErr < 0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
    pAMIRISStartStopRes->CompletionCode = CC_SUCCESS;
    return(sizeof(AMIRISStartStopRes_T));   
}

/*---------------------------------------
 * AMIControlDebugMsg
 *---------------------------------------*/
int AMIControlDebugMsg(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    AMIControlDebugMsgReq_T *pAMIControlDebugMsgReq = (AMIControlDebugMsgReq_T *)pReq;
    AMIControlDebugMsgRes_T *pAMIControlDebugMsgRes = (AMIControlDebugMsgRes_T*)pRes;
    char Cmd[MAX_STRING_LEN] = {0};

    if(g_corefeatures.runtime_dbgmsg_support == ENABLED)
    {
        pAMIControlDebugMsgRes->CompletionCode = CC_NORMAL;
        if(pAMIControlDebugMsgReq->CtrlDebugMsg == 1)
        {
            snprintf(Cmd,sizeof(Cmd),"touch %s",ENABLE_DBG_MSG);
            safe_system(Cmd);
            pAMIControlDebugMsgRes->DebugMsgStatus = DEBUG_MSG_ENABLED;
        }
        else if(pAMIControlDebugMsgReq->CtrlDebugMsg == 0)
        {
            unlink(ENABLE_DBG_MSG);
            pAMIControlDebugMsgRes->DebugMsgStatus = DEBUG_MSG_DISABLED;
        }
        else
        {
            pAMIControlDebugMsgRes->CompletionCode = CC_INV_DATA_FIELD;
        }
        return sizeof(AMIControlDebugMsgRes_T);
    }
    else
    {
        *pRes = CC_INV_CMD;
        return sizeof(*pRes);
    }
}

/*---------------------------------------
 * AMIGetDebugMsgStatus
 *---------------------------------------*/
int AMIGetDebugMsgStatus(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    struct stat buff;
    AMIGetDebugMsgStatusRes_T *pAMIGetDebugMsgStatusRes = (AMIGetDebugMsgStatusRes_T *)pRes;

    if(g_corefeatures.runtime_dbgmsg_support == ENABLED)
    {
        if(stat(ENABLE_DBG_MSG,&buff) == 0)
        {
            pAMIGetDebugMsgStatusRes->DebugMsgStatus = DEBUG_MSG_ENABLED;
        }
        else
        {
            pAMIGetDebugMsgStatusRes->DebugMsgStatus = DEBUG_MSG_DISABLED;
        }
        pAMIGetDebugMsgStatusRes->CompletionCode = CC_NORMAL;
        return sizeof(AMIGetDebugMsgStatusRes_T);
    }
    else
    {
        *pRes = CC_INV_CMD;
        return sizeof(*pRes);
    }
    
}

/*
*@fn AMI_SET_EXTENDED_PRIV
*@brief This command helps to get users shell 
*               @param pReq   - Request for the command   
*               @param ReqLen - Request length for the command
*               @param pRes   - Respose for the command
*               @param BMCInst- BMC Instance
*               @return Returns size of AMIGetUserShelltypeRes_T
*/
int AMIGetExtendedPrivilege(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMISetExtendedPrivReq_T*       pGetExtendedprivReq = (_NEAR_ AMISetExtendedPrivReq_T*)pReq;
    _NEAR_  AMIGetExtendedPrivRes_T*       pGetExtendedprivRes = (_NEAR_ AMIGetExtendedPrivRes_T*)pRes;
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    _FAR_   UserInfo_T*             pUserInfo = NULL;
    INT8U   UserId=0;
    
    UserId = pGetExtendedprivReq->UserID & 0x3F;

    /*  if user ID exceeded the Max limit */
    if (pGetExtendedprivReq->UserID > pBMCInfo->IpmiConfig.MaxUsers)
    {
        pGetExtendedprivRes->CompletionCode = CC_INV_DATA_FIELD ;
        return  sizeof (*pRes);/* Invalied user id */
    }

    pUserInfo = getUserIdInfo(UserId, BMCInst);

    /* User with given ID is not created */
    if ( NULL == pUserInfo ) 
    {
        *pRes = CC_INV_DATA_FIELD;
        return sizeof (*pRes);
    }

    LOCK_BMC_SHARED_MEM(BMCInst);

    pGetExtendedprivRes->CompletionCode = CC_NORMAL;       
    pGetExtendedprivRes->Extendedpriv = pUserInfo->ExtendedPrivilege;

    UNLOCK_BMC_SHARED_MEM(BMCInst);

    return sizeof (AMIGetExtendedPrivRes_T);
}


/*
*@fn AMISetExtendedpriv
*@brief This command helps to set users shell 
*               @param pReq   - Request for the command   
*               @param ReqLen - Request length for the command
*               @param pRes   - Respose for the command
*               @param BMCInst- BMC Instance
*               @return Returns size of AMISetUserShelltypeRes_T
*/

int AMISetExtendedPrivilege(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMISetExtendedPrivReq_T*       pSetExtendedprivReq = (_NEAR_ AMISetExtendedPrivReq_T*)pReq;
     _FAR_   UserInfo_T*             pUserInfo = NULL;
    _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
    INT8U   UserId=0;
    INT32U  oldExtendedprivstatus =0;

    UserId    = pSetExtendedprivReq->UserID & 0x3F;
   
       
    /*  if user ID exceeded the Max limit */
    if (pSetExtendedprivReq->UserID > pBMCInfo->IpmiConfig.MaxUsers)
    {
        *pRes = CC_INV_DATA_FIELD ;
        return  sizeof (*pRes);/* Invalid user id */
    }

    if(pSetExtendedprivReq->Extendedpriv & INVALID_PRIV_REQUEST)
    {
        *pRes = CC_INV_DATA_FIELD ;
        return  sizeof (*pRes);/* Invalid Extended Privilege requested*/
    }
	
    pUserInfo = getUserIdInfo(UserId, BMCInst);
    
    /* If User is not created */
    if ( NULL == pUserInfo )
    {        
        *pRes = CC_INV_DATA_FIELD;
        return sizeof (*pRes);
    }   

    /* Skipping Updation If older and newer privilege same */
    if(pUserInfo->ExtendedPrivilege == pSetExtendedprivReq->Extendedpriv ) 
    {
        *pRes = CC_NORMAL;
        return sizeof (*pRes);
    }
  
    LOCK_BMC_SHARED_MEM(BMCInst);
    oldExtendedprivstatus = pUserInfo->ExtendedPrivilege;
    pUserInfo->ExtendedPrivilege =    pSetExtendedprivReq->Extendedpriv;
    
    if ( 0 != pUserInfo->UserName[0])
    {
        AddIPMIUsrtoFlagsGrp((char *)pUserInfo->UserName, oldExtendedprivstatus,  pUserInfo->ExtendedPrivilege);
    }
    UNLOCK_BMC_SHARED_MEM(BMCInst);
    FlushIPMI((INT8U*)&pBMCInfo->UserInfo[0],(INT8U*)&pBMCInfo->UserInfo[0],pBMCInfo->IPMIConfLoc.UserInfoAddr,
                      sizeof(UserInfo_T)*MAX_USER_CFG_MDS,BMCInst);
    
    *pRes = CC_NORMAL;
    return sizeof (*pRes);
}
/**
 * OnGethostlockvalue_dynm
 * @brief This method helpd to get the adviser configuration
 * @param AdviserCfg - adviserd conf structure
 */
int OnGethostlockvalue_dynm(int *hostlock_feature)
{
	void *dl_handle = NULL;
	int ( *dl_func )( void *);
	dl_handle = NULL;
	int retval =0;
	int value=0;
	
	dl_handle = dlopen ( "/usr/local/lib/libadvisercfg.so", RTLD_NOW ); 
	if(NULL == dl_handle)
	{
		return -1;
	}
	
	dl_func =  dlsym( dl_handle, "OnGethostlockfeature_dynm" );
	if(NULL == dl_func)
	{
		IPMI_ERROR("Error in getting symbol %s \n", dlerror());
		dlclose(dl_handle);
		return -1;
	}

	retval= dl_func ( (void *)&value);
	if(retval < 0)
		return retval;
	*hostlock_feature = value;
	return retval; 
}

/**
 * OnGethostlockvalue_dynm
 * @brief This method helpd to get the adviser configuration
 * @param AdviserCfg - adviserd conf structure
 */
int OnSethostlockvalue_dynm(int hostlock_feature)
{
	void *dl_handle = NULL;
	int ( *dl_func )( void *);
	dl_handle = NULL;
	int retval =0;
	
	dl_handle = dlopen ( "/usr/local/lib/libadvisercfg.so", RTLD_NOW ); 
	if(NULL == dl_handle)
	{
		return -1;
	}
	
	 dl_func =  dlsym( dl_handle, "OnSethostlockfeature_dynm" );
	if(NULL == dl_func)
	{
		IPMI_ERROR("Error in getting symbol %s \n", dlerror());
		dlclose(dl_handle);
		return -1;
	}

	retval= dl_func ( (void *)hostlock_feature);
	
	return retval; 
}


/*
*@fn AMIGetHostLockFeatureStatus
*@brief This command helps to get host monitor lock Feature status
*               @param pReq   - Request for the command   
*               @param ReqLen - Request length for the command
*               @param pRes   - Respose for the command
*               @param BMCInst- BMC Instance
*               @return Returns size of AMIGetHostLockFeatureStatusRes_T
*/
int AMIGetHostLockFeatureStatus(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
    AMIGetHostLockFeatureStatusRes_T  *pAMIGetHLFeatureStsRes = (AMIGetHostLockFeatureStatusRes_T *)pRes;
    int status =-1;
    int hostlockfeatureStatus=0;
   
	int retval=0;
	
	if(g_corefeatures.host_lock_feature != ENABLED)
	{
		*pRes = CC_INV_CMD;
		return sizeof (INT8U);
	}
	if ( ReqLen > 0 )
	{
		*pRes = CC_REQ_INV_LEN;
		return sizeof (INT8U);
	}
	retval = OnGethostlockvalue_dynm(&hostlockfeatureStatus);
	if(retval <0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
	status =  hostlockfeatureStatus & (1<<0);
    pAMIGetHLFeatureStsRes->LockFeatureStatus =status;
    pAMIGetHLFeatureStsRes->CompletionCode = CC_NORMAL;
    
    return sizeof(AMIGetHostLockFeatureStatusRes_T);
}

/*
*@fn AMISetHostLockFeatureStatus
*@brief This command helps to set host monitor lock feature
*               @param pReq   - Request for the command   
*               @param ReqLen - Request length for the command
*               @param pRes   - Respose for the command
*               @param BMCInst- BMC Instance
*               @return Returns completion code
*/
int AMISetHostLockFeatureStatus(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMISetHostLockFeatureStatusReq_T*       pAMISetHLFeatureStsReq = (_NEAR_ AMISetHostLockFeatureStatusReq_T*)pReq;
    
    int ret = -1;
    *pRes = CC_NORMAL;
    int status=0,hostlockfeatureStatus=0;
    INT8U *curchannel;
    RestartService_T Service;
       
    if(g_corefeatures.host_lock_feature != ENABLED)
	{
		 *pRes = CC_INV_CMD;
		return sizeof (INT8U);
	}
    // check incoming Feature status to Enable/Disable
    if ( (HLENABLED != pAMISetHLFeatureStsReq->LockFeatureStatus) && (HLDISABLED != pAMISetHLFeatureStsReq->LockFeatureStatus) )
    {
        *pRes = CC_INV_FEATURE_CMD;
        return sizeof (INT8U);
    }

    ret = OnGethostlockvalue_dynm(&hostlockfeatureStatus);
    if(ret <0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
   
    status = hostlockfeatureStatus & (1<<0);
    // check incoming lockstatus to same as existing
    if(status == pAMISetHLFeatureStsReq->LockFeatureStatus)
    {
           *pRes = CC_SUCCESS;
           return sizeof (INT8U);
    }
    
	if(pAMISetHLFeatureStsReq->LockFeatureStatus == 1)
	{
		hostlockfeatureStatus |= (1<<0);
	}
	else if(pAMISetHLFeatureStsReq->LockFeatureStatus == 0)
	{
		hostlockfeatureStatus &= ~(1 << 0);
	}
	ret = OnSethostlockvalue_dynm(hostlockfeatureStatus);
	if(ret < 0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
    else
    {
    	//Post BMC Reboot task to Pend task    
		Service.ServiceName = ADVISER_CONF;
		Service.SleepSeconds = 3;		// Sleep for 3 Seconds
		SetPendStatus(PEND_OP_RESTART_SERVICES, PEND_STATUS_PENDING);    
		OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel);
		PostPendTask(PEND_OP_RESTART_SERVICES, (INT8U *) &Service, sizeof(RestartService_T),*curchannel & 0xF,BMCInst);
    }
	*pRes = CC_NORMAL;
    return sizeof (*pRes);
}

/*
*@fn AMIGetHostLockStatus
*@brief This command helps to get host monitor lock status
*               @param pReq   - Request for the command   
*               @param ReqLen - Request length for the command
*               @param pRes   - Respose for the command
*               @param BMCInst- BMC Instance
*               @return Returns size of AMIGetHostLockStatusRes_T
*/
int AMIGetHostAutoLockStatus(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst)
{
	
    AMIGetHostAutoLockStatusRes_T  *pAMIGetHostLockStatusRes = (AMIGetHostAutoLockStatusRes_T *)pRes;
    int status =-1;
    int hostlockfeature=0,hostlockfeatureStatus=0;
    int ret=-1;
   
    if(g_corefeatures.host_auto_lock != ENABLED)
	{
		 *pRes = CC_INV_CMD;
		return sizeof (INT8U);
	}
    if ( ReqLen > 0 )
    {
        *pRes = CC_REQ_INV_LEN;
        return sizeof (INT8U);
    }
    
    ret = OnGethostlockvalue_dynm(&hostlockfeatureStatus);
    if(ret <0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
    
    hostlockfeature =  hostlockfeatureStatus & (1<<0);
    //If Host Lock Feature is Disabled return error code
    if(HLDISABLED == hostlockfeature)
    {
        *pRes = CC_FEATURE_NOT_ENABLED;
        return sizeof (INT8U);
    }
    status = hostlockfeatureStatus & (1<<1);
    if(status == (1<<1))
    {
    	pAMIGetHostLockStatusRes->LockStatus =1;
    }
    else
    	pAMIGetHostLockStatusRes->LockStatus =0;
    
    pAMIGetHostLockStatusRes->CompletionCode = CC_NORMAL;

    return sizeof(AMIGetHostAutoLockStatusRes_T);
}

/*@fn AMISetHostLockStatus
*@brief This command helps to set host monitor lock
*               @param pReq   - Request for the command   
*               @param ReqLen - Request length for the command
*               @param pRes   - Respose for the command
*               @param BMCInst- BMC Instance
*               @return Returns completion code
*/
int AMISetHostAutoLockStatus(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes,int BMCInst)
{
    _NEAR_  AMISetHostAutoLockStatusReq_T*       pAMISetHostLockStatusReq = (_NEAR_ AMISetHostAutoLockStatusReq_T*)pReq;

    int ret = -1;
    int hostlockfeature=0,hostlockfeatureStatus=0;
    int prev_autolock_status = 0;
    *pRes = CC_NORMAL;
    RestartService_T Service;
    INT8U *curchannel;
    
    if(g_corefeatures.host_auto_lock != ENABLED)
	{
		 *pRes = CC_INV_CMD;
		return sizeof (INT8U);
	}
    
    ret = OnGethostlockvalue_dynm(&hostlockfeatureStatus);
    if(ret <0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
    hostlockfeature =  hostlockfeatureStatus & (1<<0);
    //If Host Lock Feature is Disabled return error code
    if(HLDISABLED == hostlockfeature)
    {
        *pRes = CC_FEATURE_NOT_ENABLED;
        return sizeof (INT8U);
    }

    // check incoming lockstatus to lock/unlock
    if ( (HOSTLOCK_CMD !=pAMISetHostLockStatusReq->LockStatus) && (HOSTUNLOCK_CMD !=pAMISetHostLockStatusReq->LockStatus) )
    {
        *pRes = CC_INV_LOCK_CMD;
        return sizeof (INT8U);
    }
    prev_autolock_status = hostlockfeatureStatus & (1<<1);
    
    // check incoming lockstatus to same as existing
    if ( prev_autolock_status == pAMISetHostLockStatusReq->LockStatus)
    {
        *pRes = CC_SUCCESS;
        return sizeof (INT8U);
    }

    if(pAMISetHostLockStatusReq->LockStatus == 1)
    {
    	hostlockfeatureStatus |= (1<<1);
    }
    else if(pAMISetHostLockStatusReq->LockStatus == 0)
    {
    	hostlockfeatureStatus &= ~(1 << 1);
    }
    else
    {
    	*pRes = CC_INV_DATA_FIELD;
    	return sizeof (INT8U);
    }
   
    ret = OnSethostlockvalue_dynm(hostlockfeatureStatus);
    if(ret < 0)
    {
        *pRes = CC_UNSPECIFIED_ERR;
        return sizeof (INT8U);
    }
    else
    {
    	 //Post BMC Reboot task to Pend task    
    	 Service.ServiceName = ADVISER_CONF;
    	 Service.SleepSeconds = 3;		// Sleep for 3 Seconds
    	 SetPendStatus(PEND_OP_RESTART_SERVICES, PEND_STATUS_PENDING);    
    	 OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel);
    	 PostPendTask(PEND_OP_RESTART_SERVICES, (INT8U *) &Service, sizeof(RestartService_T),*curchannel & 0xF,BMCInst);
    }
    
    *pRes = CC_NORMAL;
    return sizeof (*pRes);
}

int AMIGetChannelType(_NEAR_ INT8U *pReq, INT32U ReqLen, _NEAR_ INT8U *pRes, int BMCInst) 
{ 
    _NEAR_ AMIGetChannelTypeReq_T *pAMIGetChTypeReq = (_NEAR_ AMIGetChannelTypeReq_T*)pReq; 
    _NEAR_ AMIGetChannelTypeRes_T *pAMIGetChTypeRes = (_NEAR_ AMIGetChannelTypeRes_T*)pRes; 
    BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; 
    _FAR_   ChannelInfo_T*  pChannelInfo; 
     
    if((pAMIGetChTypeReq->ChannelNumber & 0xF0) || (CURRENT_CHANNEL_NUM == pAMIGetChTypeReq->ChannelNumber)) 
    { 
        pAMIGetChTypeRes->CompletionCode = CC_INV_DATA_FIELD; 
        return sizeof(*pRes); 
    } 
     
    OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->ChUserMutex,WAIT_INFINITE); 
    pChannelInfo = getChannelInfo(pAMIGetChTypeReq->ChannelNumber, BMCInst); 
    if (NULL == pChannelInfo) 
    { 
        OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex); 
        pAMIGetChTypeRes->CompletionCode = CC_INV_DATA_FIELD ; 
        return  sizeof (*pRes); 
    } 
     
    pAMIGetChTypeRes->CompletionCode = CC_NORMAL; 
    pAMIGetChTypeRes->ChannelType = pChannelInfo->ChannelType; 
    pAMIGetChTypeRes->ChannelNumber = pAMIGetChTypeReq->ChannelNumber; 
     
    OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex); 
 
    return sizeof (AMIGetChannelTypeRes_T); 
} 
