// ProtocolStack.h // Declaration of class cProtocolStack #ifndef __PROTOCOLSTACK_H #define __PROTOCOLSTACK_H #include "ACMessage.h" #define DEFAULT_HEADER_SIZE 16 #define FRAGMENT_SIZE 448 #pragma pack( push, 1 ) // The packet header struct cPacketHeader { DWORD m_dwSequence; DWORD m_dwFlags; DWORD m_dwCRC; WORD m_wUnk1; WORD m_wUnk2; WORD m_wTotalSize; WORD m_wUnk3; }; #pragma pack( pop ) class cMessageStack { public: #pragma pack( push, 1 ) struct cMessageHeader { DWORD m_dwSequence; DWORD m_dwObjectID; WORD m_wFragmentCount; WORD m_wFragmentLength; WORD m_wFragmentIndex, m_wUnknown1; }; #pragma pack( pop ) class cProtocolMessage : public ACMessage { protected: mutable BYTE *m_pbData; mutable bool *m_pbReceived; mutable bool m_bOwn; public: cProtocolMessage( BYTE *pbData ); cProtocolMessage( const cProtocolMessage &msg ); ~cProtocolMessage(); cMessageHeader *getMessageHeader() const { return reinterpret_cast< cMessageHeader * >( m_pbData ); } cProtocolMessage &operator= ( const cProtocolMessage &msg ); // ACMessage interface implementation for protocol stack virtual BYTE *getData () { return m_pbData + sizeof( cMessageHeader ); } virtual DWORD getSize () { return getMessageHeader()->m_wFragmentLength - sizeof( cMessageHeader ); } virtual DWORD getType () { return *reinterpret_cast< DWORD * >( m_pbData + sizeof( cMessageHeader ) ); } bool isComplete() const; bool fragmentMatch( BYTE *pFragmentStart ); void insertFragment( BYTE *pFragmentStart ); static DWORD calcMessageLength( BYTE *pbHeader ); }; private: typedef std::list< cProtocolMessage > cMessageList; ACMessageSink *m_pCallback; cMessageList m_messages; public: cMessageStack(); ~cMessageStack(); void start( ACMessageSink * ); void stop(); void processPacket( DWORD dwLength, BYTE *pbPayload ); void processPacketOut( DWORD dwLength, const BYTE *pbPayload ); private: void splitPacket( DWORD dwLength, BYTE *pbPayload ); void splitPacketOut( DWORD dwLength, const BYTE *pbPayload ); }; #endif