diff options
Diffstat (limited to 'K2LABI/IPC/IPCFlowDecoder.cpp')
-rw-r--r-- | K2LABI/IPC/IPCFlowDecoder.cpp | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/K2LABI/IPC/IPCFlowDecoder.cpp b/K2LABI/IPC/IPCFlowDecoder.cpp new file mode 100644 index 0000000..6b6ec19 --- /dev/null +++ b/K2LABI/IPC/IPCFlowDecoder.cpp @@ -0,0 +1,140 @@ +#include "windows-adapter.h" +#include "IPCFlowDecoder.h" +#include "Ipc.h" +#include <assert.h> + + +#define PACKET_BUFFER_SIZE (1 << 18) +#define PACKET_TEST_DEPTH 0 + +CIPCFlowDecoder::CIPCFlowDecoder(CIpc* pIpc) : CFlowDecoder() + , m_pPacket(new BYTE[PACKET_BUFFER_SIZE]) + , m_ValidPacketCount(PACKET_TEST_DEPTH) + , m_ReceiveIndex(0) + , m_pIpc(pIpc) +{ +} + +CIPCFlowDecoder::~CIPCFlowDecoder() +{ + delete [] m_pPacket; +} + +void CIPCFlowDecoder::Reset() +{ + m_ReceiveIndex = 0; + m_ValidPacketCount = 0; + this->CFlowDecoder::Reset(); +} + +CFlowDecoder::eStateRetVal CIPCFlowDecoder::ReceiveHeader() +{ + unsigned long bytesMissingForHeader = sizeof(CIpcPacket) - m_ReceiveIndex; + unsigned long bytesToAppend = (bytesMissingForHeader <= GetNumberOfBytesInBuffer() ) ? bytesMissingForHeader : GetNumberOfBytesInBuffer(); + + if (!CopyFromBuffer(&m_pPacket[m_ReceiveIndex], bytesToAppend) ) + return E_STATE_NEEDS_MORE_DATA; + + m_ReceiveIndex += bytesToAppend; + + if (m_ReceiveIndex < sizeof(CIpcPacket) ) + { + RemoveBytesFromBuffer(bytesToAppend); + return E_STATE_NEEDS_MORE_DATA; + } + + CIpcPacket* pHeader = reinterpret_cast<CIpcPacket*>(m_pPacket); + + if (pHeader->m_head != ABI_IPC_PACKET_HEAD) + { + if(m_nSynchronized && m_pIpc) + { + //::OutputDebugString("Check: Head wrong\n"); + IIPCListener* listener = m_pIpc->GetListener(); + + if(listener) + listener->OnError(m_pIpc); + } + + // Something went wrong... + m_ReceiveIndex = 0; + m_ValidPacketCount = 0; + + // Remove 1 byte from buffer + RemoveBytesFromBuffer(1); + return E_STATE_GOT_WRONG_DATA; + } + + // We've found a header now check the checksum + unsigned char checksum = 0; + + // Omit last byte -> checksum! + for (int i = 0; i < sizeof(CIpcPacket) - 1; i++) + { + checksum += m_pPacket[i]; + } + + if (checksum != pHeader->m_hdrCrc) + { + if(m_nSynchronized && m_pIpc) + { + //::OutputDebugString("Check: Crc wrong\n"); + IIPCListener* listener = m_pIpc->GetListener(); + if(listener) + listener->OnError(m_pIpc); + } + + // Something went wrong... + m_ReceiveIndex = 0; + m_ValidPacketCount = 0; + + // Remove 1 byte from buffer + RemoveBytesFromBuffer(1); + return E_STATE_GOT_WRONG_DATA; + } + //if(!m_nSynchronized) ::OutputDebugString("Check: Header correct\n"); + m_nSynchronized = true; + + RemoveBytesFromBuffer(bytesToAppend); + + // Valid header found!!! + return E_STATE_OK; +} + +CFlowDecoder::eStateRetVal CIPCFlowDecoder::ReceivePacket() +{ + unsigned long nLengthOfPacket = reinterpret_cast<CIpcPacket*>(m_pPacket)->m_length + sizeof(CIpcPacket); + unsigned long bytesMissingForPacket = nLengthOfPacket - m_ReceiveIndex; + unsigned long bytesToAppend = (bytesMissingForPacket > GetNumberOfBytesInBuffer() ) ? GetNumberOfBytesInBuffer() : bytesMissingForPacket; + + // Copy buffer... should (must) never fail! + if (!CopyFromBuffer(&m_pPacket[m_ReceiveIndex], bytesToAppend) ) + return E_STATE_NEEDS_MORE_DATA; + + // Accept the data as valid now and go on... + m_ReceiveIndex += bytesToAppend; + + // Remove bytes from source buffer... + RemoveBytesFromBuffer(bytesToAppend); + + // Received enough data? + if (m_ReceiveIndex < nLengthOfPacket) + return E_STATE_NEEDS_MORE_DATA; + + m_ReceiveIndex = 0; + + if (m_ValidPacketCount >= PACKET_TEST_DEPTH) + { + // Dispatch Message if there's was no overflow during copy! + if (m_pIpc) + { + m_pIpc->OnPacket(reinterpret_cast<CIpcPacket*>(m_pPacket) ); + } + } + else + { + m_ValidPacketCount++; + } + + return E_STATE_OK; +} |