legatt 32f4597c4d Base frontend module
- Naming style migrated to camel-case
- P7lib logger sources added
- Vcpkg manifest, CMake presets and build moved to root
- SDL2, Vulkan and RmlUi dependencies added
- Logger LOG macro added
- Logger  configuration
- SDL2 window configuration
- Vulkan configuration
- RmlUi configuration
- SDL event loop
2025-08-08 00:07:32 +03:00

1490 lines
47 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// /
// 2012-2020 (c) Baical /
// /
// This library is free software; you can redistribute it and/or /
// modify it under the terms of the GNU Lesser General Public /
// License as published by the Free Software Foundation; either /
// version 3.0 of the License, or (at your option) any later version. /
// /
// This library is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
// Lesser General Public License for more details. /
// /
// You should have received a copy of the GNU Lesser General Public /
// License along with this library. /
// /
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// This header file describe all packets types which are used in communication /
// N.B.: In this file I remove all checks for valid pointers and packets /
// because this job is made outside by packet pool. /
////////////////////////////////////////////////////////////////////////////////
#ifndef TPACKETS_H
#define TPACKETS_H
#define CLIENT_PROTOCOL_VERSION (0x0007)
//this value can store 32 bits but to avoid overflow we reduce it
#define TPACKET_MAX_ID (0xFFFFFFF)
#define TPACKET_PROCESS_NAME_MAX_LEN (96)
////////////////////////////////////////////////////////////////////////////////
//Transport Packet types, we have only 4 bits for them (16 types max)
enum eTPacket_Type
{
ETPT_CLIENT_HELLO = 0x0, //tH_Common + tH_Client_Initial
ETPT_CLIENT_PING = 0x1, //tH_Common
ETPT_CLIENT_DATA = 0x2,
ETPT_CLIENT_DATA_REPORT = 0x3,
ETPT_CLIENT_BYE = 0x4,
ETPT_ACKNOWLEDGMENT = 0x9,
ETPT_SERVER_DATA_REPORT = 0xA,
ETPT_SERVER_CHAINED = 0xB,
ETPACKET_TYPE_UNASSIGNED = 0xF
};
enum eTPacket_Endian
{
ETP_LITTLE_ENDIAN = 0,
ETP_BIG_ENDIAN ,
ETP_MAX_ENDIAN
};
////////////////////////////////////////////////////////////////////////////////
//Transport Packet extension types
enum eTPacket_Extension
{
ETPE_SERVER_NETWORK_INFO = 0x0, //sH_Ext + sH_Ext_Srv_Info
ETPE_USER_DATA = 0x1, //sH_Ext + sH_User_Data
ETPE_MAX = 0xFFFF
};
#define TPACKET_MIN_SIZE (0x200)
#define TPACKET_DEF_SIZE (1472u)
#define TPACKET_MAX_SIZE (0xFF00)
////////////////////////////////////////////////////////////////////////////////
//Transport Packet flags
#define TPACKET_FLAG_EXTRA_DATA (0x001u) // 1 << 0
#define TPACKET_FLAG_ARCH_64 (0x002u) // 1 << 1
#define TPACKET_FLAG_EXTENSION (0x004u) // 1 << 2
#define TPACKET_FLAG_BIG_ENDIAN_SRV (0x008u) // 1 << 3
#define TPACKET_FLAG_RESERVED_04 (0x010u) // 1 << 4
#define TPACKET_FLAG_RESERVED_05 (0x020u) // 1 << 5
#define TPACKET_FLAG_RESERVED_06 (0x040u) // 1 << 6
#define TPACKET_FLAG_RESERVED_07 (0x080u) // 1 << 7
#define TPACKET_FLAG_RESERVED_08 (0x100u) // 1 << 8
#define TPACKET_FLAG_RESERVED_09 (0x200u) // 1 << 9
#define TPACKET_FLAG_RESERVED_10 (0x400u) // 1 << 10
#define TPACKET_FLAG_BIG_ENDIAN_CLN (0x800u) // 1 << 11
#define TPACKET_TYPE_MASK (0xFu)
#define TPACKET_FLAGS_MASK (0xFFF0u)
#define TPACKET_FLAGS_OFFSET (4u)
////////////////////////////////////////////////////////////////////////////////
//Transport Packet structures
PRAGMA_PACK_ENTER(2) //alignment is now 2, MS only !
//This is common header for every P7 transport packet, it situated at the
//beginning of the packet, then, depending on Type can be located other headers
struct sH_Common
{
tUINT32 dwCRC32;
tUINT32 dwID;
tUINT16 wBits; //[0..3] - Type, [4..15] - flags
//tUINT16 wType:4;
//tUINT16 wFlags:12;
//We are working through UDP, so the packet size is limited to 65k.
//The minimum guaranteed size of the packet 576 bytes, user size is 512 bytes.
tUINT16 wSize;
tUINT16 wClient_ID;
} ATTR_PACK(2);
struct sH_Client_Hello
{
tUINT16 wProtocol_Version;
tUINT16 wData_Max_Size;
//Process ID and process time are dedicated to matching processes on server
//side
tUINT32 dwProcess_ID;
tUINT32 dwProcess_Start_Time_Hi;
tUINT32 dwProcess_Start_Time_Lo;
tWCHAR pProcess_Name[TPACKET_PROCESS_NAME_MAX_LEN];
} ATTR_PACK(2);
struct sH_Data_Window
{
tUINT32 dwFirst_ID;
tUINT32 dwLast_ID;
} ATTR_PACK(2);
struct sH_Packet_Ack
{
tUINT32 dwSource_ID;
tUINT16 wResult; // 0 - NOK, 1 - OK
} ATTR_PACK(2);
struct sH_Ext
{
tUINT16 wType; //extension type
tUINT16 wSize; //extension size
} ATTR_PACK(2);
struct sH_Ext_Srv_Info
{
tUINT32 dwServerVersion; //Server version
tUINT16 wProtocolVersion;//Server protocol version
tUINT16 wMTU; //maximum transfer unit (max packet size passed by all network route devices), 0 if unknown
tUINT32 dwSocket_Buffer; //size of recv socket buffer in bytes
} ATTR_PACK(2);
struct sH_Data_Window_Report
{
tUINT32 dwSource_ID;
tUINT8 pID[1]; //Array of the ID, each byte contains 8 ID markers ... bitfield
} ATTR_PACK(2);
////////////////////////////////////////////////////////////////////////////////
// //
// User packet definitions //
// //
////////////////////////////////////////////////////////////////////////////////
// This defines has been moved to P7_Client.h to be visible from outside the
// library
// #define USER_PACKET_CHANNEL_ID_BITS_COUNT (5)
// #define USER_PACKET_SIZE_BITS_COUNT (32-USER_PACKET_CHANNEL_ID_BITS_COUNT)
// #define USER_PACKET_MAX_SIZE (1 << USER_PACKET_SIZE_BITS_COUNT)
// #define USER_PACKET_CHANNEL_ID_MAX_SIZE (1 << USER_PACKET_CHANNEL_ID_BITS_COUNT)
#define INIT_USER_HEADER(iSize, iChannel_Id) (iSize | (iChannel_Id << USER_PACKET_SIZE_BITS_COUNT))
#define GET_USER_HEADER_SIZE(iBits) (iBits & ((1 << USER_PACKET_SIZE_BITS_COUNT) - 1))
#define GET_USER_HEADER_CHANNEL_ID(iBits) ((iBits >> USER_PACKET_SIZE_BITS_COUNT) & ((1 << USER_PACKET_CHANNEL_ID_BITS_COUNT) - 1))
#define CHANNEL_PACKETS_UNION_MAX_SIZE (128 * 1024)
struct sH_User_Raw //user data header
{
tUINT32 dwBits;
} ATTR_PACK(2);
struct sH_User_Data //user data header, map for sH_User_Raw
{
tUINT32 dwSize :USER_PACKET_SIZE_BITS_COUNT; //<< 28 bits for Size
tUINT32 dwChannel_ID :USER_PACKET_CHANNEL_ID_BITS_COUNT; //<< 5 bits for ChannelId
} ATTR_PACK(2);
GASSERT(sizeof(sH_User_Data) == sizeof(sH_User_Raw));
PRAGMA_PACK_EXIT()
////////////////////////////////////////////////////////////////////////////////
// CTPacket for providing basic functionality over tH_Common packet's header
class CTPacket
{
protected:
tUINT8 *m_pBuffer;
tUINT32 m_dwBuffer_Size;
tBOOL m_bInitialized;
tUINT32 m_dwPool_ID;
tBOOL m_bShell;
sH_Common *m_pHeader; //point to m_pBuffer
public:
////////////////////////////////////////////////////////////////////////////
//CTPacket::CTPacket
CTPacket()
: m_pBuffer(NULL)
, m_dwBuffer_Size(0)
, m_bInitialized(TRUE)
, m_dwPool_ID(0)
, m_bShell(TRUE)
, m_pHeader(NULL)
{
}//CTPacket::CTPacket
////////////////////////////////////////////////////////////////////////////
//CTPacket::CTPacket
CTPacket(tUINT8 *i_pBuffer,
tUINT32 i_dwBuffer_Size,
tUINT32 i_dwPool_ID
)
: m_pBuffer(i_pBuffer)
, m_dwBuffer_Size(i_dwBuffer_Size)
, m_bInitialized(TRUE)
, m_dwPool_ID(i_dwPool_ID)
, m_bShell(TRUE)
, m_pHeader(NULL)
{
if (m_pBuffer)
{
m_bInitialized = TRUE;
memset(m_pBuffer, 0, m_dwBuffer_Size);
m_pHeader = (sH_Common*)m_pBuffer;
}
else
{
m_bInitialized = FALSE;
}
}//CTPacket::CTPacket
////////////////////////////////////////////////////////////////////////////
//CTPacket::CTPacket
CTPacket(tUINT32 i_dwBuffer_Size, tUINT32 i_dwPool_ID)
: m_pBuffer(NULL)
, m_dwBuffer_Size(0)
, m_bInitialized(FALSE)
, m_dwPool_ID(i_dwPool_ID)
, m_bShell(FALSE)
, m_pHeader(NULL)
{
m_pBuffer = new tUINT8[i_dwBuffer_Size];
if (m_pBuffer)
{
m_dwBuffer_Size = i_dwBuffer_Size;
m_bInitialized = TRUE;
memset(m_pBuffer, 0, m_dwBuffer_Size);
m_pHeader = (sH_Common*)m_pBuffer;
}
}//CTPacket::CTPacket
////////////////////////////////////////////////////////////////////////////
//CTPacket::~CTPacket
virtual ~CTPacket()
{
if ( (FALSE == m_bShell)
&& (NULL != m_pBuffer)
)
{
delete [] m_pBuffer;
m_pBuffer = NULL;
}
m_dwBuffer_Size = 0;
m_bInitialized = FALSE;
m_dwPool_ID = 0;
m_pHeader = NULL;
} //CTPacket::~CTPacket
////////////////////////////////////////////////////////////////////////////
//CTPacket::Chage_Endianness
virtual void Chage_Endianness()
{
m_pHeader->dwCRC32 = ntohl(m_pHeader->dwCRC32);
m_pHeader->dwID = ntohl(m_pHeader->dwID);
m_pHeader->wBits = ntohs(m_pHeader->wBits);
m_pHeader->wClient_ID = ntohs(m_pHeader->wClient_ID);
m_pHeader->wSize = ntohs(m_pHeader->wSize);
}
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Initialized
inline tBOOL Get_Initialized()
{
return m_bInitialized;
} //CTPacket::Get_Initialized
////////////////////////////////////////////////////////////////////////////
//CTPacket::Finalize
virtual void Finalize(tUINT32 i_dwPacket_ID, tUINT16 i_wClient_ID)
{
m_pHeader->dwID = i_dwPacket_ID;
m_pHeader->wClient_ID = i_wClient_ID;
m_pHeader->dwCRC32 = Calculate_CRC(m_pHeader->wSize);
}//CTPacket::Finalize
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Size
inline tUINT16 Get_Size()
{
return m_pHeader->wSize;
}//CTPacket::Get_Size
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Client_ID
inline tUINT16 Get_Client_ID()
{
return m_pHeader->wClient_ID;
}//CTPacket::Get_Client_ID
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Type
inline eTPacket_Type Get_Type()
{
return (eTPacket_Type)(m_pHeader->wBits & TPACKET_TYPE_MASK);
}//CTPacket::Get_Type
////////////////////////////////////////////////////////////////////////////
//CTPacket::Set_Type
inline void Set_Type(eTPacket_Type i_eType)
{
m_pHeader->wBits &= ~TPACKET_TYPE_MASK; //clear type
m_pHeader->wBits |= (i_eType & TPACKET_TYPE_MASK); //set new one
}//CTPacket::Get_Flags
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_ID
inline tUINT32 Get_ID()
{
return m_pHeader->dwID;
}//CTPacket::Get_ID
////////////////////////////////////////////////////////////////////////////
//CTPacket::Is_Damaged
inline tBOOL Is_Damaged()
{
return (Calculate_CRC(m_pHeader->wSize) != m_pHeader->dwCRC32);
}//CTPacket::Is_Damaged
////////////////////////////////////////////////////////////////////////////
//CTPacket::Is_Damaged
inline tBOOL Is_Damaged(tBOOL i_bSwapBytes)
{
if (i_bSwapBytes)
{
return (Calculate_CRC(ntohs(m_pHeader->wSize)) != ntohl(m_pHeader->dwCRC32));
}
else
{
return (Calculate_CRC(m_pHeader->wSize) != m_pHeader->dwCRC32);
}
}//CTPacket::Is_Damaged
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Flags
inline tUINT16 Get_Flags()
{
return (m_pHeader->wBits & TPACKET_FLAGS_MASK) >> TPACKET_FLAGS_OFFSET;
}//CTPacket::Get_Flags
////////////////////////////////////////////////////////////////////////////
//CTPacket::Set_Flag
inline void Set_Flag(tUINT16 i_wFlag)
{
m_pHeader->wBits |= (i_wFlag << TPACKET_FLAGS_OFFSET) & TPACKET_FLAGS_MASK;
}//CTPacket::Get_Flags
////////////////////////////////////////////////////////////////////////////
//CTPacket::Clr_Flag
inline void Clr_Flag(tUINT16 i_wFlag)
{
m_pHeader->wBits &= ~((i_wFlag << TPACKET_FLAGS_OFFSET) & TPACKET_FLAGS_MASK);
}//CTPacket::Get_Flags
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Buffer
inline tUINT8 *Get_Buffer()
{
return m_pBuffer;
}//CTPacket::Get_Buffer
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Buffer
inline tUINT32 Get_Crc()
{
return m_pHeader->dwCRC32;
}//CTPacket::Get_Buffer
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Buffer_Size
inline tUINT32 Get_Buffer_Size()
{
return m_dwBuffer_Size;
}//CTPacket::Get_Buffer_Size
////////////////////////////////////////////////////////////////////////////
//CTPacket::Get_Pool_ID
inline tUINT32 Get_Pool_ID()
{
return m_dwPool_ID;
}//CTPacket::Get_Pool_ID
////////////////////////////////////////////////////////////////////////////
//CTPacket::Attach
virtual tBOOL Attach(CTPacket *i_pPacket)
{
if ( (NULL == i_pPacket)
|| (FALSE == m_bShell)
)
{
return FALSE;
}
m_pBuffer = i_pPacket->m_pBuffer;
m_dwBuffer_Size = i_pPacket->m_dwBuffer_Size;
m_pHeader = (sH_Common*)m_pBuffer;
m_dwPool_ID = i_pPacket->m_dwPool_ID;
return (NULL != m_pBuffer);
}//CTPacket::Attach
////////////////////////////////////////////////////////////////////////////
//CTPacket::Detach
inline tBOOL Detach()
{
if (FALSE == m_bShell)
{
return FALSE;
}
m_pBuffer = NULL;
m_dwBuffer_Size = 0;
m_pHeader = NULL;
m_dwPool_ID = 0;
return TRUE;
}//CTPacket::Detach
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::Add_Extra
inline tBOOL Add_Extra(const tUINT8 *i_pData, tUINT16 i_dwSize, tUINT16 i_wFlag)
{
if ( (FALSE == m_bInitialized)
|| (TRUE == m_bShell)
|| (NULL == i_pData)
|| (0 >= i_dwSize)
|| ((m_dwBuffer_Size - m_pHeader->wSize ) < i_dwSize)
)
{
return FALSE;
}
memcpy(m_pBuffer + m_pHeader->wSize, i_pData, i_dwSize);
m_pHeader->wSize = (tUINT16)(m_pHeader->wSize + i_dwSize);
CTPacket::Set_Flag(i_wFlag);
return TRUE;
}//CTPClient_Data_Report::Add_Extra
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::Clr_Extra
inline void Clr_Extra()
{
if ( (FALSE == m_bInitialized)
|| (TRUE == m_bShell)
)
{
return;
}
CTPacket::Clr_Flag(TPACKET_FLAG_EXTRA_DATA);
CTPacket::Clr_Flag(TPACKET_FLAG_EXTENSION);
}//CTPClient_Data_Report::Clr_Extra
protected:
////////////////////////////////////////////////////////////////////////////
//CTPacket::Calculate_CRC
inline tUINT32 Calculate_CRC(size_t i_szLength)
{
size_t l_szOffset = offsetof(sH_Common, dwCRC32) + sizeof(m_pHeader->dwCRC32);
//this is absolute minimum size of the packet
if (sizeof(sH_Common) > i_szLength)
{
i_szLength = sizeof(sH_Common);
}
return Get_CRC32(m_pBuffer + l_szOffset, i_szLength - l_szOffset);
}//CTPacket::Calculate_CRC
};//CTPacket
////////////////////////////////////////////////////////////////////////////***
// Class for providing basic functionality over tH_Client_Initial packet's
// header
#define CLIENT_INITIAL_SIZE (sizeof(sH_Client_Hello) + sizeof(sH_Common))
class CTPClient_Hello: public CTPacket
{
sH_Client_Hello *m_pInitial;
public:
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::CTPClient_Hello
//stationary packet, it belong to stream
CTPClient_Hello():
CTPacket(CLIENT_INITIAL_SIZE, 0)
,m_pInitial(NULL)
{
if (m_pHeader)
{
m_pHeader->wSize = CLIENT_INITIAL_SIZE;
CTPacket::Set_Type(ETPT_CLIENT_HELLO);
m_pInitial = (sH_Client_Hello*)(m_pBuffer + sizeof(sH_Common));
}
}//CTPClient_Hello::CTPClient_Hello
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::CTPClient_Hello
//dynamic packet, it belong to Pool
CTPClient_Hello(CTPacket *i_pPacket):
CTPacket()
,m_pInitial(NULL)
{
m_bInitialized = Attach(i_pPacket);
if (m_bInitialized)
{
m_pInitial = (sH_Client_Hello*)(m_pBuffer + sizeof(sH_Common));
}
}//CTPClient_Hello::CTPClient_Hello
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::Chage_Endianness
virtual void Chage_Endianness()
{
m_pInitial->wProtocol_Version = ntohs(m_pInitial->wProtocol_Version);
m_pInitial->wData_Max_Size = ntohs(m_pInitial->wData_Max_Size);
m_pInitial->dwProcess_ID = ntohl(m_pInitial->dwProcess_ID);
m_pInitial->dwProcess_Start_Time_Hi = ntohl(m_pInitial->dwProcess_Start_Time_Hi);
m_pInitial->dwProcess_Start_Time_Lo = ntohl(m_pInitial->dwProcess_Start_Time_Lo);
tWCHAR *l_pBegin = m_pInitial->pProcess_Name;
tWCHAR *l_pEnd = m_pInitial->pProcess_Name + TPACKET_PROCESS_NAME_MAX_LEN;
while ( (*l_pBegin)
&& (l_pBegin < l_pEnd)
)
{
*l_pBegin = ntohs(*l_pBegin);
l_pBegin ++;
}
}
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::Fill
inline tBOOL Fill(tUINT16 i_wProtocol_Version,
tUINT16 i_wData_Max_Size,
tUINT32 i_dwProcess_ID,
tUINT32 i_dwProcess_Start_Time_Hi,
tUINT32 i_dwProcess_Start_Time_Lo,
tWCHAR *i_pProcess_Name //[TPACKET_PROCESS_NAME_MAX_LEN]
)
{
if ( (FALSE == m_bInitialized)
|| (TRUE == m_bShell)
|| (NULL == i_pProcess_Name)
)
{
return FALSE;
}
m_pInitial->wProtocol_Version = i_wProtocol_Version;
m_pInitial->wData_Max_Size = i_wData_Max_Size;
m_pInitial->dwProcess_ID = i_dwProcess_ID;
m_pInitial->dwProcess_Start_Time_Hi = i_dwProcess_Start_Time_Hi;
m_pInitial->dwProcess_Start_Time_Lo = i_dwProcess_Start_Time_Lo;
tWCHAR *l_pSrc = i_pProcess_Name;
tWCHAR *l_pDst = m_pInitial->pProcess_Name;
tUINT16 l_wRst = TPACKET_PROCESS_NAME_MAX_LEN - 1;
//wcsncpy_s(m_pInitial->pProcess_Name,
// TPACKET_PROCESS_NAME_MAX_LEN,
// i_pProcess_Name,
// TPACKET_PROCESS_NAME_MAX_LEN - 1
// );
while ( (l_wRst)
&& (*l_pSrc)
)
{
*l_pDst = *l_pSrc;
l_pDst ++;
l_pSrc ++;
l_wRst --;
}
*l_pDst = 0;
return TRUE;
} //CTPClient_Hello::Fill
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::Fill
inline tUINT16 Get_Protocol_Version()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pInitial->wProtocol_Version;
}//CTPClient_Hello::Fill
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::Get_Data_Max_Size
inline tUINT16 Get_Data_Max_Size()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pInitial->wData_Max_Size;
}//CTPClient_Hello::Get_Data_Max_Size
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::Get_Process_ID
inline tUINT32 Get_Process_ID()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pInitial->dwProcess_ID;
}//CTPClient_Hello::Get_Process_ID
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::Get_Process_Time_Hi
inline tUINT32 Get_Process_Time_Hi()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pInitial->dwProcess_Start_Time_Hi;
}//CTPClient_Hello::Get_Process_Times
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::Get_Process_Time_Low
inline tUINT32 Get_Process_Time_Low()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pInitial->dwProcess_Start_Time_Lo;
}//CTPClient_Hello::Get_Process_Times
////////////////////////////////////////////////////////////////////////////
//CTPClient_Hello::Get_Process_Name
inline tWCHAR *Get_Process_Name()
{
if (FALSE == m_bInitialized)
{
return NULL;
}
return m_pInitial->pProcess_Name;
}//CTPClient_Hello::Get_Process_Name
}; //CTPClient_Hello
////////////////////////////////////////////////////////////////////////////////
// Class for providing basic functionality over client data packets
#define CLIENT_DATA_HEADER_SIZE sizeof(sH_Common)
class CTPData: public CTPacket
{
public:
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::CTPClient_Data
CTPData(CTPacket *i_pPacket):
CTPacket()
{
m_bInitialized = Attach(i_pPacket);
}//CTPClient_Data::CTPClient_Data
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::CTPClient_Data
CTPData():
CTPacket()
{
}//CTPClient_Data::CTPClient_Data
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::Attach
inline tBOOL Attach(CTPacket *i_pPacket)
{
m_bInitialized = CTPacket::Attach(i_pPacket);
return m_bInitialized;
}//CTPClient_Data::Attach
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::Initialize
inline void Initialize()
{
if (m_pHeader)
{
m_pHeader->wSize = sizeof(sH_Common);
CTPacket::Set_Type(ETPT_CLIENT_DATA);
}
}//CTPClient_Data::Initialize
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::Get_Data
inline tUINT8 *Get_Data()
{
if ( (NULL == m_pBuffer)
|| (m_dwBuffer_Size <= sizeof(sH_Common))
)
{
return NULL;
}
return m_pBuffer + sizeof(sH_Common);
}//CTPClient_Data::Get_Data
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::Get_Data_Size
inline tUINT16 Get_Data_Size()
{
if (NULL == m_pHeader)
{
return 0;
}
return m_pHeader->wSize - sizeof(sH_Common);
}//CTPClient_Data::Get_Data_Size
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::Get_Tail
inline tUINT8 *Get_Tail()
{
if ( (NULL == m_pBuffer)
|| (m_pHeader->wSize >= m_dwBuffer_Size)
)
{
return NULL;
}
return m_pBuffer + m_pHeader->wSize;
}//CTPClient_Data::Get_Tail
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::Get_Tail_Size
inline tUINT16 Get_Tail_Size()
{
if (NULL == m_pHeader)
{
return 0;
}
return (tUINT16)(m_dwBuffer_Size - m_pHeader->wSize);
}//CTPClient_Data::Get_Tail_Size
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::Append_Size
inline tBOOL Append_Size(tUINT16 i_wSize)
{
if ( (NULL == m_pHeader)
|| ( i_wSize > Get_Tail_Size() )
)
{
return FALSE;
}
m_pHeader->wSize += i_wSize;
return TRUE;
}//CTPClient_Data::Append_Size
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data::Finalize
inline void Finalize(tUINT32 i_dwPacket_ID, tUINT16 i_wClient_ID)
{
if (m_pHeader)
{
CTPacket::Set_Type(ETPT_CLIENT_DATA);
CTPacket::Finalize(i_dwPacket_ID, i_wClient_ID);
}
}//CTPClient_Data::Finalize
};//CTPClient_Data
////////////////////////////////////////////////////////////////////////////////
// Class for providing basic functionality over client data report packet
#define CLIENT_DATA_REPORT_SIZE (sizeof(sH_Data_Window) + sizeof(sH_Common))
class CTPData_Window: public CTPacket
{
sH_Data_Window *m_pReport;
public:
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data_Report::CTPClient_Data_Report
//stationary packet, it belong to stream
CTPData_Window():
CTPacket(CLIENT_DATA_REPORT_SIZE, 0)
,m_pReport(NULL)
{
if (m_bInitialized)
{
m_pHeader->wSize = CLIENT_DATA_REPORT_SIZE;
CTPacket::Set_Type(ETPT_CLIENT_DATA_REPORT);
m_pReport = (sH_Data_Window*)(m_pBuffer + sizeof(sH_Common));
}
}//CTPClient_Data_Report::CTPClient_Data_Report
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data_Report::CTPClient_Data_Report
//dynamic packet, it belong to Pool
CTPData_Window(CTPacket *i_pPacket):
CTPacket()
,m_pReport(NULL)
{
m_bInitialized = Attach(i_pPacket);
if (m_bInitialized)
{
m_pReport = (sH_Data_Window*)(m_pBuffer + sizeof(sH_Common));
}
}//CTPClient_Data_Report::CTPClient_Data_Report
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data_Report::Fill
inline tBOOL Fill(tUINT32 i_dwData_First_ID, tUINT32 i_dwData_Last_ID)
{
if ( (FALSE == m_bInitialized)
|| (TRUE == m_bShell)
)
{
return FALSE;
}
m_pReport->dwFirst_ID = i_dwData_First_ID;
m_pReport->dwLast_ID = i_dwData_Last_ID;
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data_Report::Chage_Endianness
virtual void Chage_Endianness()
{
m_pReport->dwFirst_ID = ntohl(m_pReport->dwFirst_ID);
m_pReport->dwLast_ID = ntohl(m_pReport->dwLast_ID);
}//CTPClient_Data_Report::Chage_Endianness
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data_Report::Get_First_ID
inline tUINT32 Get_First_ID()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pReport->dwFirst_ID;
}//CTPClient_Data_Report::Get_First_ID
////////////////////////////////////////////////////////////////////////////
//CTPClient_Data_Report::Get_Last_ID
inline tUINT32 Get_Last_ID()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pReport->dwLast_ID;
}//CTPClient_Data_Report::Get_Last_ID
};//CTPClient_Data_Report
////////////////////////////////////////////////////////////////////////////////
// Class for providing basic functionality over client alive packet
#define CLIENT_ALIVE_SIZE (sizeof(sH_Common))
class CTPClient_Ping: public CTPacket
{
public:
////////////////////////////////////////////////////////////////////////////
//CTPClient_Ping::CTPClient_Ping
//stationary packet, it belong to stream
CTPClient_Ping():
CTPacket(CLIENT_ALIVE_SIZE, 0)
{
if (m_bInitialized)
{
m_pHeader->wSize = CLIENT_ALIVE_SIZE;
CTPacket::Set_Type(ETPT_CLIENT_PING);
}
}//CTPClient_Ping::CTPClient_Ping
};
////////////////////////////////////////////////////////////////////////////////
// Class for providing basic functionality over client bye packet
#define CLIENT_BYE_SIZE (sizeof(sH_Common))
class CTPClient_Bye: public CTPacket
{
public:
////////////////////////////////////////////////////////////////////////////
//CTPClient_Ping::CTPClient_Ping
//stationary packet, it belong to stream
CTPClient_Bye():
CTPacket(CLIENT_BYE_SIZE, 0)
{
if (m_bInitialized)
{
m_pHeader->wSize = CLIENT_BYE_SIZE;
CTPacket::Set_Type(ETPT_CLIENT_BYE);
}
}//CTPClient_Ping::CTPClient_Ping
};//CTPClient_Ping
////////////////////////////////////////////////////////////////////////////////
// Class for providing basic functionality over server response packet
#define ACKNOWLEDGMENT_SIZE (sizeof(sH_Packet_Ack) + sizeof(sH_Common))
class CTPAcknowledgment:
public CTPacket
{
sH_Packet_Ack *m_pResponse;
public:
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::CTPServer_Response
//stationary packet, it belong to stream
CTPAcknowledgment(tUINT32 i_uBufferSize = TPACKET_MIN_SIZE, tUINT32 i_uPoolId = 0)
: CTPacket(i_uBufferSize, i_uPoolId)
, m_pResponse(NULL)
{
if (m_bInitialized)
{
Reset();
m_pResponse = (sH_Packet_Ack*)(m_pBuffer + sizeof(sH_Common));
}
}//CTPServer_Response::CTPServer_Response
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::CTPServer_Response
//dynamic packet, it belong to Pool
CTPAcknowledgment(CTPacket *i_pPacket):
CTPacket()
,m_pResponse(NULL)
{
m_bInitialized = Attach(i_pPacket);
if (m_bInitialized)
{
m_pResponse = (sH_Packet_Ack*)(m_pBuffer + sizeof(sH_Common));
}
}//CTPServer_Response::CTPServer_Response
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::Reset
inline void Reset()
{
m_pHeader->dwCRC32 = 0u;
m_pHeader->dwID = 0u;
m_pHeader->wBits = 0;
m_pHeader->wClient_ID = 0;
m_pHeader->wSize = ACKNOWLEDGMENT_SIZE;
CTPacket::Set_Type(ETPT_ACKNOWLEDGMENT);
}
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::Fill
inline tBOOL Fill(tUINT32 i_dwSource_ID, tUINT16 i_wResult)
{
if ( (FALSE == m_bInitialized)
|| (TRUE == m_bShell)
)
{
return FALSE;
}
m_pResponse->dwSource_ID = i_dwSource_ID;
m_pResponse->wResult = i_wResult;
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::Chage_Endianness
virtual void Chage_Endianness()
{
m_pResponse->dwSource_ID = ntohl(m_pResponse->dwSource_ID);
m_pResponse->wResult = ntohs(m_pResponse->wResult);
}//CTPServer_Response::Chage_Endianness
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::Get_Source_ID
inline tUINT32 Get_Source_ID()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pResponse->dwSource_ID;
}//CTPClient_Data_Report::Get_Source_ID
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::Get_Result
inline tUINT16 Get_Result()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pResponse->wResult;
}//CTPClient_Data_Report::Get_Result
////////////////////////////////////////////////////////////////////////////
//CTPServer_Response::Finalize
virtual void Finalize(tUINT32 i_dwPacket_ID,
tUINT16 i_wClient_ID,
tBOOL i_bSwapBytes)
{
m_pHeader->dwID = i_dwPacket_ID;
m_pHeader->wClient_ID = i_wClient_ID;
if (!i_bSwapBytes)
{
m_pHeader->dwCRC32 = Calculate_CRC(m_pHeader->wSize);
}
else
{
CTPacket::Chage_Endianness();
Chage_Endianness();
m_pHeader->dwCRC32 = ntohl(Calculate_CRC(ntohs(m_pHeader->wSize)));
}
}//CTPServer_Response::Finalize
};//CTPServer_Response
////////////////////////////////////////////////////////////////////////////////
// Class for providing basic functionality over server report packet
#define SERVER_REPORT_SIZE (TPACKET_MIN_SIZE)
#define SERVER_REPORT_HEADER_SIZE (sizeof(sH_Common) +\
offsetof(sH_Data_Window_Report, pID))
class CTPData_Window_Report:
public CTPacket
{
sH_Data_Window_Report *m_pReport;
tUINT32 m_dwCount;
public:
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::CTPServer_Report
//stationary packet, it belong to stream
CTPData_Window_Report()
: CTPacket(SERVER_REPORT_SIZE, 0)
, m_pReport(NULL)
, m_dwCount(0)
{
if (m_bInitialized)
{
Reset();
m_pReport = (sH_Data_Window_Report*)(m_pBuffer + sizeof(sH_Common));
m_dwCount = m_pHeader->wSize - SERVER_REPORT_HEADER_SIZE;
}
}//CTPServer_Report::CTPServer_Report
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::CTPServer_Report
//dynamic packet, it belong to Pool
CTPData_Window_Report(CTPacket *i_pPacket):
CTPacket()
,m_pReport(NULL)
,m_dwCount(0)
{
m_bInitialized = Attach(i_pPacket);
if (m_bInitialized)
{
m_pReport = (sH_Data_Window_Report*)(m_pBuffer + sizeof(sH_Common));
m_dwCount = m_pHeader->wSize - SERVER_REPORT_HEADER_SIZE;
}
}//CTPServer_Report::CTPServer_Report
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::Reset
inline void Reset()
{
m_pHeader->dwCRC32 = 0u;
m_pHeader->dwID = 0u;
m_pHeader->wBits = 0;
m_pHeader->wClient_ID = 0;
m_pHeader->wSize = SERVER_REPORT_SIZE;
CTPacket::Set_Type(ETPT_SERVER_DATA_REPORT);
}//CTPServer_Report::Reset
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::Is_ID
inline tBOOL Is_ID(tUINT32 i_dwFirst_ID, tUINT32 i_dwCurrent_ID)
{
tUINT32 l_dwOffset = ID_Difference(i_dwFirst_ID, i_dwCurrent_ID);
if ( (NULL == m_pReport)
|| (l_dwOffset >= (m_dwCount << 3))
)
{
return FALSE;
}
return ( 0 != (m_pReport->pID[l_dwOffset >> 3] & (1 << (l_dwOffset % 8))) );
}//CTPServer_Report::Is_ID
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::Clr_IDs
inline tBOOL Clr_IDs()
{
if ( (FALSE == m_bInitialized)
|| (TRUE == m_bShell)
)
{
return FALSE;
}
memset(m_pReport->pID, 0, m_dwCount);
return TRUE;
} //Clr_IDs
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::Set_ID
inline tBOOL Set_ID(tUINT32 i_dwFirst_ID, tUINT32 i_dwCurrent_ID)
{
tUINT32 l_dwOffset = ID_Difference(i_dwFirst_ID, i_dwCurrent_ID);
if ( (NULL == m_pReport)
|| (l_dwOffset >= (m_dwCount << 3))
)
{
return FALSE;
}
m_pReport->pID[l_dwOffset >> 3] |= (1 << (l_dwOffset % 8));
return TRUE;
}//CTPServer_Report::Set_ID
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::Get_Source_ID
inline tUINT32 Get_Source_ID()
{
if (FALSE == m_bInitialized)
{
return 0;
}
return m_pReport->dwSource_ID;
}//CTPServer_Report::Get_Source_ID
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::Fill
inline tBOOL Fill(tUINT32 i_dw_Source_ID)
{
if ( (FALSE == m_bInitialized)
|| (TRUE == m_bShell)
)
{
return FALSE;
}
m_pReport->dwSource_ID = i_dw_Source_ID;
return TRUE;
}//CTPServer_Report::Fill
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::Finalize
virtual void Finalize(tUINT32 i_dwPacket_ID,
tUINT16 i_wClient_ID,
tBOOL i_bSwapBytes)
{
m_pHeader->dwID = i_dwPacket_ID;
m_pHeader->wClient_ID = i_wClient_ID;
if (!i_bSwapBytes)
{
m_pHeader->dwCRC32 = Calculate_CRC(m_pHeader->wSize);
}
else
{
CTPacket::Chage_Endianness();
Chage_Endianness();
m_pHeader->dwCRC32 = ntohl(Calculate_CRC(ntohs(m_pHeader->wSize)));
}
}//CTPServer_Report::Finalize
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::Chage_Endianness
virtual void Chage_Endianness()
{
m_pReport->dwSource_ID = ntohl(m_pReport->dwSource_ID);
}//CTPServer_Report::Chage_Endianness
private:
////////////////////////////////////////////////////////////////////////////
//CTPServer_Report::ID_Difference
inline tUINT32 ID_Difference(tUINT32 i_dwFirst_ID, tUINT32 i_dwCurrent_ID)
{
if (i_dwCurrent_ID < i_dwFirst_ID)
{
return ((TPACKET_MAX_ID - i_dwFirst_ID) + i_dwCurrent_ID);
}
return (i_dwCurrent_ID - i_dwFirst_ID);
}//CTPServer_Report::ID_Difference
};//CTPServer_Report
////////////////////////////////////////////////////////////////////////////////
// Class for providing basic functionality over server info ext packet
#define EXT_SRV_INFO_SIZE (sizeof(sH_Ext) + sizeof(sH_Ext_Srv_Info))
class CTPESrv_Info
{
size_t m_szMax;
tUINT8 m_pBuffer[sizeof(sH_Ext) + sizeof(sH_Ext_Srv_Info)];
sH_Ext *m_pExt;
sH_Ext_Srv_Info *m_pInfo;
public:
////////////////////////////////////////////////////////////////////////////
//CTPESrv_Info::CTPESrv_Info
//stationary packet, it belong to stream
CTPESrv_Info()
: m_szMax(sizeof(sH_Ext) + sizeof(sH_Ext_Srv_Info))
, m_pExt(NULL)
, m_pInfo(NULL)
{
memset(m_pBuffer, 0, m_szMax);
m_pExt = (sH_Ext*)m_pBuffer;
m_pInfo = (sH_Ext_Srv_Info*)(m_pBuffer + sizeof(sH_Ext));
m_pExt->wSize = (tUINT16)m_szMax;
m_pExt->wType = ETPE_SERVER_NETWORK_INFO;
}//CTPESrv_Info::CTPESrv_Info
////////////////////////////////////////////////////////////////////////////
//CTPESrv_Info::Fill
inline void Fill(tUINT32 i_dwServerV, tUINT16 i_wProtocolV, tUINT16 i_wMTU, tUINT32 i_dwSocketBuffer)
{
m_pInfo->dwServerVersion = i_dwServerV;
m_pInfo->dwSocket_Buffer = i_dwSocketBuffer;
m_pInfo->wMTU = i_wMTU;
m_pInfo->wProtocolVersion = i_wProtocolV;
}
////////////////////////////////////////////////////////////////////////////
//CTPESrv_Info::Chage_Endianness
virtual void Chage_Endianness()
{
m_pExt->wSize = ntohs(m_pExt->wSize);
m_pExt->wType = ntohs(m_pExt->wType);
m_pInfo->dwServerVersion = ntohl(m_pInfo->dwServerVersion);
m_pInfo->dwSocket_Buffer = ntohl(m_pInfo->dwSocket_Buffer);
m_pInfo->wMTU = ntohs(m_pInfo->wMTU);
m_pInfo->wProtocolVersion = ntohs(m_pInfo->wProtocolVersion);
}//CTPESrv_Info::Chage_Endianness
////////////////////////////////////////////////////////////////////////////
//CTPESrv_Info::GetBuffer
inline const tUINT8 *GetBuffer()
{
return m_pBuffer;
}
////////////////////////////////////////////////////////////////////////////
//CTPESrv_Info::GetBufferSize
inline size_t GetBufferSize()
{
return m_szMax;
}
};//CTPESrv_Info
#if defined(_DEBUG) || defined(DEBUG)
#define PACKET_PRINT(i_Log, i_Prefix, i_Packet) Packet_Print(i_Log,i_Prefix, i_Packet);
#else
#define PACKET_PRINT(i_Log, i_Prefix, i_Packet)
#endif
inline void Packet_Print(IJournal *i_pLog,
const tXCHAR *l_pPrefix,
CTPacket *i_pPacket)
{
if ( (NULL == i_pLog)
|| (IJournal::eLEVEL_TRACE < i_pLog->Get_Verbosity())
|| (NULL == i_pPacket)
)
{
return;
}
eTPacket_Type l_eType = i_pPacket->Get_Type();
switch (l_eType)
{
case ETPT_CLIENT_HELLO:
{
CTPClient_Hello l_cHello(i_pPacket);
JOURNAL_DEBUG(i_pLog,
TM("%s [Initial] ID=%d, Size=%d, Protocol=%d, MaxSize=%d Process[%d/%s]"),
l_pPrefix,
(tUINT32)l_cHello.Get_ID(),
(tUINT32)l_cHello.Get_Size(),
(tUINT32)l_cHello.Get_Protocol_Version(),
(tUINT32)l_cHello.Get_Data_Max_Size(),
(tUINT32)l_cHello.Get_Process_ID(),
l_cHello.Get_Process_Name()
);
break;
}
case ETPT_CLIENT_PING:
{
JOURNAL_DEBUG(i_pLog,
TM("%s [Alive] ID=%d, Size=%d"),
l_pPrefix,
(tUINT32)i_pPacket->Get_ID(),
(tUINT32)i_pPacket->Get_Size()
);
break;
}
case ETPT_CLIENT_DATA:
{
break;
}
case ETPT_CLIENT_DATA_REPORT:
{
CTPData_Window l_cReport(i_pPacket);
JOURNAL_DEBUG(i_pLog,
TM("%s [Data report] ID=%d, Size=%d, window ID [%d .. %d]"),
l_pPrefix,
(tUINT32)l_cReport.Get_ID(),
(tUINT32)l_cReport.Get_Size(),
(tUINT32)l_cReport.Get_First_ID(),
(tUINT32)l_cReport.Get_Last_ID()
);
break;
}
case ETPT_CLIENT_BYE:
{
JOURNAL_DEBUG(i_pLog,
TM("%s [Bye] ID=%d, Size=%d"),
l_pPrefix,
(tUINT32)i_pPacket->Get_ID(),
(tUINT32)i_pPacket->Get_Size()
);
break;
}
case ETPT_ACKNOWLEDGMENT:
{
CTPAcknowledgment l_cResponse(i_pPacket);
JOURNAL_DEBUG(i_pLog,
TM("%s [Response] ID=%d, Size=%d, Source ID=%d Result=%d"),
l_pPrefix,
(tUINT32)l_cResponse.Get_ID(),
(tUINT32)l_cResponse.Get_Size(),
(tUINT32)l_cResponse.Get_Source_ID(),
(tUINT32)l_cResponse.Get_Result()
);
break;
}
case ETPT_SERVER_DATA_REPORT:
{
CTPData_Window_Report l_cReport(i_pPacket);
JOURNAL_DEBUG(i_pLog,
TM("%s [Data report] ID=%d, Size=%d, Source ID=%d"),
l_pPrefix,
(tUINT32)l_cReport.Get_ID(),
(tUINT32)l_cReport.Get_Size(),
(tUINT32)l_cReport.Get_Source_ID()
);
break;
}
case ETPT_SERVER_CHAINED:
{
break;
}
default:
{
JOURNAL_DEBUG(i_pLog,
TM("%s [Unknown] ID=%d, Size=%d"),
l_pPrefix,
(tUINT32)i_pPacket->Get_ID(),
(tUINT32)i_pPacket->Get_Size()
);
break;
}
}
}
#endif //TPACKETS_H