#ifndef _xbNETSTRUCT_
#define _xbNETSTRUCT_
/*<<<***************************************************************************
The MIT License (MIT)

Copyright(C) 2013 - 2015 Marc Mirti Mancinelli, Christophe Lardau and Philippe Pamart (xdcube.org)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
#Title: xbNetStruct
#Project: xdcBase
////////////////////////////////////////////////////////////////////////////////
#Author: Marc MIRTI MANCINELLI
#History:
<12/02/2014: creation.
12/02/2014: this notice inserted.
***************************************************************************>>>*/

#ifndef _xbEXCEPTION_
#	include "xbException.h"
#endif
#ifndef _xbDATA_
#	include "xbData.h"
#endif

#define xbnetCPP
#define xbnetEBCDIC

#ifdef xbLITTLEENDIAN
#		define xbnetComToUint64(nb)	((uint64)nb)

#		define xbnetUint64ToCom(nb)	((uint64)nb)

#		define xbnetComToUlong(nb)	((unsigned long)nb)

#		define xbnetUlongToCom(nb)	((unsigned long)nb)

#		undef xbnetINVUSED
#elif defined(xbBIGENDIAN)
#		define xbnetComToUint64(nb)	xbnetInv64(nb)

#		define xbnetUint64ToCom(nb)	xbnetInv64(nb)

#		define xbnetComToUlong(nb)	xbnetInv32(nb)

#		define xbnetUlongToCom(nb)	xbnetInv32(nb)

#		define xbnetINVUSED
#else
Error : no storage type defined for integers
#endif

enum xbnetStatus
{
	xbnetStatus_Unknown = 0,
	xbnetStatus_Continue = 100,
	xbnetStatus_SwitchProtocol = 101,
	xbnetStatus_RitaContinue = 150,

	xbnetStatus_Ok = 200,
		xbnetStatus_Created = 201,
		xbnetStatus_Accepted = 202,
		xbnetStatus_NoContent = 204,
		xbnetStatus_ResetContent = 205,
		xbnetStatus_PartialContent = 206,
		xbnetStatus_MultipleChoice = 300,
		xbnetStatus_Moved = 301,
		xbnetStatus_Found = 302,
		xbnetStatus_NotModified = 304,
		xbnetStatus_UseProxy = 305,
		xbnetStatus_TemporaryRedirect = 307,

		xbnetStatus_BadRequest = 400,
		xbnetStatus_AuthentificationReq = 401,
		xbnetStatus_Forbidden = 403,
		xbnetStatus_NotFound = 404,
		xbnetStatus_NotAllowed = 405,
		xbnetStatus_NotAcceptable = 406,
		xbnetStatus_ProxyAuthentificationReq = 407,
		xbnetStatus_TimeOut = 408,
		xbnetStatus_Conflict = 409,
		xbnetStatus_Gone = 410,
		xbnetStatus_LengthReq = 411,
		xbnetStatus_PrecondFailed = 412,
		xbnetStatus_EntityTooLarge = 413,
		xbnetStatus_UrlTooLong = 414,
		xbnetStatus_UnsupportedMediaType = 415,
		xbnetStatus_BadRange = 416,
		xbnetStatus_ExceptationFailed = 417,

		xbnetStatus_InternalError = 500,
		xbnetStatus_NotImpl = 501,
		xbnetStatus_BadGateway = 502,
		xbnetStatus_ServiceUnavailable = 503,
		xbnetStatus_GatewayTimeout = 504,
		xbnetStatus_ProtoVersionNotSupported = 505
};

extern xbString xbEXPORT xbnetLabel(xbnetStatus status);

#ifdef xbnetINVUSED
extern unsigned long xbEXPORT xbnetInv32(unsigned long nb);
extern uint64 xbEXPORT xbnetInv64(uint64 nb);
#endif

#ifdef xbnetEPRO_SUPPORT
/*************************************************************************
 * Common header for all frames                                          *
 *************************************************************************/
