/*****************************************************************
******************************************************************
***                                                            ***
***        (C)Copyright 2008, American Megatrends Inc.         ***
***                                                            ***
***                    All Rights Reserved                     ***
***                                                            ***
***       5555 Oakbrook Parkway, Norcross, GA 30093, USA       ***
***                                                            ***
***                     Phone 770.246.8600                     ***
***                                                            ***
******************************************************************
******************************************************************
******************************************************************
* 
* Filename: libipmi_IPM.c
*
* Descriptions: Contains implementation of Device specific
*   high level functions
*
* Author: Rajasekhar
*
******************************************************************/
#include "libipmi_IPM.h"


#include <string.h>

/**
\breif	Executes GetDeviceID IPMI command.
 @param	pSession		[in]Session handle
 @param	pGetDeviceID	[out]Device ID structure according to IPMI Spec
 @param	timeout			[in]timeout value in seconds.

 @retval Returns LIBIPMI_STATUS_SUCCESS on success and error codes on failure
*/
uint16_t	IPMICMD_GetDeviceID( IPMI20_UDS_SESSION_T *pUDSSession, GetDevIDRes_T	*pGetDeviceID, int timeout )
{
	uint8_t		Req [20];
	uint32_t		dwResLen;
	uint16_t		wRet;

	//dwResLen = sizeof(GetDevIDRes_T);
	wRet = LIBIPMI_Send_RAW_IPMI2_0_Command(pUDSSession, 
											DEFAULT_NET_FN_LUN, CMD_GET_DEV_ID,
											Req, 0,
											(uint8_t*)pGetDeviceID, &dwResLen,
											timeout);
	return wRet;
}

uint16_t	IPMC_GetDeviceID( IPMI20_UDS_SESSION_T *pUDSSession, uint8_t IpmbAddr, GetDevIDRes_T	*pGetDeviceID, int timeout )
{
	int wRet = 0;
	uint32_t	dwResLen;
	uint8_t 	Req[10] = {0};
	uint8_t		Res[100] = {0};

	Req[0] = 0x40;	//Track | channel 0
	Req[1] = IpmbAddr;
	Req[2] = NETFNLUN_IPMI_APP;
	Req[3] = 0x100 - (Req[1] + Req[2])&0xff;	//checksum1
	Req[4] = 0x20;
	Req[5] = 0x10;
	Req[6] = CMD_GET_DEV_ID;	
	Req[7] = 0x100 - (Req[4] + Req[5] + Req[6])&0xff;

	//dwResLen = sizeof(GetDevIDRes_T);
	wRet = LIBIPMI_Send_RAW_IPMI2_0_Command(pUDSSession, 
											DEFAULT_NET_FN_LUN, CMD_SEND_MSG,
											Req, 8,
											Res, &dwResLen,
											timeout);
	
	memcpy(pGetDeviceID, &Res[6], sizeof(GetDevIDRes_T));
	if(( wRet != 0 ) || (Res[6] != 0))
	{
			printf("Error IPMC GetDeviceID\n");
			return -1;
	}

	return wRet;
}


/**
\breif	Executes GetDeviceGUID IPMI command.
 @param	pSession		[in]Session handle
 @param	pGetDeviceID	[out]Device GUID structure according to IPMI Spec
 @param	timeout			[in]timeout value in seconds.

 @retval Returns LIBIPMI_STATUS_SUCCESS on success and error codes on failure
*/
uint16_t	IPMICMD_GetDeviceGUID( IPMI20_UDS_SESSION_T *pUDSSession, GetDevGUIDRes_T *pGetDeviceGUID, int timeout )
{
	uint8_t		Req [20];
	uint32_t		dwResLen;
	uint16_t		wRet;

	dwResLen = sizeof(GetDevGUIDRes_T);
	wRet = LIBIPMI_Send_RAW_IPMI2_0_Command(pUDSSession, 
											DEFAULT_NET_FN_LUN, CMD_GET_DEV_GUID,
											Req, 0,
											(uint8_t*)pGetDeviceGUID, &dwResLen,
											timeout);
	return wRet;
}


/**
\breif	Higher level function for retrieving DeviceID.
		Calls IPMICMD_GetDeviceID internally.
 @param	pSession		[in]Session handle
 @param	pszDeviceID		[out]Device ID in the form of chars
 @param	timeout			[in]timeout value in seconds.

 @retval Returns LIBIPMI_STATUS_SUCCESS on success and error codes on failure
*/
uint16_t LIBIPMI_HL_GetDeviceID( IPMI20_UDS_SESSION_T *pUDSSession, char *pszDeviceID, int timeout )
{
	uint8_t	i;
	uint16_t	wRet = LIBIPMI_E_SUCCESS;
	char	szTemp[10];
	GetDevIDRes_T	DeviceID;

	pszDeviceID[0] = (char)0;
	
	wRet = IPMICMD_GetDeviceID( pUDSSession, &DeviceID, timeout);

	if (wRet == LIBIPMI_E_SUCCESS)
	{
		uint8_t	*pbyRes;
		pbyRes = (uint8_t *) &DeviceID;
		for (i = 0; i < (uint8_t)sizeof(GetDevIDRes_T); i++ )
		{
			sprintf (szTemp, "%x ", pbyRes[i]);
			strcat(pszDeviceID, szTemp);
		}
	}
	
	return wRet;
}

/**
\breif	Higher level function for retrieving Device GUID.
		Calls IPMICMD_GetDeviceGUID internally.
 @param	pSession		[in]Session handle
 @param	pszDeviceID		[out]Device GUID in the form of chars
 @param	timeout			[in]timeout value in seconds.

 @retval Returns LIBIPMI_STATUS_SUCCESS on success and error codes on failure
*/
uint16_t LIBIPMI_HL_GetDeviceGUID( IPMI20_UDS_SESSION_T *pUDSSession, char *pszDeviceGUID, int timeout )
{
	uint8_t	i;
	uint16_t	wRet;
	char	szTemp[10];
	GetDevGUIDRes_T DeviceGUID;

	pszDeviceGUID[0] = (char)0;
	
	wRet = IPMICMD_GetDeviceGUID( pUDSSession, &DeviceGUID, timeout);

	if (wRet == LIBIPMI_E_SUCCESS)
	{
		uint8_t	*pbyRes;
		pbyRes = (uint8_t *) &DeviceGUID;
		for (i = 0; i < (uint8_t)sizeof(GetDevGUIDRes_T); i++ )
		{
			sprintf (szTemp, "%x ", pbyRes[i]);
			strcat(pszDeviceGUID, szTemp);
		}
	}
	
	return wRet;
}

