//////////////////////////////////////////////////////////////////////////////
//
// Asura_Platform_NetSocket.h
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

#if defined ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#if !defined __ASURA_PLATFORM_NETSOCKET_H__
#define __ASURA_PLATFORM_NETSOCKET_H__

#include <netex/errno.h>
#include <netex/net.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/******************************************************************************/
/* Macros                                                                     */
/******************************************************************************/
#define SOCKET_ERROR (-1)
#define INVALID_SOCKET (-1)
#define INADDR_NONE 0xffffffff

#define WSAEWOULDBLOCK      SYS_NET_EWOULDBLOCK             
#define WSAEINPROGRESS      SYS_NET_EINPROGRESS             
#define WSAEALREADY         SYS_NET_EALREADY                
#define WSAENOTSOCK         SYS_NET_ENOTSOCK                
#define WSAEDESTADDRREQ     SYS_NET_EDESTADDRREQ            
#define WSAEMSGSIZE         SYS_NET_EMSGSIZE                
#define WSAEPROTOTYPE       SYS_NET_EPROTOTYPE              
#define WSAENOPROTOOPT      SYS_NET_ENOPROTOOPT             
#define WSAEPROTONOSUPPORT  SYS_NET_EPROTONOSUPPORT         
#define WSAESOCKTNOSUPPORT  SYS_NET_ESOCKTNOSUPPORT         
#define WSAEOPNOTSUPP       SYS_NET_EOPNOTSUPP              
#define WSAEPFNOSUPPORT     SYS_NET_EPFNOSUPPORT            
#define WSAEAFNOSUPPORT     SYS_NET_EAFNOSUPPORT            
#define WSAEADDRINUSE       SYS_NET_EADDRINUSE              
#define WSAEADDRNOTAVAIL    SYS_NET_EADDRNOTAVAIL           
#define WSAENETDOWN         SYS_NET_ENETDOWN                
#define WSAENETUNREACH      SYS_NET_ENETUNREACH             
#define WSAENETRESET        SYS_NET_ENETRESET               
#define WSAECONNABORTED     SYS_NET_ECONNABORTED            
#define WSAECONNRESET       SYS_NET_ECONNRESET              
#define WSAENOBUFS          SYS_NET_ENOBUFS                 
#define WSAEISCONN          SYS_NET_EISCONN                 
#define WSAENOTCONN         SYS_NET_ENOTCONN                
#define WSAESHUTDOWN        SYS_NET_ESHUTDOWN               
#define WSAETOOMANYREFS     SYS_NET_ETOOMANYREFS            
#define WSAETIMEDOUT        SYS_NET_ETIMEDOUT               
#define WSAECONNREFUSED     SYS_NET_ECONNREFUSED            
#define WSAELOOP            SYS_NET_ELOOP                   
#define WSAENAMETOOLONG     SYS_NET_ENAMETOOLONG            
#define WSAEHOSTDOWN        SYS_NET_EHOSTDOWN               
#define WSAEHOSTUNREACH     SYS_NET_EHOSTUNREACH            
#define WSAENOTEMPTY        SYS_NET_ENOTEMPTY               
#define WSAEPROCLIM         SYS_NET_EPROCLIM                
#define WSAEUSERS           SYS_NET_EUSERS                  
#define WSAEDQUOT           SYS_NET_EDQUOT                  
#define WSAESTALE           SYS_NET_ESTALE                  
#define WSAEREMOTE          SYS_NET_EREMOTE
#define WSAEINVAL           SYS_NET_EINVAL

#define SD_SEND				SHUT_WR			// for shutdown

// On the Xbox, use the VDP protocol which allows for combined game and voice data
// (game data is sent encrypted, voice unencrypted)
// On other platforms, we will want to use IPPROTO_UDP
// On PS3 we must specify 0 in conjunction with socket type SOCK_DGRAM_P2P
#define ASURA_NETSOCKET_PROTOCOL 0
#define ASURA_QOSSOCKET_PROTOCOL 0

// PS3 uses a special socket type for the signaling (NAT traversal) system.
#define ASURA_NETSOCKET_SOCKETTYPE						SOCK_DGRAM_P2P
#define ASURA_QOSSOCKET_SOCKETTYPE						SOCK_DGRAM_P2P

// The PS3 socket uses sockaddr_in_p2p instead of sockaddr_in. It requires a virtual port to be set.
#define ASURA_PS3_NETSOCKET_VPORT						(1)
#define ASURA_PS3_QOSSOCKET_VPORT						(2)

// Macro to fix up the vport when setting up an address. In Asura we always use a single vport.
#define ASURA_NETSOCKET_FIXUPSOCKADDRIN(xAddress)		{ xAddress.sin_vport = htons(ASURA_PS3_NETSOCKET_VPORT); }

// On PC/PS2/PS3 IP+UDP header size is 28 bytes
#define ASURA_NETSOCKET_PROTOCOL_PACKETHEADERSIZE (28)

#define ASURA_NETSOCKET_DEFAULTPORT (3658)

#define ASURA_QOS_DEFAULT_PORT_SERVER (ASURA_NETSOCKET_DEFAULTPORT)
#define ASURA_QOS_DEFAULT_PORT_CLIENT (ASURA_NETSOCKET_DEFAULTPORT)

#define ASURA_NETSOCKET_IS_ERROR_CODE( iReturnValue ) ((iReturnValue) < 0)
#define ASURA_NETSOCKET_IS_INVALID_SOCKET( iReturnValue ) ((iReturnValue) < 0)

#define WSAGetLastError(s) sys_net_errno

// functions
#define closesocket socketclose

#define getsockname( s, sAddr, iLeng )					getsockname( s, sAddr, (socklen_t*)(iLeng) )
#define recvfrom( s, buf, len, flags, addr, addrLen )	recvfrom( s, buf, len, flags, addr, (socklen_t*)(addrLen) )

#define select		socketselect

/******************************************************************************/
/* Types                                                                      */
/******************************************************************************/

typedef int SOCKET;
typedef u_int Asura_NetAddress;
typedef unsigned int in_addr_t;

typedef struct sockaddr			SOCKADDR;
typedef struct sockaddr_in_p2p	SOCKADDR_IN;
typedef struct in_addr     		IN_ADDR;
typedef struct hostent     		HOSTENT;
typedef struct timeval     		TIMEVAL;

#endif // !defined __ASURA_PLATFORM_NETSOCKET_H__
