/****************************************************************
 ****************************************************************
 **                                                            **
 **    (C)Copyright 2010-2011, American Megatrends Inc.        **
 **                                                            **
 **            All Rights Reserved.                            **
 **                                                            **
 **        5555 Oakbrook Pkwy, Building 200, Norcross,         **
 **                                                            **
 **        Georgia 30093, USA. Phone-(770)-246-8600.           **
 **                                                            **
 ****************************************************************
 ****************************************************************/
/*****************************************************************
 *
 * AMIBiosCode.c
 * 
 *
 * Author: Gokulakannan. S <gokulakannans@amiindia.co.in>
 *****************************************************************/


#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>

#include "Support.h"
#include "dbgout.h"
#include "PMConfig.h"
#include "NVRData.h"
#include "NVRAccess.h"
#include "IPMIDefs.h"
#include "SharedMem.h"
#include "IPMI_AMIBiosCode.h"
#include "AMIBiosCode.h"


#if AMI_GET_BIOS_CODE != UNIMPLEMENTED

static INT8U
ReadBiosCodes(int nCode, unsigned char *pCode, int *pLen)
{
	void *pHandle = NULL;
	int (*pGetBiosCode) ( unsigned char *, int );
	
	pHandle = dlopen("/usr/local/lib/libsnoop.so", RTLD_NOW);
	if (pHandle == NULL)
	{
		return CC_INV_CMD;
	}
	
	if (nCode == CURRENT)
	{
		pGetBiosCode = dlsym(pHandle, "ReadCurrentBiosCode");
	}
	else if (nCode == PREVIOUS)
	{
		pGetBiosCode = dlsym(pHandle, "ReadPreviousBiosCode");
	}
	else
	{
		dlclose (pHandle);
		return CC_INV_DATA_FIELD;
	}
	
	if (pGetBiosCode == NULL)
	{
		dlclose (pHandle);
		return CC_INV_CMD;
	}
	
	(*pLen) = pGetBiosCode(pCode, MAX_SIZE);

	/* Check whether the driver returned a INT number*/
	if ((*pLen) == -1)
	{
		TDBG("No Bios Codes Found \n");
		(*pLen) = 0;
		dlclose (pHandle);
		return OEMCC_FILE_ERR;
	}
	
#if 0
    printf("Bios Codes :\n");

    for(i=0;i<(*pLen);i++)
    {
        printf("%02X ", pCode[i]);
        if ((i>0) && (((i+1)%16)==0))
            printf("\n");
    }
    printf("\n");
#endif

    dlclose (pHandle);
    return CC_NORMAL;
}


/**
 * @fn AMIGetBiosCode
 * @brief Set the SOL Status.
 * @param[in] pReq - pointer to the request.
 * @param[in] ReqLen - Length of the request.
 * @param[out] pRes - pointer to the result.
 * @retval      CC_NORMAL, on success,
 *              CC_INV_DATA_FIELD, if invalid data in the request.
 */

int
AMIGetBiosCode (_NEAR_ INT8U* pReq, INT32U ReqLen, _NEAR_ INT8U* pRes, int BMCInst)
{
    AMIGetBiosCodeReq_T* pAMIGetBiosCodeReq  =  ( AMIGetBiosCodeReq_T* ) pReq;
    AMIGetBiosCodeRes_T* pAMIGetBiosCodeRes  =  ( AMIGetBiosCodeRes_T* ) pRes;
    int nLen = 0;

    memset (pAMIGetBiosCodeRes, 0x00, sizeof (AMIGetBiosCodeRes_T));
    pAMIGetBiosCodeRes->CompletionCode = ReadBiosCodes(pAMIGetBiosCodeReq->Command, pAMIGetBiosCodeRes->BiosCode, &nLen);

    // Length of the bioscode including the completion code.
    return (nLen + 1);
}

#endif
