/**
 * @file   libipmi_StorDevice.h
 * @author Anurag Bhatia
 * @date   15-Sep-2004
 *
 * @brief  Contains exported APIs by LIBIPMI for
 *  		communicating with the BMC for NetFn type Storage.
 *
 */

#ifndef __LIBIPMI_STORDEVICE_H__
#define __LIBIPMI_STORDEVICE_H__

/* LIIPMI core header files */
#include "libipmi_session.h"
#include "libipmi_errorcodes.h"

/* command specific header files */
#include "com_IPMI_SEL.h"
#include "com_IPMI_FRU.h"
#include "com_IPMI_IPMB.h"
#include "com_IPMI_Storage.h"
//#include "IPMIConf.h"
//#include "SELRecord.h"

#include "libipmi_sdr.h"

#ifdef  __cplusplus
extern "C" {
#endif

/*****************************************************************************
	System Event Log
******************************************************************************/
  uint16_t IPMICMD_GetSELInfo(IPMI20_UDS_SESSION_T *pUDSSession,
					SELInfo_T *pResGetSELInfo,
					int timeout);
  uint16_t IPMICMD_GetSELAllocationInfo(IPMI20_UDS_SESSION_T *pUDSSession,
					SELAllocInfo_T *pResGetSELAllocInfo,
					int timeout);
  uint16_t IPMICMD_ReserveSEL(IPMI20_UDS_SESSION_T *pUDSSession,
					ReserveSELRes_T* pReserveSelRes,
					int timeout);
  uint16_t IPMICMD_GetSELEntry(IPMI20_UDS_SESSION_T *pUDSSession,
					GetSELReq_T* pGetSELReqData,
					uint8_t* pGetSELResData,
					uint32_t ResDataLen,
					int timeout);
  uint16_t IPMICMD_AddSELEntry(IPMI20_UDS_SESSION_T *pUDSSession,
					SELEventRecord_T* pSELReqData,
					AddSELRes_T* pSELResData,
					int timeout);
  uint16_t IPMICMD_DeleteSELEntry(IPMI20_UDS_SESSION_T *pUDSSession,
					uint16_t RecordID,
					int timeout);

/*---------- LIBIPMI Higher level routines -----------*/
  uint16_t LIBIPMI_HL_GetNumOfSELEntries(IPMI20_UDS_SESSION_T *pUDSSession,
					uint16_t* nNumOfSELEntries,
					int timeout);
  uint16_t IPMC_GetNumOfSELEntries(IPMI20_UDS_SESSION_T *pUDSSession, uint8_t IpmbAddr, 
					uint16_t* nNumOfSELEntries,
					int timeout);
  uint16_t LIBIPMI_HL_GetMaxPossibleSELEntries(IPMI20_UDS_SESSION_T *pUDSSession,
					uint16_t* nMaxPossibleSELEntries,
					int timeout);
  uint16_t IPMC_GetMaxPossibleSELEntries(IPMI20_UDS_SESSION_T *pUDSSession, uint8_t IpmbAddr,
						uint16_t* nMaxPossibleSELEntries,
						int timeout);
  uint16_t LIBIPMI_HL_GetAllSELEntries(IPMI20_UDS_SESSION_T *pUDSSession,
					SELEventRecord_T *pSELEntriesBuffer,
					int timeout);

  uint16_t LIBIPMI_HL_GetAllSensorInfo(IPMI20_UDS_SESSION_T *pUDSSession,
					uint8_t **SDRBuff,
					int *SDRCount,
					int *MaxSDRLen,
					int timeout);
  uint16_t LIBIPMI_HL_GetSensorName(IPMI20_UDS_SESSION_T *pUDSSession,
					uint8_t SlaveAdd,
					uint8_t LUNid,
					uint8_t SensorNum,
					uint8_t *SensorName,
					int timeout);
// uint16_t LIBIPMI_HL_GetAllFRUDevice(IPMI20_UDS_SESSION_T *pUDSSession,
// 					uint8_t *pFRUIDs,
// 					uint8_t *nFRUs,
// 					uint8_t nFRUsName[][16],
// 					int timeout);

/*****************************************************************************
	Field Replacement Unit (FRU)
******************************************************************************/

#pragma pack(1)
/*this is a structure used by an abstraction function
for getallselentries
we want all sel entires but we also want sensor names*/
typedef struct _SELEventRecordWithSensorName
{
	SELRec_T EventRecord;
	uint8_t SensorName[MAX_ID_STR_LEN]; //MAX_ID_STR_LEN is the max possible because SensorName len in SDR is indicated by 6 bits
} SELEventRecordWithSensorName_T;

#ifndef MAX_FRU_DEVICES
#define MAX_FRU_DEVICES	32
#endif

typedef struct _SDRHeader
{
    /** The ID of this SDR, LSB first */
    uint8_t RecordID[ 2 ];
    /** Version of this SDR (Not always the same as the IPMI version!) */
    uint8_t SDRVersion;
    /** The type of this SDR, usually \ref SDR_FULL or \ref SDR_COMPACT */
    uint8_t RecordType;
    /** The length of the SDR that follows this header */
    uint8_t RecordLength;
}  SDRHeader;

#pragma pack()

uint8_t libipmi_GetBits(uint8_t orig, uint8_t startbit, uint8_t endbit);

//Having this for backward compatibility. Projects still using GetBits
//Will remove this macro when all projects stop using it
#define GetBits libipmi_GetBits

  uint16_t IPMICMD_GetFRUInventoryAreaInfo(IPMI20_UDS_SESSION_T *pUDSSession,
				FRUInventoryAreaInfoReq_T *pReqFRUInventoryAreaInfo,
				FRUInventoryAreaInfoRes_T *pResFRUInventoryAreaInfo,
				int timeout);

  uint16_t IPMICMD_ReadFRUData(IPMI20_UDS_SESSION_T *pUDSSession,
				FRUReadReq_T* pFRUReadReqData,
				FRUReadRes_T* pFRUReadResData,
				int timeout);

  uint16_t IPMICMD_WriteFRUData(IPMI20_UDS_SESSION_T *pUDSSession,
				FRUWriteReq_T* pFRUWriteReqData,
				uint32_t ReqDataLen /* Bytes to be written + sizeof(FRUWriteReq_T) */,
				FRUWriteRes_T* pFRUWriteResData,
				int timeout);

  // uint16_t LIBIPMI_HL_GetAllFRUDevices(IPMI20_UDS_SESSION_T *pUDSSession,
		// 		uint8_t *pFRUIDs,
		// 		uint8_t *pFRUNames,
		// 		uint8_t *nFRUs,
		// 		int timeout);

  uint16_t Storlead_GetAllSelEntriesWithSensorNames(IPMI20_UDS_SESSION_T *pUDSSession, uint8_t IpmbAddr,
	SELEventRecordWithSensorName_T *pSELEntriesBuffer,
	int timeout);

  uint16_t IPMICMD_ClearSEL(IPMI20_UDS_SESSION_T *pUDSSession,
				int timeout);

  uint16_t IPMC_ClearSEL(IPMI20_UDS_SESSION_T *pUDSSession, uint8_t IpmbAddr, 
				int timeout);

  uint8_t IPMICMD_GetSELTime(IPMI20_UDS_SESSION_T *pUDSSession,
				GetSELTimeRes_T *pGetSELTimeRes, int timeout);

  uint8_t IPMICMD_SetSELTime(IPMI20_UDS_SESSION_T *pUDSSession,
				SetSELTimeReq_T *pSetSELTimeReq, int timeout);
  uint8_t IPMC_SetSELTime(IPMI20_UDS_SESSION_T *pUDSSession, uint8_t IpmbAddr,
				SetSELTimeReq_T *pSetSELTimeReq, int timeout);

  uint8_t IPMICMD_GetSELTimeUTCOffset(IPMI20_UDS_SESSION_T *pUDSSession,
				GetSELTimeUTCOffsetRes_T *pGetSELTimeUTCOffsetRes, int timeout);

  uint8_t IPMICMD_SetSELTimeUTCOffset(IPMI20_UDS_SESSION_T *pUDSSession,
				SetSELTimeUTCOffsetReq_T *pSetSELTimeUTCOffsetReq, int timeout);


#ifdef  __cplusplus
}
#endif

#endif
