summaryrefslogtreecommitdiffstats
path: root/K2LABI/IPC/IPCFlowDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'K2LABI/IPC/IPCFlowDecoder.cpp')
-rw-r--r--K2LABI/IPC/IPCFlowDecoder.cpp140
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;
+}