#define xbnetFrameStatus_FRAMEFOLLOWING	((unsigned char)0x01)
#define xbnetFrameStatus_CLOSECONNECTION	((unsigned char)0x02)

#define xbnetFrameStatus_ACCEPTHTMLERROR	((unsigned char)0x04)
#define xbnetFrameStatus_ACCEPTHTLPFRAME	((unsigned char)0x08)

#ifndef xbnetFrame_SIZEMAX
#define xbnetFrame_SIZEMAX	0x1000000 // 16777216 octets, header compris
#endif

struct xbEXPORT xbnetFrameHeader
{
	/*000*/ unsigned long	m_cByteFrame;
	/*004*/ unsigned char	m_status;
	/*005*/ unsigned char	m_action[3];
#ifdef xbnetCPP
	xbnetFrameHeader()
	{
		xbAssert(sizeof(*this) == 8);
	}
#endif
}; /*008*/ 

/*xbnetFrameHeader_CRYPTOFFSET must be sizeof(struct xbnetFrameHeader) 
for as400 source */
#define xbnetFrameHeader_CRYPTOFFSET	(sizeof(struct xbnetFrameHeader))

/* String types */
#define xbnetFrameString_CHARS			((char)0x1)
#define xbnetFrameString_BLOB				((char)0x2)
//TODO: #define xbnetFrameString_ULONG			((char)0x3)


/*************************************************************************
 * I - Frame used by client to init connection                           *
 *************************************************************************/
#define xbnetFrameInit_STATUS		((unsigned char)0xEC)
#define xbnetFrameInit_ACT0		((unsigned char)0xAD)
#define xbnetFrameInit_ACT1		((unsigned char)0xE0)
#define xbnetFrameInit_ACT2		((unsigned char)0x52)

struct xbEXPORT xbnetFrameCusInit
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
#ifdef xbnetCPP
	xbnetFrameCusInit();
	bool Check();
#endif
}; /*008*/

extern void xbEXPORT xbnetFrameCusInit_Init(struct xbnetFrameCusInit *pFrame);
extern bool xbEXPORT xbnetFrameCusInit_Check(const struct xbnetFrameCusInit *pFrame);

/*************************************************************************
 * II - Frame used by server to answer to connection init                *
 *************************************************************************/
struct xbEXPORT xbnetFrameSrvInit
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
	/*008*/ unsigned long			m_cp;
	/*012*/ unsigned long			m_rsrv;
	/*016*/ uint64					m_keyCrypt1;
	/*024*/ uint64					m_keyCrypt2;
#ifdef xbnetCPP
	xbnetFrameSrvInit();
	bool Check();
#endif
}; /*032*/

extern void xbEXPORT xbnetFrameSrvInit_Init(struct xbnetFrameSrvInit *pFrame);
extern bool xbEXPORT xbnetFrameSrvInit_Check(const struct xbnetFrameSrvInit *pFrame);

/*Communication encryption */
#define xbnetCrypt_KEYSZ	256
struct xbEXPORT xbnetCrypt
{
	unsigned long	m_arrKey[(xbnetCrypt_KEYSZ>>2)+1];
};

extern bool xbEXPORT xbnetCryptOk(uint64 keyCrypt1,uint64 keyCrypt2);
extern void xbEXPORT xbnetCryptKeyGen(uint64 *pKeyCrypt1,uint64 *pKeyCrypt2);
extern void xbEXPORT xbnetCryptGet(uint64 keyCrypt1,uint64 keyCrypt2,
						struct xbnetCrypt *pCrypt);
extern void xbEXPORT xbnetEncrypt(const struct xbnetCrypt *pCrypt,int sz,
					   const void *_pSrce,void *_pDest);
extern void xbEXPORT xbnetDecrypt(const struct xbnetCrypt *pCrypt,int sz,
					   const void *_pSrce,void *_pDest);


