summaryrefslogtreecommitdiffstats
path: root/ABI-IPC/abi-ipc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ABI-IPC/abi-ipc.cpp')
-rw-r--r--ABI-IPC/abi-ipc.cpp172
1 files changed, 172 insertions, 0 deletions
diff --git a/ABI-IPC/abi-ipc.cpp b/ABI-IPC/abi-ipc.cpp
new file mode 100644
index 0000000..2730811
--- /dev/null
+++ b/ABI-IPC/abi-ipc.cpp
@@ -0,0 +1,172 @@
+//
+// abi-ipc.cpp
+// AmbientLight
+//
+// Created by Thorsten Kummermehr on 10/9/13.
+//
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "abi-ipc.h"
+
+using namespace K2L::Automotive::ABI;
+using namespace K2L::Automotive::ABI_IPC;
+
+
+AbiUsbIpc::AbiUsbIpc() : _isConnected( false ), _receiveThreadIsRunning( false ), _receiveCB( NULL ),
+ _receiveCBArgument( NULL ), _rxHandle( -1 ), _txHandle( -1 )
+{
+}
+
+AbiUsbIpc::~AbiUsbIpc()
+{
+ Disconnect();
+}
+
+bool AbiUsbIpc::Connect( const char *cdevRx, const char *cdevTx )
+{
+ fprintf( stdout, "Connecting to RX:%s TX:%s\n", cdevRx, cdevTx );
+ bool success = -1 != ( _rxHandle = open( cdevRx, O_RDONLY ) );
+ if( success )
+ {
+ _isConnected = -1 != ( _txHandle = open( cdevTx, O_WRONLY ) );
+ }
+
+ if( !_isConnected )
+ {
+ if( -1 != _rxHandle )
+ {
+ close( _rxHandle );
+ _rxHandle = -1;
+ }
+ fprintf( stderr, "Failed to open cdev\n" );
+ return false;
+ }
+
+ if( pthread_create( &_receiveThread, NULL, ReceiveThread, this ) )
+ {
+ fprintf( stderr, "Failed to create receive thread\n" );
+ Disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+bool AbiUsbIpc::Connect( const char *cdevRxTx )
+{
+ fprintf( stdout, "Connecting to combined RX and TX:%s\n", cdevRxTx );
+ _isConnected = -1 != ( _rxHandle = _txHandle = open( cdevRxTx, O_RDWR ) );
+ if( !_isConnected )
+ {
+ fprintf( stderr, "Failed to open cdev\n" );
+ return false;
+ }
+
+ if( pthread_create( &_receiveThread, NULL, ReceiveThread, this ) )
+ {
+ fprintf( stderr, "Failed to create receive thread\n" );
+ Disconnect();
+ return false;
+ }
+
+ return true;
+}
+
+void AbiUsbIpc::Disconnect( void )
+{
+ if( !_isConnected )
+ return;
+ _isConnected = false;
+
+ //Give the receive thread one second to shutdown
+ for( int i = 0; i < 100; i++ )
+ {
+ if( _receiveThreadIsRunning )
+ usleep( 10000 );
+ else
+ break;
+ }
+
+ if( 0 != _rxHandle )
+ {
+ close( _rxHandle );
+ _rxHandle = -1;
+ }
+
+ if( 0 != _txHandle )
+ {
+ close( _txHandle );
+ _txHandle = -1;
+ }
+}
+
+bool AbiUsbIpc::IsConnected()
+{
+ return _isConnected;
+}
+
+int AbiUsbIpc::Send( const BYTE *data, DWORD length )
+{
+ if( !_isConnected )
+ return 0;
+ return ( int )write( _txHandle, data, length );
+}
+
+void AbiUsbIpc::SetReceivePriority( int prio )
+{
+}
+
+void AbiUsbIpc::SetReceiveCallback( AbiIpcDevice_RxCB_t receiveCB, void *cbArg )
+{
+ if( NULL != _receiveCB )
+ {
+ fprintf( stderr,
+ "The actual implementaion of SetReceiveCallback supports only one listener. To be improved.\n" );
+ return;
+ }
+ _receiveCB = receiveCB;
+ _receiveCBArgument = cbArg;
+}
+
+void *AbiUsbIpc::ReceiveThread( void *param )
+{
+ if( NULL == param )
+ {
+ fprintf( stderr,
+ "Receive thread could not be started, because the this pointer was not passed as argument\n" );
+ pthread_exit( 0 );
+ }
+ AbiUsbIpc *that = ( AbiUsbIpc * )param;
+
+ that->_receiveThreadIsRunning = true;
+ while( that->_isConnected )
+ {
+ ssize_t rc = read( that->_rxHandle, that->receiveBuffer, sizeof( that->receiveBuffer ) );
+ if( rc <= 0 )
+ {
+ //Receive error (<0) or other side closed connection (==0)
+ //fprintf( stdout, "Closing connection because read returned value %d\n", ( uint32_t )rc );
+ //if( that->_isConnected )
+ //{
+ // that->Disconnect();
+ //}
+ }
+ else
+ {
+ // "rc"-bytes received
+ if( NULL != that->_receiveCB )
+ {
+ that->_receiveCB( ( uint8_t * )&that->receiveBuffer, ( uint32_t )rc, that->_receiveCBArgument );
+ }
+ }
+ }
+ that->_receiveThreadIsRunning = false;
+ pthread_exit( 0 );
+}