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

#ifndef __LIBIPMI_XPORTDEVICE_H__
#define __LIBIPMI_XPORTDEVICE_H__

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

/* command specific header files */
#include "IPMIDefs.h"
#include "IPMI_DeviceConfig.h"
#include "IPMI_LANConfig.h" // For LAN configuration parameters union definition


#include "IPMI_SOLConfig.h"
#include "IPMI_SerialModem.h"


/* Handling for packing structs */
#ifdef __GNUC__
#define PACKED __attribute__ ((packed))
#else
#define PACKED
#pragma pack( 1 )
#endif

#ifdef  __cplusplus
extern "C" {
#endif

#define CHANNEL_MEDIUM_TYPE_LAN 0x04
#define MAX_IPV6_ADDRS 16

/* ----------------- Multiple IPv6 Response Structure ----------------- */

typedef struct 
{
	unsigned char Address[MAX_IPV6_ADDRS][IP6_ADDR_LEN];
	unsigned char Prefix[MAX_IPV6_ADDRS];
	unsigned char Source;
} GetAllIPv6Address_T;
	
/*---------- IPMI Command direct routines ----------*/
/* LAN related functions */
LIBIPMI_API uint16_t IPMICMD_GetLANConfig(IPMI20_SESSION_T *pSession,
				GetLanConfigReq_T* pGetLANConfigReqData,
				GetLanConfigRes_T* pGetLANConfigResData,
				int timeout);
LIBIPMI_API uint16_t IPMICMD_SetLANConfig(IPMI20_SESSION_T *pSession,
				SetLanConfigReq_T* pSetLANConfigReqData,
				unsigned int ReqDataLen,
				SetLanConfigRes_T* pSetLANConfigResData,
				int timeout);


/*---------- LIBIPMI Higher level routines -----------*/
#define LAN_DEST_TYPE_SNMP 0x0
#define LAN_DEST_TYPE_OEM1 0x6
#define LAN_DEST_ADDR_FORMAT_IPV4 0x0
#define LAN_DEST_ADDR_FORMAT_IPV6 0x1
#define VLAN_STATUS_BIT 0x8000

uint16_t LIBIPMI_HL_GetNumOfLANInterfaces(IPMI20_SESSION_T *pSession, uint8_t* pLanInfo,
					uint8_t* pNumOfLANDestEntries, int timeout);

uint16_t LIBIPMI_HL_GetPHYConfig(IPMI20_SESSION_T *pSession, uint8_t Channel,
               		       PHYConfig_T *PHYConfigRes, int timeout);

uint16_t LIBIPMI_HL_GetPHYConfigTable(IPMI20_SESSION_T *pSession, PHYConfig_T* pPHYConfigTable,
       				    uint8_t* pNumOfLANInterfaces, int timeout);

uint16_t LIBIPMI_HL_SetPHYConfig(IPMI20_SESSION_T *pSession, uint8_t Channel, uint8_t AutoNegotiation,
         		       uint16_t Speed, uint8_t Duplex, int timeout);

uint16_t LIBIPMI_HL_GetNCSIMode(IPMI20_SESSION_T *pSession, uint8_t Channel,
                                                                    uint8_t Index,uint8_t *AutoSelect, int timeout);

uint16_t LIBIPMI_HL_SetNCSIMode(IPMI20_SESSION_T *pSession, uint8_t Channel, uint8_t Index,
                                                                   uint8_t AutoSelect, int timeout);

uint16_t LIBIPMI_HL_SetNCSISetting(IPMI20_SESSION_T *pSession, uint8_t Channel, uint8_t Index,
                                                                   uint8_t ChannelID, uint8_t PackageID, int timeout);

uint16_t LIBIPMI_HL_GetNCSISetting(IPMI20_SESSION_T *pSession, uint8_t Channel,
                                                                    uint8_t Index,uint8_t *ChannelID,uint8_t *PackageID, int timeout);

uint16_t LIBIPMI_HL_GetNCSIConfigNUM(IPMI20_SESSION_T *pSession, uint8_t Channel,
                                                                            uint8_t *ConfigNum, int timeout);

uint16_t LIBIPMI_HL_GetNumOfLANDestinationEntries(IPMI20_SESSION_T *pSession,
					uint8_t* pNumOfLANDestEntries,
					uint8_t Channel,
					int timeout);

uint16_t LIBIPMI_HL_GetLANDestinationType(IPMI20_SESSION_T *pSession,
					uint8_t Channel,
					uint8_t  index,
					LANDestType_T *LANDestTypeRes,
					int timeout);

uint16_t LIBIPMI_HL_GetLANDestinationAddress(IPMI20_SESSION_T *pSession,
					uint8_t Channel,
					uint8_t  index,
					LANDestAddr_T *LANDestAddrRes,
					int timeout);

uint16_t LIBIPMI_HL_GetLANDestinationV6Address(IPMI20_SESSION_T *pSession,
					uint8_t Channel,
					uint8_t  index,
					LANDestv6Addr_T *LANDestv6AddrRes,
					int timeout);

uint16_t LIBIPMI_HL_GetLANDestinationType_AddrTable(IPMI20_SESSION_T *pSession,
					LANDestType_T* pDestTypeTable,
					LANDestAddr_T* pDestAddrTable,
					uint8_t* pNumOfLANDestEntries,
					uint8_t Channel,
					int timeout);

uint16_t LIBIPMI_HL_SetLANDestinationType(IPMI20_SESSION_T *pSession,
					uint8_t Channel,
					uint8_t  index,
					uint8_t desttype,
					int timeout);

uint16_t LIBIPMI_HL_SetLANDestinationAddress(IPMI20_SESSION_T *pSession,
					uint8_t Channel,
					uint8_t  index,
					uint8_t addrFormat,
					uint8_t* destAddr,
					int timeout);

uint16_t LIBIPMI_HL_SetLANDestinationV6Address(IPMI20_SESSION_T *pSession,
					uint8_t Channel,
					uint8_t  index,
					uint8_t addrFormat,
					uint8_t* destAddr,
					int timeout);

uint16_t LIBIPMI_HL_SetLANAlertEntry(IPMI20_SESSION_T *pSession,
					uint8_t DestSel,
					uint8_t* pDestAddr,uint8_t channel,
					int timeout);

uint16_t LIBIPMI_HL_SetLANAlertEntry_IPv6(IPMI20_SESSION_T *pSession,
					uint8_t DestSel,
					uint8_t* pDestAddr,uint8_t channel,
					int timeout);

uint16_t LIBIPMI_HL_EnableVlan (IPMI20_SESSION_T *pSession, 
		            uint8_t VlanStatus, uint16_t vlanID, uint8_t Priority, uint8_t Channel, int timeout);

uint16_t LIBIPMI_HL_GetVlanStatus (IPMI20_SESSION_T *pSession, 
		            uint8_t *VlanStatus, uint16_t *vlanID, uint8_t *Priority, uint8_t Channel, int timeout);

LIBIPMI_API uint16_t IPMICMD_SetLANAlertEntryType(IPMI20_SESSION_T *pSession,
					uint8_t DestSel,
					uint8_t AlertType,uint8_t Channel,
					int timeout);

uint16_t LIBIPMI_HL_GetLANEnable(IPMI20_SESSION_T *pSession,
									uint8_t EthIndex, uint8_t *LANEnable, int timeout);

uint16_t LIBIPMI_HL_SetLANEnable(IPMI20_SESSION_T *pSession,
									uint8_t EthIndex, uint8_t LANEnable, int timeout);

uint16_t LIBIPMI_HL_GetBondEnable(IPMI20_SESSION_T *pSession,
                                                           uint8_t Index,uint8_t * BondCfg,int timeout);

uint16_t LIBIPMI_HL_SetBondEnable(IPMI20_SESSION_T * pSession, 
                                                           uint8_t * BondCfg, int timeout);

uint16_t LIBIPMI_HL_SetActiveSlave(IPMI20_SESSION_T * pSession,uint8_t Index,
                                                               uint8_t ActiveSlave, int timeout);

uint16_t LIBIPMI_HL_GetActiveSlave(IPMI20_SESSION_T * pSession, 
                                                                    uint8_t Index, uint8_t * Activeslave, int timeout);

uint16_t LIBIPMI_HL_IsBondEnabled(IPMI20_SESSION_T * pSession, 
                                                                    uint8_t * BondEnabled, int timeout);

uint16_t LIBIPMI_HL_BondVLANEnabled(IPMI20_SESSION_T * pSession, 
                                                                    uint8_t * BondVLANEnabled, int timeout);

uint16_t LIBIPMI_HL_GetLANCount(IPMI20_SESSION_T * pSession, 
                                                         uint8_t* LANCount,uint8_t * LANIndex, int timeout);

uint16_t LIBIPMI_HL_GetChannelNum(IPMI20_SESSION_T * pSession, 
                                                                    uint8_t Index, uint8_t * Channel, int timeout);

uint16_t LIBIPMI_HL_GetLANIndex(IPMI20_SESSION_T * pSession, 
                                                                    uint8_t Index, uint8_t * IfcName, int timeout);

uint16_t LIBIPMI_HL_GetSNMPCommunity(IPMI20_SESSION_T *pSession,
                    uint8_t* pCommunityStr, uint8_t Channel,
					int timeout);

uint16_t LIBIPMI_HL_SetSNMPCommunity(IPMI20_SESSION_T *pSession,
                    uint8_t* CommunityStr,uint8_t Channel,
					int timeout);

uint16_t LIBIPMI_HL_GetMACAddress(IPMI20_SESSION_T *pSession,
		            uint8_t *MACAddr,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_GetAllIPv6Addresses(IPMI20_SESSION_T *pSession,
				uint8_t Channel, uint8_t *Address, uint8_t *pIPCount,
				int timeout);

uint16_t LIBIPMI_HL_SetIPv4Source(IPMI20_SESSION_T *pSession, 
		            uint8_t Source,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv4Source(IPMI20_SESSION_T *pSession,
		            uint8_t *Source,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_SetIPv6Source(IPMI20_SESSION_T *pSession,
		            uint8_t Source,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv6Source(IPMI20_SESSION_T *pSession, 
		            uint8_t *Source,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_SetIPv4Address(IPMI20_SESSION_T *pSession, 
		            uint8_t *Address,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv4Address(IPMI20_SESSION_T *pSession,
		            uint8_t *Address,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_SetIPv6Address(IPMI20_SESSION_T *pSession,
		            uint8_t *Address,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv6Address(IPMI20_SESSION_T *pSession,
		            uint8_t *Address,uint8_t Channel,
		            int timeout);
		            
uint16_t LIBIPMI_HL_GetIPv6LinkAddress(IPMI20_SESSION_T *pSession, 
		            uint8_t *Address,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_SetIPv4NetMask(IPMI20_SESSION_T *pSession,
		            uint8_t *Mask,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv4NetMask(IPMI20_SESSION_T *pSession, 
		            uint8_t *Mask,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_SetIPv6Prefix(IPMI20_SESSION_T *pSession,
		            uint8_t Prefix,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv6Prefix(IPMI20_SESSION_T *pSession,
		            uint8_t *Prefix,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv6LinkPrefix (IPMI20_SESSION_T *pSession, 
		            uint8_t *Prefix,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_SetIPv4Gateway(IPMI20_SESSION_T *pSession,
		            uint8_t *Gateway,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv4Gateway(IPMI20_SESSION_T *pSession,
		            uint8_t *Gateway,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_SetIPv6Gateway(IPMI20_SESSION_T *pSession, 
		            uint8_t *Gateway,uint8_t Channel,
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv6Gateway(IPMI20_SESSION_T *pSession, 
		            uint8_t *Gateway,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_SetIPv6Enable(IPMI20_SESSION_T *pSession, 
		            uint8_t Enable,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv6Enable(IPMI20_SESSION_T *pSession,
		            uint8_t *Enable,uint8_t Channel, 
		            int timeout);

uint16_t LIBIPMI_HL_GetIPv4NetworkCfg(IPMI20_SESSION_T *pSession, 
					uint8_t *Source,
					uint8_t *Address,
					uint8_t *Mask,
					uint8_t *Gateway,
					uint8_t Channel,
					int timeout);

uint16_t LIBIPMI_HL_SetIPv4NetworkCfg(IPMI20_SESSION_T *pSession,
                                        uint8_t *Address,
                                        uint8_t *Mask,
                                        uint8_t *Gateway,
                                        uint8_t Channel,
                                        int timeout);

uint16_t LIBIPMI_HL_GetIPv6NetworkCfg(IPMI20_SESSION_T *pSession, 
					uint8_t *Source,
					uint8_t *Address,
					uint8_t *Prefix,
					uint8_t *Gateway,
					uint8_t Channel,
					int timeout);

uint16_t LIBIPMI_HL_SetIPv6NetworkCfg(IPMI20_SESSION_T *pSession,
                                        uint8_t *Address,
                                        uint8_t Prefix,
                                        uint8_t *Gateway,
                                        uint8_t Channel,
                                        int timeout);

/********************SERIAL PORT RELATED************************************/


#define SOL_SERIAL_PORT 0x01
#define SERIAL_MODEM_PORT 0x02
#define DEFAULT_TIMEOUT 2
#pragma pack(1)
typedef struct
{
    GetSOLConfigRes_T Res;
    uint8_t   BaudRate;

}  Wrapper_GetSOLConfigRes_T;



typedef struct
{
    SetSOLConfigReq_T Req;
    uint8_t   BaudRate;

}  Wrapper_SetSOLConfigReq_T;

typedef struct
{

    struct
        {
        uint8_t   Reserved    : 4;
        uint8_t	DtrHangup   : 1;
        uint8_t	FlowControl : 2;
        
	
    } PACKED Control;

    struct 
    {
        uint8_t BitRate	    : 4;
        uint8_t Reserved	    : 4;
	

    }  PACKED BaudRate;

} PACKED Serial_Port_Settings_T;




typedef enum
{
    None_Parity,
    Odd_Parity,
    Even_Parity
} PARITY_TYPE;

typedef enum
{
    None_FlowControl,
    XonXoff_FlowControl,
    Hardware_FlowControl
} FLOW_CONTROL_TYPE;


typedef struct
{
    unsigned long BaudRate;
    unsigned char  DataBits;
    PARITY_TYPE Parity;
    unsigned char StopBits;
    FLOW_CONTROL_TYPE FlowControl;
    unsigned char DtrHangup;
    

} PACKED SERIAL_STRUCT;

typedef struct
{
    GetSerialModemConfigRes_T Res;
    Serial_Port_Settings_T serial;

}  PACKED Wrapper_GetSerialModemConfigRes_T;


typedef struct
{
    SetSerialModemConfigReq_T Req;
    Serial_Port_Settings_T serial;

}  Wrapper_SetSerialModemConfigReq_T;

#pragma pack()

/*---------- LIBIPMI Higher level routines -----------*/

uint16_t IPMICMD_GetSerialCfg_SOL_Advanced( IPMI20_SESSION_T *pSession, uint8_t* char_acc_interval,uint8_t* char_send_threshold,int timeout );
uint16_t IPMICMD_SetSerialCfg_SOL_Advanced( IPMI20_SESSION_T *pSession, uint8_t char_acc_interval,uint8_t char_send_threshold,int timeout );

uint16_t LIBIPMI_HL_GetSerialCfg_Messaging(IPMI20_SESSION_T *pSession, \
					 SERIAL_STRUCT *serial, int timeout );

uint16_t LIBIPMI_HL_SetSerialCfg_Messaging(IPMI20_SESSION_T *pSession,  \
					 SERIAL_STRUCT *serial, int timeout);

uint16_t LIBIPMI_HL_GetSerialCfg_SOL(IPMI20_SESSION_T *pSession, \
					 SERIAL_STRUCT *serial, uint8_t* Enabled,int timeout );

uint16_t LIBIPMI_HL_SetSerialCfg_SOL(IPMI20_SESSION_T *pSession, \
                                   SERIAL_STRUCT *serial, uint8_t Enabled,int timeout);


/** 
 * \breif Sets the Serial Port configurations of the serial ports, SOL, Modem/Serial 
 * 
 * @param pSession 
 * @param type SOL or Modem/Serial
 * @param serial 
 * @param timeout 
 * 
 * @return -1 on error 0 on success.
 */
uint16_t	LIBIPMI_HL_Generic_SetSerialConfig( IPMI20_SESSION_T *pSession, int type, \
						    SERIAL_STRUCT *serial, int timeout );

/** 
 * \brief Gets the Serial Port Configuration from the BMC.
 * 
 * @param pSession 
 * @param type SOL or Modem/Serial
 * @param serial 
 * @param timeout 
 * 
 * @return 
 */
uint16_t	LIBIPMI_HL_Generic_GetSerialConfig( IPMI20_SESSION_T *pSession, int type, \
					    SERIAL_STRUCT *serial, int timeout );

/********************SERIAL PORT RELATED************************************/

#ifdef  __cplusplus
}
#endif

#endif


