#pragma once

#define PACKET_SIZE     1536
#define TEST_ADDRESSES  100

#define TESTERPORT        13400

#define UDP_SOCKET        0x01
#define TCP_SOCKET        0x02
#define CLI_SOCKET        0x04
#define DHCP_SOCKET       0x08

#define MAX_MAC_ADDRESS_LENGTH  8
#define MAX_MAC_ADDRESS_STRING_LENGTH  32
#define MAX_IPV4_ADDRESS_LENGTH  4
#define MAX_IPV4_ADDRESS_STRING_LENGTH  16
#define MAX_IPV6_ADDRESS_LENGTH  16
#define MAX_IPV6_ADDRESS_STRING_LENGTH  64
#define MAX_IP_ADDRESSES  10


typedef struct AddressData
{
	BOOL     bValidMACAddress;
	BYTE     MACAddress[MAX_MAC_ADDRESS_LENGTH];
	BYTE     MACAddressString[MAX_MAC_ADDRESS_STRING_LENGTH];

	boolean  bValidIPv4Address;
	DWORD    ulIPv4Address;
	BYTE     IPv4Address[MAX_IPV4_ADDRESS_LENGTH];
	BYTE     IPv4AddressString[MAX_IPV4_ADDRESS_STRING_LENGTH];
	
	boolean  bValidIPv6Address;
	BYTE     IPv6Address[MAX_IPV6_ADDRESS_LENGTH];
	BYTE     IPv6AddressString[MAX_IPV6_ADDRESS_STRING_LENGTH];
} t_stAddressData;


#define SOCKETNAMESTRINGSIZE 10
typedef struct SocketData
{
	t_stAddressData  *pAddr;
	WORD              usPort;
	SOCKET            hSock;
	SOCKADDR_IN       source_sin;
	SOCKADDR_IN       remote_sin;
	INT               iError;
	BYTE              Type;
	char              NameString[SOCKETNAMESTRINGSIZE];
	boolean           bConnected;
	boolean           bStop;
} t_stSocketData;


extern t_stAddressData   gstTesterAddressData;
extern t_stAddressData   gstVehicleAddressData;


extern t_stSocketData  stDHCPSocketData;
extern t_stSocketData  stUDPSocketData;
extern t_stSocketData  stTCPSocketData;
extern t_stSocketData* apstSocketData[TEST_ADDRESSES];


extern boolean         gbSocketCheck;


extern BYTE   RcvdIPAddress[4];
extern BYTE   RcvdIPAddressString[16];


#define eStaticBufferSize  1536
extern BYTE   m_aucReadMessage[eStaticBufferSize];


#define NUM_SOCKET_ERRORS  49
extern unsigned short ausSocketErrors[NUM_SOCKET_ERRORS];

enum Socket_Error_Codes
{
	eSocketTimeout = NUM_SOCKET_ERRORS,
	eSocketClosed,
	eSocketConnectionClosing,
	eSocketMissingLocalIPAddress,
	eSocketCreateEvent,
	eSocketStartThread,
	eWaitForError,
	eUnexpectedMessage,
	eOutputQueueFull,
	eMaxSocketErrorCodes,
};
#define MAX_ERR_DESC_LEN 60
extern char aszSocketErrorDescriptions[eMaxSocketErrorCodes + 1][MAX_ERR_DESC_LEN];


void   InitSocketData ( t_stSocketData *pstSocketData, int Type );
int    OpenSocket     ( t_stSocketData *pstSocketData );
STATUS CloseSocket    ( t_stSocketData *pstSocketData );
STATUS CloseSockets   ( void );
BOOL   PurgeSocketBuffer  ( t_stSocketData *pstSocketData );
char*  GetEthernetErrorString ( int iError );
void   getMACAddressStringFromArray  ( BYTE *pMACAddress, char *pMACAddressString );
DWORD  getIPv4AddressStringFromArray ( BYTE *pIPAddress,  char *pIPAddressString );
DWORD  getIPAddressArrayFromString   ( BYTE *pIPAddress,  char *pIPAddressString );
int     Ping               ( unsigned long ipaddr );
boolean AddressAvailable   ( DWORD  destIP, DWORD  srcIP );
int     isSocketConnected  ( SOCKET socket );