/*************************************************************************
 * III - Frame used by client to start connection                        *
 *************************************************************************/
#define xbnetFrameCus_SERVICESZ	12
struct xbEXPORT xbnetFrameCusConnect
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
	/*008*/ char					m_service[xbnetFrameCus_SERVICESZ];
	/*020*/ unsigned long			m_cByteVars; 
	/*024	char					m_vars[m_cByteVars];*/
#ifdef xbnetCPP
	xbnetFrameCusConnect(
			const char *pszService
#	ifdef xbnetEBCDIC
			,TEBCDICmap *pMap
#	endif
			);
	bool Check(
#ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#endif
				);
#endif
}; /*024 + m_cByteVars*/


extern bool xbEXPORT xbnetFrameCusConnect_Check(const struct xbnetFrameCusConnect *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
								 );
extern void xbEXPORT xbnetFrameCusConnect_Init(struct xbnetFrameCusConnect *pFrame,
							 const char *pszService
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );


/*************************************************************************
 * IV - Frame used by server to answer to connection or execution ask    *
 *************************************************************************/
struct xbEXPORT xbnetFrameSrvRtn
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
	/*008*/ unsigned long			m_cByteRtns; 
	/*012	char					m_rtns[m_cByteRtns]*/
#ifdef xbnetCPP
	xbnetFrameSrvRtn(
			 bool bErr
#	ifdef xbnetEBCDIC
			,TEBCDICmap *pMap
#	endif
			);
	bool IsErr(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
		);
	bool IsRtn(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
		);
#endif
}; /*012 + m_cByteVars*/

extern void xbEXPORT xbnetFrameSrvRtn_Init(struct xbnetFrameSrvRtn *pFrame,
							 bool bErr
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );

extern bool xbEXPORT xbnetFrameSrvRtn_IsErr(struct xbnetFrameSrvRtn *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );

extern bool xbEXPORT xbnetFrameSrvRtn_IsRtn(struct xbnetFrameSrvRtn *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );

/*************************************************************************
 * V - Frame used by client to send execution context to server          *
 *************************************************************************/
struct xbEXPORT xbnetFrameCusCtx
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
	/*008*/ unsigned long			m_cByteEnvs; 
	/*012*/ unsigned long			m_cByteVars; 
	/*016	char					m_envs[m_cByteEnvs]*/
	/*016+m_cByteEnvs char			m_vars[m_cByteVars]*/
#ifdef xbnetCPP
	xbnetFrameCusCtx(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
			);
	bool Check(
#ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#endif
			);
#endif
}; /*016 + m_cByteEnvs + m_cByteVars */

extern void xbEXPORT xbnetFrameCusCtx_Init(struct xbnetFrameCusCtx *pFrame
							 ,TEBCDICmap *pMap
							 );


/*************************************************************************
 * VI - Frame used by client to execute a module                         *
 *************************************************************************/
struct xbEXPORT xbnetFrameCusExec
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
	/*008*/ unsigned long			m_cByteMod; 
	/*012*/ unsigned long			m_cBytePrms; 
	/*016	char					m_mod[m_cByteMod]*/
	/*016+m_cByteMod char			m_prms[m_cBytePrms]*/
#ifdef xbnetCPP
	xbnetFrameCusExec(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
			);
	bool Check(
#ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#endif
			);
#endif
}; /*016 + m_cByteMod + m_cBytePrms */

extern void xbnetFrameCusExec_Init(struct xbnetFrameCusExec *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );
extern bool xbEXPORT xbnetFrameCusExec_Check(struct xbnetFrameCusExec *pFrame);

/***************************************************************************
 * VII - Htlp Frame used by client and server for complex request or answer*
 ***************************************************************************/
//Values for xbnetFrameHtlp.m_main
#define xbnetFrameHtlpMain_HttpOrder			0x00000001 //(not available in response)
	//string expected
