#ifndef _SOCKET4_H_
#define _SOCKET4_H_

#include <Socket3.h>


#define ARP_CACHE_EMPTY   0
#define ARP_CACHE_STATIC  1
#define ARP_CACHE_ILLIGAL 2
#define ARP_CACHE_DYNAMIC 3
#define ARP_CACHE_ROUNTER 4


#define IPPORT_FUNCTION_COUNT 10
#define MAX_ARP_CACHE 10




//Arp缓冲
typedef struct tagARPCACHE
{
	ETHERNET_ADDRESS mEthernetAddr;
	IP_ADDRESS       mIPAddr;
	WORD wType;//类型1=其它；2=非法；3=动态的；4=静态的

	//时间
	DWORD dwTime;
}ARPCACHE;


struct IPPORT_FUNCTION
{
	BOOL bExist;
	BYTE byProtoent;

    IP_ADDRESS mSelfAddr;
    IP_ADDRESS mPeerAddr;

    WORD wSelfPort;
    WORD wPeerPort;

    WORD wParam1;
    WORD wParam2;
    BOOL FAR (*pFc)(ETHERNET_HEADER *, void *pPage, WORD wSize, WORD wParam);
};

#define SOCKET_STATE_EMPTY       0x0
#define SOCKET_STATE_SELFEXIST   0x1
#define SOCKET_STATE_PEEREXIST   0x2
#define SOCKET_STATE_PEERCLOSE   0x4
#define SOCKET_STATE_SELFCLOSE   0x8
#define SOCKET_STATE_SELFSYN     0x10
#define SOCKET_STATE_PEERSYN     0x20

#define SENDTCP_LOC (0L * 2L* 1024L * ETHERFIFO_TCP_SIZE)
#define RECVTCP_LOC (1L * 2L* 1024L * ETHERFIFO_TCP_SIZE)

//服务器最大的侦听数
#define MAX_SOCKETLISTEN_COUNT 5

//Socket句柄表缓冲最大个数
#define MAX_SOCKETTABLE_COUNT 5

#ifndef __BORLANDC__
        #include <Time.h>
#else
struct timeval
{
	long tv_sec;
	long tv_usec;
};
#endif
//SOCKET句柄表的元素
struct SOCKET_HEADER
{
	WORD hSocket; //句柄

	BYTE byProtoent;//协议
	
	IP_ADDRESS mIPRecvAddr; //接收方地址
	WORD	   wRecvPort;  //接收方端口

	IP_ADDRESS mIPSendAddr; //发送方地址
	WORD	   wSendPort; //发送方端口

    BOOL bServer;
    BOOL bActive;

	int nListenCount;//作为服务器时的侦听数
    int nIpFuncLoc;

    DWORD			dwSendSeqNO;//TCP发送者的序列号
	DWORD			dwSendAckNO;//TCP发送者的确认号

    DWORD			dwRecvSeqNO;//TCP接收者的序列号
	DWORD			dwRecvAckNO;//TCP接收者的确认号

	BOOL bURG;//紧急标志URG
	BOOL bACK;//确认标志ACK
	BOOL bPSH;//压栈标志PSH
	BOOL bRST;//重置标志RST
	BOOL bSYN;//同步标志STN
	BOOL bFIN;//结束标志FIN
	BOOL bQuick;//指示是否立即发送到网卡

    int nState;
    CXmsMemory* pXmsMemory_Send;
    CXmsMemory* pXmsMemory_Recv;

    CFifo mSendFifo;
    CFifo mRecvFifo;

	int nErrorCode;
	timeval mTimeVal;
};


void DisplaySocketString(char* pStr);
void DisplayEthernet(BYTE* pEthernet, int nDisplayStyle,BOOL bRecv);

//=====================================================================
BOOL __SendUdpPage(BYTE * pData, int nSize, IP_ADDRESS mIPRecvAddr,
	WORD wRecvPort, WORD wSendPort, SOCKET hSocket = INVALID_SOCKET,
		BOOL FAR (*pFc)(IP_HEADER *, void FAR *, SOCKET) = NULL);

BOOL __SendTcpPage(char* pData, int nSize, IP_ADDRESS mIPRecvAddr,
		WORD wRecvPort, WORD wSendPort, DWORD dwSeqNO, DWORD dwAckNO,
		BOOL bURG, BOOL bAck, BOOL bPSH, BOOL bRST, BOOL bSYN, BOOL bFin, BOOL bQuick,
		SOCKET hSocket = INVALID_SOCKET,
		BOOL FAR (*pFc)(IP_HEADER * pIp, void FAR * pPage, SOCKET hSocket) = NULL);

BOOL SendEthernet(BYTE* pData = NULL , int nData = 0);
BOOL ReceiveEthernet(ETHERNET_HEADER* pEthernetHeader, int nCx);

void InitIpPortFunction();
void UninitIpPortFunction();

BOOL RegisterIpFunc(BYTE byProtoent, IP_ADDRESS mSelfAddr,
	WORD wSelfPort, IP_ADDRESS mPeerAddr, WORD wPeerPort,int* pnLoc,WORD wParam1,
	WORD wParam2, BOOL FAR (*pFc)(ETHERNET_HEADER *, void FAR *, WORD,WORD));
void UnresisterIpFunc(int nLoc);
int FindIpFunc(BYTE byProtoent, IP_ADDRESS mSelfAddr, IP_ADDRESS mPeerAddr,
	WORD wSelfPort, WORD wPeerPort, DWORD dwParam);

int GlobalMallocArpCache(WORD wType);
BOOL GlobalFreeArpCache(int nIndex);
BOOL FindArpCacheForIP(const IP_ADDRESS pIpAddress, ETHERNET_ADDRESS pEthernetAddr, int* pnLoc);
BOOL FindArpCacheForNIC(IP_ADDRESS pIpAddress, const ETHERNET_ADDRESS pEthernetAddr, int* pnLoc);

BOOL AddArpCache(const IP_ADDRESS pIpAddr, const ETHERNET_ADDRESS pEthernetAddr, WORD wType);
void DisplayArp();
void __DoWithArpTimeOut();

//初始化SOCKET句柄表
void InitSocketTable();
void UninitSocketTable();
SOCKET MallocSocketTable();
void FreeSocketTable(SOCKET hSocket);
SOCKET_HEADER* GetSocketFromHandle(SOCKET hSocket);

void __SavePage_ToSocket(SOCKET_HEADER* pSocket, BYTE* pPage, WORD wSize);
void __RegisterPage_ToSocket(SOCKET_HEADER* pSocket, BYTE* pData, WORD wSize);

#endif