summaryrefslogtreecommitdiffstats
path: root/K2LABI/IPC
diff options
context:
space:
mode:
Diffstat (limited to 'K2LABI/IPC')
-rw-r--r--K2LABI/IPC/IPCFlowDecoder.cpp140
-rw-r--r--K2LABI/IPC/IPCFlowDecoder.h28
-rw-r--r--K2LABI/IPC/Ipc.h29
-rw-r--r--K2LABI/IPC/K2LIPC.cpp70
-rw-r--r--K2LABI/IPC/K2LIPC.h199
5 files changed, 466 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;
+}
diff --git a/K2LABI/IPC/IPCFlowDecoder.h b/K2LABI/IPC/IPCFlowDecoder.h
new file mode 100644
index 0000000..d099275
--- /dev/null
+++ b/K2LABI/IPC/IPCFlowDecoder.h
@@ -0,0 +1,28 @@
+#ifndef __IPC_FLOW_DECODER_H__
+#define __IPC_FLOW_DECODER_H__
+
+#include "FlowDecoder.h"
+#include "K2LIPC.h"
+
+using namespace K2L::Automotive::IPC;
+class CIpc;
+
+class CIPCFlowDecoder : public CFlowDecoder
+{
+public:
+ CIPCFlowDecoder(CIpc* pIpc);
+ ~CIPCFlowDecoder();
+ virtual void Reset();
+
+protected:
+ eStateRetVal ReceiveHeader();
+ eStateRetVal ReceivePacket();
+
+private:
+ BYTE* m_pPacket;
+ unsigned long m_ReceiveIndex;
+ int m_ValidPacketCount;
+ CIpc* m_pIpc;
+};
+
+#endif // __IPC_FLOW_DECODER_H__
diff --git a/K2LABI/IPC/Ipc.h b/K2LABI/IPC/Ipc.h
new file mode 100644
index 0000000..1775ebf
--- /dev/null
+++ b/K2LABI/IPC/Ipc.h
@@ -0,0 +1,29 @@
+#pragma once
+#include "K2LIPC.h"
+#include "SLock.h"
+
+using namespace K2L::Automotive::IPC;
+
+class CIpc : public IIpc
+{
+public:
+ CIpc();
+ virtual ~CIpc();
+
+ int Init(IIPCListener* pListener);
+ int Deinit();
+ int FormatRequest(BYTE channel, BYTE ifaceId, BYTE funId, DWORD dwSenderID, const BYTE *pData, DWORD dataLen, BYTE* pResult, int nResultLen, int* nResultLenNeeded);
+ IIPCListener* GetListener();
+ void OnPacket(CIpcPacket* pPacket);
+ void Decode(BYTE* pBuffer, DWORD nLen);
+ IIPCListener* CreateListener(FCT_OnMessageEvent callback, FCT_OnEvent error, FCT_OnEvent overflow);
+ void DestroyListener();
+
+private:
+ CIPCFlowDecoder* m_pFlowDecoder;
+ BYTE* m_pResultBuffer;
+ int m_nResultLen;
+ int m_errorCode;
+ IIPCListener* m_pIpcListener;
+ CLock m_lock;
+}; \ No newline at end of file
diff --git a/K2LABI/IPC/K2LIPC.cpp b/K2LABI/IPC/K2LIPC.cpp
new file mode 100644
index 0000000..5d17359
--- /dev/null
+++ b/K2LABI/IPC/K2LIPC.cpp
@@ -0,0 +1,70 @@
+#include "windows-adapter.h"
+#include "K2LIPC.h"
+#include "IPCFlowDecoder.h"
+#include "Ipc.h"
+
+IIpc* CIpcFactory::CreateIpc()
+{
+ return new CIpc();
+}
+
+//-----------------------------------------------------------------------------
+void CIpcFactory::DestroyIpc(IIpc* pIpc)
+{
+ delete pIpc;
+}
+
+//-----------------------------------------------------------------------------
+K2LABI_API IPC_HANDLE CreateIPC()
+{
+ CIpc* pIpc = new CIpc;
+ return reinterpret_cast<IPC_HANDLE>(pIpc);
+}
+
+//-----------------------------------------------------------------------------
+K2LABI_API void DestroyIPC(IPC_HANDLE hIpc)
+{
+ CIpc* pIpc = reinterpret_cast<CIpc*>(hIpc);
+ delete pIpc;
+}
+
+//-----------------------------------------------------------------------------
+K2LABI_API int IPCInit(IPC_HANDLE hIpc, FCT_OnMessageEvent callback, FCT_OnEvent error, FCT_OnEvent overflow)
+{
+ CIpc* pIpc = reinterpret_cast<CIpc*>(hIpc);
+ if (!pIpc)
+ return -1;
+
+ IIPCListener* pListener = pIpc->CreateListener(callback, error, overflow);
+ return pIpc->Init(pListener);
+}
+
+//-----------------------------------------------------------------------------
+K2LABI_API int IPCDeinit(IPC_HANDLE hIpc)
+{
+ CIpc* pIpc = reinterpret_cast<CIpc*>(hIpc);
+ if (!pIpc)
+ return -1;
+
+ pIpc->DestroyListener();
+ return pIpc->Deinit();
+}
+
+//-----------------------------------------------------------------------------
+K2LABI_API int IPCFormatRequest(IPC_HANDLE hIpc, BYTE channel, BYTE ifaceId, BYTE funId, DWORD dwSenderID, const BYTE *pReqData, DWORD dataLen, BYTE* pResult, int nResultLen, int* nNeededResultLen)
+{
+ CIpc* pIpc = reinterpret_cast<CIpc*>(hIpc);
+ if (!pIpc)
+ return -1;
+
+ return pIpc->FormatRequest(channel, ifaceId, funId, dwSenderID, pReqData, dataLen, pResult, nResultLen, nNeededResultLen);
+}
+
+//-----------------------------------------------------------------------------
+K2LABI_API void IPCDecode(IPC_HANDLE hIpc, BYTE* pData, int nDataLen)
+{
+ CIpc* pIpc = reinterpret_cast<CIpc*>(hIpc);
+
+ if (pIpc)
+ pIpc->Decode(pData, nDataLen);
+}
diff --git a/K2LABI/IPC/K2LIPC.h b/K2LABI/IPC/K2LIPC.h
new file mode 100644
index 0000000..e959dbf
--- /dev/null
+++ b/K2LABI/IPC/K2LIPC.h
@@ -0,0 +1,199 @@
+/*=== K2L GmbH ===============================================================*/
+/**
+\file
+ This file contains the API of the \ref IPC interface.
+
+\ingroup IPC
+
+\par COPYRIGHT (c) 2000-2011 by K2L GmbH
+ All rights reserved.
+*/
+/*==============================================================================
+ Alle Rechte an der Software verbleiben bei der K2L GmbH.
+
+ Die K2L GmbH raeumt dem Lizenznehmer nach vollstaendiger
+ Bezahlung der Lizenzgebuehr ein nicht ausschliessliches,
+ unwiderrufliches, nicht uebertragbares, zeitlich und geografisch
+ nicht beschraenktes Recht zur Nutzung der jeweils
+ auftragsgegenstaendlichen Software innerhalb des Lizenznehmers ein.
+
+ Die Weitergabe des Nutzungsrechts durch den Lizenznehmer ist auf
+ dessen Zulieferer beschraenkt. Die Zulieferer sind zu verpflichten,
+ die Software nur im Rahmen von Projekten fuer den Lizenznehmer
+ zu verwenden; weitere Rechte der Zulieferer sind auszuschliessen.
+===HEADER END=================================================================*/
+//@{
+
+#pragma once
+
+/// \defgroup IPC Interprocess communication
+/// The IPC group ...
+namespace K2L
+{
+ namespace Automotive
+ {
+ namespace IPC
+ {
+
+class IIpc;
+
+/// Identifies the head of the packet.
+#define ABI_IPC_PACKET_HEAD 0x04
+
+/// Identifies the IPC channel 7.
+#define ABI_IPC_CHANNEL7 0x07
+
+/// Identifies the IPC channel 8.
+#define ABI_IPC_CHANNEL8 0x08
+
+#pragma pack(push, 1)
+/// \brief Class holding all informations to create a IPC message.
+/// \ingroup IPC
+class CIpcPacket
+{
+public:
+ /// The header of the IPC packet.
+ BYTE m_head;
+
+ /// The channel of the IPC packet.
+ BYTE m_channel;
+
+ /// The length of the IPC packet.
+ DWORD m_length;
+
+ /// The error code of the IPC packet.
+ BYTE m_errorCode;
+
+ /// Checksum of the IPC header.
+ BYTE m_hdrCrc;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+/// \brief Class holding all informations to create a IPC request.
+/// \ingroup IPC
+class CRequest
+{
+public:
+ /// Message processing group in the ABI device.
+ BYTE m_interface;
+
+ /// Function id of the request.
+ BYTE m_function;
+
+ /// Request Id.
+ DWORD m_requestId;
+};
+#pragma pack(pop)
+
+/*============================================================================*/
+/// \brief Interface of IPC event listener.
+/// \note Abstract base class. So it has to be implemented.
+/// \ingroup IPC
+/*============================================================================*/
+class K2LABI_API IIPCListener
+{
+public:
+ virtual ~IIPCListener() {}
+
+ /// Called if packet arrived.
+ /// \param[in] pIpc Pointer to IPC that has occured event.
+ /// \param[in] pPacket Pointer to data package.
+ /// \param[in] nLen Length of package.
+ virtual void OnMessage(IIpc* pIpc, BYTE channel, BYTE errorCode, BYTE* pPacket, int nLen) = 0;
+
+ /// Called if error occured.
+ /// \param[in] pIpc Pointer to IPC that has occured event.
+ virtual void OnError(IIpc* pIpc) = 0;
+
+ /// Called if message lost caused by an overflow.
+ /// \param[in] pIpc Pointer to IPC that has occured event.
+ virtual void OnMessageLost(IIpc* pIpc) = 0;
+};
+
+/*============================================================================*/
+/// \brief Interface of interprocess connection.
+/// \ingroup IPC
+/*============================================================================*/
+class K2LABI_API IIpc
+{
+public:
+ virtual ~IIpc() {}
+
+ /// Initializes IPC connection.
+ /// \param[in] Device to connect.
+ /// \param[in] Event listener.
+ /// \return 0 if operation successful.
+ /// \return !0 if operation failed.
+ virtual int Init(IIPCListener* pListener) = 0;
+
+ /// Deinitializes IPC connection.
+ /// \return 0 if operation successful.
+ /// \return !0 if operation failed.
+ virtual int Deinit() = 0;
+
+ /// Sends a request to the device.
+ /// \param[in] Namespace ID of command.
+ /// \param[in] Function ID of command.
+ /// \param[in] Pointer to data that should be send.
+ /// \param[in] Length of data.
+ /// \param[out] Length of result.
+ /// \param[out] Error code of operation.
+ /// \return Response of request. NULL if no response returned.
+ virtual int FormatRequest(BYTE channel, BYTE ifaceId, BYTE funId, DWORD dwSenderID, const BYTE *pData, DWORD dataLen, BYTE* pResult, int nResultLen, int* nResultLenNeeded) = 0;
+
+ /// Decodes a IPC message from the buffer.
+ /// \param[in] pPipe Pipe to check if an overflow occurr.
+ /// \param[in] pBuffer Pointer to the first byte of message that should be decoded.
+ /// \param[in] nLen Length of message.
+ virtual void Decode(BYTE* pBuffer, DWORD nLen) = 0;
+
+ /// Gets a pointer to the registered event listener.
+ /// \return Pointer to event listener.
+ virtual IIPCListener* GetListener() = 0;
+};
+
+/*============================================================================*/
+/// \brief Factory to create IPC connections.
+/// \ingroup IPC
+/*============================================================================*/
+class K2LABI_API CIpcFactory
+{
+public:
+ /// Create new IPC connection.
+ /// \return Pointer to new IPC connection.
+ static IIpc* CreateIpc();
+
+ /// Destroy IPC connection.
+ /// \param[in] Pointer to IPC connection that should be destroied.
+ static void DestroyIpc(IIpc* pIpc);
+};
+ }
+ }
+}
+
+/*============================================================================*/
+/* C interface */
+/*============================================================================*/
+
+extern "C"
+{
+#define IPC_HANDLE HANDLE
+
+typedef void (*FCT_OnMessageEvent) (IPC_HANDLE, BYTE, BYTE, BYTE*, int);
+typedef void (*FCT_OnEvent) (IPC_HANDLE);
+
+K2LABI_API IPC_HANDLE CreateIPC ();
+K2LABI_API void DestroyIPC (IPC_HANDLE hIpc);
+
+K2LABI_API int IPCInit (IPC_HANDLE hIpc, FCT_OnMessageEvent callback, FCT_OnEvent error, FCT_OnEvent overflow);
+K2LABI_API int IPCDeinit (IPC_HANDLE hIpc);
+K2LABI_API int IPCFormatRequest (IPC_HANDLE hIpc, BYTE channel, BYTE ifaceId, BYTE funId, DWORD dwSenderID, const BYTE *pReqData, DWORD dataLen, BYTE* pResult, int nResultLen, int* nNeededResultLen);
+K2LABI_API void IPCDecode (IPC_HANDLE hIpc, BYTE* pData, int nDataLen);
+K2LABI_API void IPCDecodeFlow (IPC_HANDLE hIpc, HANDLE hReaderPipe, BYTE* pData, int nDataLen);
+}
+
+//@}
+/*============================================================================*/
+/* END OF FILE */
+/*============================================================================*/