#define xbnetFrameHtlpMain_HttpPath			0x00000002 //(not available in response)
	//string expected
#define xbnetFrameHtlpMain_HttpVer			0x00000004
	//string expected
#define xbnetFrameHtlpMain_Agent				0x00000008 //Server name for response
	//string expected
#define xbnetFrameHtlpMain_UsrPwd				0x00000010 //(normally not available in response)
	//string+string expected
#define xbnetFrameHtlpMain_StatusCode			0x00000020
	//integer expected
#define xbnetFrameHtlpMain_StatusMsg			0x00000040
	//string expected
#define xbnetFrameHtlpMain_ContentType		0x00000080
	//string expected
#define xbnetFrameHtlpMain_ContentLength		0x00000100
	//integer expected
#define xbnetFrameHtlpMain_ContentRangeUnit	0x00000200
	//string expected (not specified & range used -> default unit is byte)
#define xbnetFrameHtlpMain_ContentRange		0x00000400
	//integer+integer+integer(start-end-total length) expected
#define xbnetFrameHtlpMain_Cookie				0x00000800
	//integer(=cookie count) + list of (string + string) expected
#define xbnetFrameHtlpMain_SessionId			0x00001000 //"Je sais pas ce que c'est !" >> Cookie persistant pr identifier le poste faisant la connection
	//guid expected
#define xbnetFrameHtlpMain_ConVar				0x00002000
	//integer(=convar count) + list of (string + string) expected
#define xbnetFrameHtlpMain_HttpParam			0x00004000 //(not available in response)
	//integer(=params count) + list of (variant) expected
#define xbnetFrameHtlpMain_Mode				0x00008000
	//integer=following flags
#	define xbnetFrameHtlpMainMode_Cacheable		0x00000001

#define xbnetFrameHtlpMain_ContentLocation	0x00010000  //(not available in request)
	//string expected
#define xbnetFrameHtlpMain_Location			0x00020000  //(normally not available in request)
	//string expected
#define xbnetFrameHtlpMain_Host				0x00040000 //(not available in response)
	//string expected
#define xbnetFrameHtlpMain_ClientId			0x00080000
	//guid expected
#define xbnetFrameHtlpMain_SupportedEncoding	0x00100000
	//integer(=format count) + list of (string:"name[;params;...;q=1.0]") expected -> say to server or client what type of compression it supports
#define xbnetFrameHtlpMain_WantedEncoding		0x00200000
	//integer(=format count) + list of (string:"name[;params;...;q=1.0]") expected -> ask to server or client compression
#define xbnetFrameHtlpMain_ContentLength64	0x00400000 //TODO
	//integer64 expected
#define xbnetFrameHtlpMain_ContentRange64		0x00800000 //TODO
	//integer64+integer64+integer64(start-end-total length) expected



//Values for xbnetFrameHtlp.m_ctx //(normally not available in response)
#define xbnetFrameHtlpCtx_Usr					0x00000001
	//string expected
#define xbnetFrameHtlpCtx_Pwd					0x00000002
	//string expected
#define xbnetFrameHtlpCtx_Site				0x00000004
	//string expected
#define xbnetFrameHtlpCtx_Bus					0x00000008
	//string expected
#define xbnetFrameHtlpCtx_Date				0x00000010
	//oledate/double expected 
#define xbnetFrameHtlpCtx_Lcid				0x00000020
	//integer expected
#define xbnetFrameHtlpCtx_Lang				0x00000040
	//string expected
#define xbnetFrameHtlpCtx_TZ					0x00000080
	//string expected
#define xbnetFrameHtlpCtx_Env					0x00000100
	//integer(=convar count) + list of (string) expected


//Values for xbnetFrameHtlp.m_record & m_data
#define xbnetFrameHtlpRD_Count				0x00000001
	//integer expected
#define xbnetFrameHtlpRD_Data					0x00000002
	//if record: integer(=rec members count) + list of variant expected
	//if data: integer(=data size) + data
#define xbnetFrameHtlpRD_DataFollowing		0x00000004
	//no data expected
#define xbnetFrameHtlpRD_No					0x00000008
	//integer expected
#define xbnetFrameHtlpRD_Type					0x00000010
	//string expected
#define xbnetFrameHtlpRD_Length				0x00000020
	//integer expected


struct xbEXPORT xbnetFrameHtlpPart
{
	/*000*/ unsigned long			m_offset;
	/*004*/ unsigned long			m_contain;
#ifdef xbnetCPP
	xbnetFrameHtlpPart()
	{
		m_offset = 0;
		m_contain = 0;
	}
	bool IsEmpty() const
	{
		return m_offset == 0 || m_contain == 0;
	}
	bool IsValid() const
	{
		return m_offset > 0 && m_contain != 0;
	}
#endif
}; /*008*/

struct xbEXPORT xbnetFrameHtlp
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
	/*008*/ struct xbnetFrameHtlpPart	m_main;
	/*016*/ struct xbnetFrameHtlpPart	m_ctx;
	/*024*/ struct xbnetFrameHtlpPart	m_record;
	/*032*/ struct xbnetFrameHtlpPart	m_data;
	/*040	char					m_dta[...]*/
#ifdef xbnetCPP
	xbnetFrameHtlp(
			 xbOpMode opm
#	ifdef xbnetEBCDIC
			,TEBCDICmap *pMap
#	endif
			);
	bool IsRequest(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
		);
	bool IsAnswer(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
		);
#endif
}; /*040 + m_cByteVars*/

extern void xbEXPORT xbnetFrameHtlp_Init(struct xbnetFrameHtlp *pFrame,
							 xbOpMode opm
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );
extern bool xbEXPORT xbnetFrameHtlp_IsRequest(struct xbnetFrameHtlp *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );
extern bool xbEXPORT xbnetFrameHtlp_IsAnswer(struct xbnetFrameHtlp *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );

/*************************************************************************
 * VIII - Frame used for compression                                     *
 *************************************************************************/
struct xbnetFrameEncode
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
	/*008*/	ulong					m_cByteType;
	/*012	char					m_typeEncoding[m_cByteType]*/
	/*012+m_cByteType	char		m_encodedData[m_cByteFrame-sizeof(xbnetFrameEncode)-m_cByteType]*/
#ifdef xbnetCPP
	xbnetFrameEncode(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
			);
	bool Check(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
			);
#endif
}; /*012 + m_cByteType + cByteCompData = m_cByteFrame */

extern void xbEXPORT xbnetFrameEncode_Init(struct xbnetFrameEncode *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );

extern bool xbEXPORT xbnetFrameEncode_Check(struct xbnetFrameEncode *pFrame
#	ifdef xbnetEBCDIC
			,TEBCDICmap *pMap
#	endif
			);


/*************************************************************************
 * Others frames    *
 *************************************************************************/
struct xbEXPORT xbnetFrameRaw
{
	/*000*/ struct xbnetFrameHeader	m_hdr;
	/*008*/ unsigned long			m_rawMode;
	/*012	char					m_rawData[m_hdr.m_cByteFrame - sizeof(xbnetFrameRaw)]*/
#ifdef xbnetCPP
	xbnetFrameRaw(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
			);
	bool Check(
#	ifdef xbnetEBCDIC
			TEBCDICmap *pMap
#	endif
		);
#endif
}; /*012 + m_cByteVars*/

extern void xbEXPORT xbnetFrameRaw_Init(struct xbnetFrameRaw *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );
extern bool xbEXPORT xbnetFrameRaw_Check(struct xbnetFrameRaw *pFrame
#ifdef xbnetEBCDIC
							 ,TEBCDICmap *pMap
#endif
							 );
#endif //xbnetEPRO_SUPPORT

#endif //_xbNETSTRUCT_
