summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchristian mueller <christian.ei.mueller@bmw.de>2011-12-20 23:58:20 +0100
committerchristian mueller <christian.ei.mueller@bmw.de>2011-12-20 23:58:20 +0100
commit18d1c7ee814993ae3fbee5635650e55472dac587 (patch)
tree598b6302cb883e9eaa58469d6e6e68a6e92a1c6c
parent1c992fd131eab06ee4f5a7090377031975092aba (diff)
downloadaudiomanager-18d1c7ee814993ae3fbee5635650e55472dac587.tar.gz
* first version of the sockethandler with test
-rw-r--r--AudioManagerDaemon/include/SocketHandler.h137
-rw-r--r--AudioManagerDaemon/src/SocketHandler.cpp295
-rw-r--r--AudioManagerDaemon/test/CMakeLists.txt1
-rw-r--r--AudioManagerDaemon/test/sockethandler/CMakeLists.txt69
-rw-r--r--AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp244
-rw-r--r--AudioManagerDaemon/test/sockethandler/sockethandlerTest.h56
6 files changed, 802 insertions, 0 deletions
diff --git a/AudioManagerDaemon/include/SocketHandler.h b/AudioManagerDaemon/include/SocketHandler.h
new file mode 100644
index 0000000..df6fa7a
--- /dev/null
+++ b/AudioManagerDaemon/include/SocketHandler.h
@@ -0,0 +1,137 @@
+/*
+ * SocketHandler.h
+ *
+ * Created on: Dec 18, 2011
+ * Author: christian
+ */
+
+#ifndef SOCKETHANDLER_H_
+#define SOCKETHANDLER_H_
+
+#include <audiomanagertypes.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <map>
+#include <stdint.h>
+#include <sys/poll.h>
+#include <list>
+
+namespace am {
+
+class TBasicPollCallback;
+class TBasicTimerCallback;
+
+class SocketHandler
+{
+public:
+ typedef uint16_t timerHandle_t; //!<this is a handle for a timer to be used with the SocketHandler
+ SocketHandler();
+ virtual ~SocketHandler();
+
+ am_Error_e addFDPoll(const int fd,const short event,TBasicPollCallback*& callback);
+ am_Error_e removeFDPoll(const int fd);
+ am_Error_e addTimer(const timespec timeouts,TBasicTimerCallback*& callback,timerHandle_t& handle);
+ am_Error_e removeTimer(const timerHandle_t handle);
+ void start_listenting();
+ void stop_listening();
+
+private:
+ struct timer_s //!<struct that holds information of timers
+ {
+ timerHandle_t handle; //!<the handle of the timer
+ timespec countdown; //!<the countdown, this value is decreased every time the timer is up
+ timespec timeout; //!<the original timer value
+ TBasicTimerCallback* callback; //!<the callbackfunction
+ };
+
+ class SubstractTime //!<functor to easy substract from each countdown value
+ {
+ private:
+ timespec param;
+ public:
+ SubstractTime(timespec param): param(param) {}
+ void operator()(timer_s& t) const;
+ };
+
+ typedef std::vector<pollfd> mPollfd_t; //!<vector of filedescriptors
+ typedef std::map<int,TBasicPollCallback*> mMapFdCallback_t; //!<map for the callbacks
+
+ bool fdIsValid(const int fd) const;
+ void initTimer();
+ void timerUp();
+ int timespec2ms(const timespec& time);
+ static bool compareCountdown(const timer_s& a, const timer_s& b)
+ {
+ return (a.countdown.tv_sec==b.countdown.tv_sec) ? (a.countdown.tv_nsec < b.countdown.tv_nsec) : (a.countdown.tv_sec < b.countdown.tv_sec);
+ }
+
+
+ mMapFdCallback_t mMapFdCallback;
+ std::list<timer_s> mListTimer;
+ mPollfd_t mListPollfd;
+ timerHandle_t mNextTimer;
+ timerHandle_t mLastInsertedHandle;
+ timespec mTimeout;
+ bool mDispatch;
+};
+
+/**
+ * classic functor for the BasiCallCallback
+ */
+class TBasicPollCallback
+{
+public:
+ virtual void Call (int fd, const short revent)=0;
+ virtual ~TBasicPollCallback(){};
+};
+
+/**
+ * classic functor for the BasicTimerCallback
+ */
+class TBasicTimerCallback
+{
+public:
+ virtual void Call (SocketHandler::timerHandle_t handle)=0;
+ virtual ~TBasicTimerCallback(){};
+};
+
+
+/**
+ * template to create the functor for a class
+ */
+template <class TClass> class TSpecificPollCallback : public TBasicPollCallback
+{
+private:
+ TClass* mInstance;
+ void (TClass::*mFunction)(int fd, const short revent);
+
+public:
+ TSpecificPollCallback(TClass* instance, void(TClass::*function)(int fd, const short revent))
+ :mInstance(instance), mFunction(function){};
+
+ virtual void Call(int fd, const short revent)
+ {
+ (*mInstance.*mFunction)(fd,revent);
+ };
+};
+
+/**
+ * template to create the functor for a class
+ */
+template <class TClass> class TSpecificTimerCallback : public TBasicTimerCallback
+{
+private:
+ TClass* mInstance;
+ void (TClass::*mFunction)(SocketHandler::timerHandle_t handle);
+
+public:
+ TSpecificTimerCallback(TClass* instance, void(TClass::*function)(SocketHandler::timerHandle_t handle))
+ :mInstance(instance), mFunction(function){};
+
+ virtual void Call(SocketHandler::timerHandle_t handle)
+ {
+ (*mInstance.*mFunction)(handle);
+ }
+};
+} /* namespace am */
+#endif /* SOCKETHANDLER_H_ */
diff --git a/AudioManagerDaemon/src/SocketHandler.cpp b/AudioManagerDaemon/src/SocketHandler.cpp
new file mode 100644
index 0000000..eecba5a
--- /dev/null
+++ b/AudioManagerDaemon/src/SocketHandler.cpp
@@ -0,0 +1,295 @@
+/*
+ * SocketHandler.cpp
+ *
+ * Created on: Dec 18, 2011
+ * Author: christian
+ */
+
+#include "SocketHandler.h"
+#include <assert.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+#include <sys/poll.h>
+#include <algorithm>
+#include <time.h>
+#include <features.h>
+
+//todo: implement ppoll
+
+#include <iostream> //todo remove
+
+namespace am {
+
+SocketHandler::SocketHandler()
+ :mMapFdCallback(),
+ mListTimer(),
+ mListPollfd(),
+ mNextTimer(),
+ mLastInsertedHandle(1),
+ mDispatch(true)
+{
+ mTimeout.tv_nsec=-1;
+ mTimeout.tv_sec=-1;
+}
+
+SocketHandler::~SocketHandler()
+{
+}
+
+
+//todo: maybe have some: give me more time returned?
+/**
+ * start the block listening for filedescriptors. This is the mainloop.
+ */
+void SocketHandler::start_listenting()
+{
+ int pollStatus;
+
+ //init the timer
+ initTimer();
+
+ while (mDispatch)
+ {
+ //block until something is on a filedescriptor
+ if((pollStatus=poll(&mListPollfd.front(),mListPollfd.size(),timespec2ms(mTimeout)))==-1)
+ {
+ //todo enter DLT message here;
+ }
+
+ if (pollStatus!=0) //only check filedescriptors if there was a change
+ {
+ //todo: here could be a timer that makes sure naughty plugins return!
+
+ //go through the list of fds and check if an event was set...
+ mPollfd_t::iterator iterator=mListPollfd.begin();
+ mPollfd_t::iterator iteratorEnd=mListPollfd.end();
+ for(;iterator!=iteratorEnd;++iterator)
+ {
+ //oh yes! then, fire the callback !
+ if(iterator->revents !=0)
+ {
+ //check the map for the right callback
+ mMapFdCallback_t::iterator iteratorCB=mMapFdCallback.begin();
+ iteratorCB=mMapFdCallback.find(iterator->fd);
+ if(iteratorCB!=mMapFdCallback.end())
+ {
+ //fire!
+ iteratorCB->second->Call(iterator->fd,iterator->events);
+ }
+ }
+ }
+ }
+ else //Timerevent
+ {
+ //this was a timer event, we need to take care about the timers
+ timerUp();
+ }
+ }
+}
+
+/**
+ * exits the loop
+ */
+void SocketHandler::stop_listening()
+{
+ mDispatch=false;
+}
+
+/**
+ * Adds a filedescriptor to the polling loop
+ * @param fd this is a valid filedescriptor
+ * @param event the event flags
+ * @param callback the callback that shall be called if the filedescriptor poll succeeded
+ * @return E_OK if the descriptor was added, E_NON_EXISTENT if the fd is not valid
+ */
+am_Error_e SocketHandler::addFDPoll(const int fd, const short event, TBasicPollCallback*& callback)
+{
+ if (!fdIsValid(fd)) return E_NON_EXISTENT;
+
+ pollfd tempPollfd;
+ tempPollfd.fd=fd;
+ tempPollfd.events=event;
+ tempPollfd.revents=NULL;
+
+ //insert the filedescriptor into the poll array
+ mListPollfd.push_back(tempPollfd);
+
+ //insert the callback into the map
+ mMapFdCallback.insert(std::make_pair(fd,callback));
+ return E_OK;
+}
+
+/**
+ * removes a filedescriptor from the poll loop
+ * @param fd the filedescriptor to be removed
+ * @return E_OK in case of sucess, E_NON_EXISTENT or E_UNKNOWN if the fd in not registered
+ */
+am_Error_e SocketHandler::removeFDPoll(const int fd)
+{
+ mMapFdCallback_t::iterator iterator=mMapFdCallback.begin();
+
+ //find the filedescriptor
+ iterator=mMapFdCallback.find(fd);
+ if (iterator==mMapFdCallback.end()) return E_NON_EXISTENT;
+
+ //erase it
+ mMapFdCallback.erase(iterator);
+
+ //also remove from the callBackList
+ mPollfd_t::iterator pollIterator=mListPollfd.begin();
+ for(;pollIterator!=mListPollfd.end();++pollIterator)
+ {
+ if (pollIterator->fd==fd)
+ {
+ mListPollfd.erase(pollIterator);
+ return E_OK;
+ }
+ }
+ return E_UNKNOWN;
+}
+
+/**
+ * adds a timer to the list of timers. The callback will be fired when the timer is up.
+ * This is not a high precise timer, it is very coarse. It is meant to be used for timeouts when waiting
+ * for an answer via a filedescriptor.
+ * One time timer. If you need again a timer, you need to add a new timer in the callback of the old one.
+ * @param timeouts time until the callback is fired
+ * @param callback the callback
+ * @param handle the handle that is created for the timer is returned. Can be used to remove the timer
+ * @return E_OK in case of success
+ */
+am_Error_e SocketHandler::addTimer(const timespec timeouts,TBasicTimerCallback*& callback,timerHandle_t& handle)
+{
+ assert(!((timeouts.tv_sec==0) && (timeouts.tv_nsec==0)));
+ assert(callback!=NULL);
+
+ timer_s timerItem;
+
+ //create a new handle for the timer
+ handle=mLastInsertedHandle++; //todo: overflow ruling !
+ timerItem.handle=handle;
+ timerItem.countdown=timeouts;
+ timerItem.timeout=timeouts;
+ timerItem.callback=callback;
+
+ //add timer to the list
+ mListTimer.push_back(timerItem);
+
+ //very important: sort the list so that the smallest value is front
+ mListTimer.sort(compareCountdown);
+ mTimeout=mListTimer.front().countdown;
+ return E_OK;
+}
+
+/**
+ * removes a timer from the list of timers
+ * @param handle the handle to the timer
+ * @return E_OK in case of success, E_UNKNOWN if timer was not found.
+ */
+am_Error_e SocketHandler::removeTimer(const timerHandle_t handle)
+{
+ assert(handle!=0);
+
+ //go through the list and remove the timer with the handle
+ std::list<timer_s>::iterator it=mListTimer.begin();
+ for(;it!=mListTimer.end();++it)
+ {
+ if(it->handle==handle)
+ {
+ it=mListTimer.erase(it);
+ if (!mListTimer.empty())
+ {
+ mTimeout=mListTimer.front().countdown;
+ }
+ else
+ {
+ mTimeout.tv_nsec=-1;
+ mTimeout.tv_sec=-1;
+ }
+ return E_OK;
+ }
+ }
+ return E_UNKNOWN;
+}
+
+/**
+ * checks if a filedescriptor is valid
+ * @param fd the filedescriptor
+ * @return true if the fd is valid
+ */
+bool SocketHandler::fdIsValid(const int fd) const
+{
+ return (fcntl(fd, F_GETFL) != -1 || errno != EBADF);
+}
+
+/**
+ * whenever a timer is up, this function needs to be called.
+ * Removes the fired timer, calls the callback and resets mTimeout
+ */
+void SocketHandler::timerUp()
+{
+ //first fire the event
+ mListTimer.front().callback->Call(mListTimer.front().handle);
+
+ //then remove the first timer, the one who fired
+ mListTimer.pop_front();
+ if(!mListTimer.empty())
+ {
+ //substract the old value from all timers in the list
+ std::for_each(mListTimer.begin(),mListTimer.end(),SubstractTime(mTimeout));
+ mTimeout=mListTimer.front().countdown;
+ }
+ else
+ {
+ mTimeout.tv_nsec=-1;
+ mTimeout.tv_sec=-1;
+ }
+}
+
+/**
+ * inits the timers
+ */
+void SocketHandler::initTimer()
+{
+ if(!mListTimer.empty())
+ {
+ mTimeout=mListTimer.front().countdown;
+ }
+ else
+ {
+ mTimeout.tv_nsec=-1;
+ mTimeout.tv_sec=-1;
+ }
+}
+
+/**
+ * convert timespec to milliseconds
+ * @param time time in timespec
+ * @return time in milliseconds
+ */
+inline int SocketHandler::timespec2ms(const timespec& time)
+{
+ return (time.tv_nsec==-1 && time.tv_sec==-1) ? -1 : time.tv_sec*1000 + time.tv_nsec/1000000;
+}
+
+/**
+ * functor to easy substract from each countdown
+ * @param t value to substract from
+ */
+void SocketHandler::SubstractTime::operator()(timer_s& t) const
+{
+ int val=0;
+ if((val=t.countdown.tv_nsec-param.tv_nsec)<0)
+ {
+ t.countdown.tv_nsec=1000000000 + val;
+ t.countdown.tv_sec--;
+ }
+ else
+ {
+ t.countdown.tv_nsec=val;
+ }
+ (t.countdown.tv_sec-param.tv_sec)<0 ? 0 : (t.countdown.tv_sec-=param.tv_sec);
+}
+
+
+} /* namespace am */
diff --git a/AudioManagerDaemon/test/CMakeLists.txt b/AudioManagerDaemon/test/CMakeLists.txt
index 3bcc777..e2e22c0 100644
--- a/AudioManagerDaemon/test/CMakeLists.txt
+++ b/AudioManagerDaemon/test/CMakeLists.txt
@@ -15,3 +15,4 @@ cmake_minimum_required(VERSION 2.6)
add_subdirectory (database)
add_subdirectory (routingInterface)
add_subdirectory (controlInterface)
+add_subdirectory (sockethandler) \ No newline at end of file
diff --git a/AudioManagerDaemon/test/sockethandler/CMakeLists.txt b/AudioManagerDaemon/test/sockethandler/CMakeLists.txt
new file mode 100644
index 0000000..a7dd63d
--- /dev/null
+++ b/AudioManagerDaemon/test/sockethandler/CMakeLists.txt
@@ -0,0 +1,69 @@
+#
+# Copyright (C) 2011, BMW AG
+#
+# GeniviAudioMananger ControlInterfaceTest
+#
+# \file CMakeLists.txt
+#
+# \date 20-Oct-2011 3:42:04 PM
+# \author Christian Mueller (christian.ei.mueller@bmw.de)
+#
+# \section License
+# GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
+# Copyright (C) 2011, BMW AG Christian Mueller Christian.ei.mueller@bmw.de
+#
+# This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License, version 2.1, for more details.
+# You should have received a copy of the GNU Lesser General Public License, version 2.1, along with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+# Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may also be applicable to programs even in cases in which the program is not a library in the technical sense.
+# Linking AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. You may license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to license your linked modules under the GNU Lesser General Public License, version 2.1, you may use the program under the following exception.
+# As a special exception, the copyright holders of AudioManager give you permission to combine AudioManager with software programs or libraries that are released under any license unless such a combination is not permitted by the license of such a software program or library. You may copy and distribute such a system following the terms of the GNU Lesser General Public License, version 2.1, including this special exception, for AudioManager and the licenses of the other code concerned.
+# Note that people who make modified versions of AudioManager are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, version 2.1, gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception.
+#
+
+cmake_minimum_required(VERSION 2.6)
+
+PROJECT(socketHandlerTest)
+
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -DUNIT_TEST=1 -DDLT_CONTEXT=AudioManager")
+
+set(STD_INCLUDE_DIRS "/usr/include")
+set(DBUS_FOLDER ${CMAKE_SOURCE_DIR}/../../../dbusInterfaces)
+set(AUDIO_INCLUDES_FOLDER ${CMAKE_SOURCE_DIR}/../../../includes)
+set(DBUS_INCLUDES_FOLDER ${CMAKE_SOURCE_DIR}/../../../../dbusIncludes)
+set(INCLUDES_FOLDER ${CMAKE_SOURCE_DIR}/../../include)
+set(EXECUTABLE_OUTPUT_PATH ../../../../test/)
+
+FIND_PACKAGE(PkgConfig)
+pkg_check_modules(DLT REQUIRED automotive-dlt)
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${AUDIO_INCLUDES_FOLDER}
+ ${DBUS_ARCH_INCLUDE_DIR}
+ ${DBUS_INCLUDES_FOLDER}
+ ${CMAKE_SOURCE_DIR}
+ ${STD_INCLUDE_DIRS}
+ ${DLT_INCLUDE_DIRS}
+ ${DBUS_INCLUDE_DIR}
+ ${INCLUDES_FOLDER}
+)
+
+file(GLOB Socket_SRCS_CXX
+ "../../src/SocketHandler.cpp"
+ "*.cpp"
+)
+
+ADD_EXECUTABLE(socketHandlerTest ${Socket_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES(socketHandlerTest
+ ${DLT_LIBRARIES}
+ ${DBUS_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT}
+ gtest
+ gmock
+)
+
+
+
diff --git a/AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp b/AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp
new file mode 100644
index 0000000..2cab649
--- /dev/null
+++ b/AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp
@@ -0,0 +1,244 @@
+/*
+ * sockethandlerTest.cpp
+ *
+ * Created on: Dec 19, 2011
+ * Author: christian
+ */
+
+#include "sockethandlerTest.h"
+#include <stdio.h>
+#include <sys/socket.h> /* for socket(), connect(), (), and recv() */
+#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
+#include <sys/ioctl.h>
+#include <string.h>
+#include <netdb.h>
+
+
+using namespace testing;
+using namespace am;
+
+sockethandlerTest::sockethandlerTest()
+{
+}
+
+sockethandlerTest::~sockethandlerTest()
+{
+}
+
+void fdCallBack::connectSocket(int fd, const short events)
+{
+ std::cout<<"Socket connection received and open"<<std::endl;
+
+ //accept the connection
+ mSocketConnection = accept(fd, NULL, NULL);
+ short event = 0;
+ event |=POLLIN;
+
+ TBasicPollCallback* buf=&pSocketDataCallback;
+ //add new socketConnection to the handler
+ mSocketHandler->addFDPoll(mSocketConnection,event,buf);
+}
+
+
+
+
+fdCallBack::fdCallBack(SocketHandler *SocketHandler)
+:mSocketConnection(0),
+ mSocketHandler(SocketHandler),
+ pSocketDataCallback(this, &fdCallBack::handleSocketData),
+ pSocketConnectionCallback(this, &fdCallBack::connectSocket)
+{
+}
+
+
+
+void am::fdCallBack::handleSocketData(int fd, const short events)
+{
+ char buffer[3000];
+ std::string msg;
+
+ //there is something for us, read it
+ int read=recv(mSocketConnection,buffer,sizeof(buffer),NULL);
+ msg=std::string(buffer,read);
+ if (msg.compare("stopit")==0)
+ {
+ mSocketHandler->stop_listening();
+ }
+ else if (msg.compare("answer")==0)
+ {
+ std::string answer="myAnswer";
+ send(mSocketConnection,answer.c_str(),answer.size(),NULL);
+ }
+}
+
+fdCallBack::~fdCallBack()
+{
+}
+
+am::timerCallBack::timerCallBack(SocketHandler *myHandler)
+ :pTimer1Callback(this, &timerCallBack::timer1Callback),
+ pTimer2Callback(this, &timerCallBack::timer2Callback),
+ pTimer3Callback(this, &timerCallBack::timer3Callback),
+ pTimer4Callback(this, &timerCallBack::timer4Callback),
+ mSocketHandler(myHandler)
+
+{
+}
+
+
+
+am::timerCallBack::~timerCallBack()
+{
+}
+
+
+
+void am::timerCallBack::timer1Callback(SocketHandler::timerHandle_t handle)
+{
+ std::cout<<"callback1 called"<<std::endl;
+ timespec timeout;
+ timeout.tv_nsec=0;
+ timeout.tv_sec=1;
+ TBasicTimerCallback *buf=&pTimer1Callback;
+ SocketHandler::timerHandle_t handle_;
+ mSocketHandler->addTimer(timeout,buf,handle_);
+}
+
+
+
+void am::timerCallBack::timer2Callback(SocketHandler::timerHandle_t handle)
+{
+ std::cout<<"callback2 called"<<std::endl;
+ timespec timeout;
+ timeout.tv_nsec=0;
+ timeout.tv_sec=1;
+ TBasicTimerCallback *buf=&pTimer2Callback;
+ SocketHandler::timerHandle_t handle_;
+ mSocketHandler->addTimer(timeout,buf,handle_);
+}
+
+void am::timerCallBack::timer3Callback(SocketHandler::timerHandle_t handle)
+{
+ std::cout<<"callback3 called"<<std::endl;
+}
+
+void am::timerCallBack::timer4Callback(SocketHandler::timerHandle_t handle)
+{
+ std::cout<<"callback4 called"<<std::endl;
+}
+
+void* playWithSocketServer(void* data)
+{
+ int yes = 1;
+
+ //get a SocketHandler
+ SocketHandler myHandler;
+
+ //get a class that handles the callbacks from the handler
+ fdCallBack testCallback(&myHandler);
+
+ //prepare the socket, bind etc...
+ struct sockaddr_in servAddr;
+ int socketHandle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ setsockopt(socketHandle, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ servAddr.sin_port = htons(6060);
+ bind(socketHandle, (struct sockaddr*)(&servAddr), sizeof (servAddr));
+ listen(socketHandle, 3);
+
+ //prepare the event (we want POLLIN because we need to listen)
+ short event = 0;
+ event |=POLLIN;
+
+ TBasicPollCallback* buf=&testCallback.pSocketConnectionCallback;
+ //add the callback to the Sockethandler
+ myHandler.addFDPoll(socketHandle, event, buf);
+
+ //start the mainloop
+ myHandler.start_listenting();
+ close(socketHandle);
+}
+
+
+
+TEST(sockethandlerTest,playWithSockets)
+{
+ pthread_t serverThread;
+ char buffer[3000];
+
+ //creates a thread that handles the serverpart
+ pthread_create(&serverThread,NULL,playWithSocketServer,NULL);
+
+ sleep(1); //give a little time to settle everything
+ //make everything ready to send data
+ struct sockaddr_in servAddr;
+ int socketHandle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ struct hostent *host;
+ host = (struct hostent*) gethostbyname("localhost");
+
+ memset(&servAddr, 0, sizeof(servAddr));
+ memcpy(&servAddr.sin_addr, host->h_addr_list[0], host->h_length);
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_port = htons(6060);
+
+ //connect to the socket
+ int k =connect(socketHandle,(struct sockaddr *) &servAddr, sizeof(servAddr));
+
+ std::string msg="answer";
+
+ //send first the answer message and wait for the reply
+ int p=send(socketHandle,msg.c_str(),msg.size(),NULL);
+ int read=recv(socketHandle,buffer,sizeof(buffer),NULL);
+ msg=std::string(buffer,read);
+ ASSERT_TRUE(msg.compare("myAnswer")==0);
+
+ msg="stopit";
+ //now send a message causing the handler to stop and end the loop
+ p=send(socketHandle,msg.c_str(),msg.size(),NULL);
+ pthread_join(serverThread,NULL);
+}
+
+TEST(sockethandlerTest,playWithTimers)
+{
+ SocketHandler myHandler;
+ timerCallBack testCallback(&myHandler);
+ timespec timeoutTime, timeout2, timeout3, timeout4;
+ timeoutTime.tv_sec=3;
+ timeoutTime.tv_nsec=0;
+ timeout2.tv_nsec=0;
+ timeout2.tv_sec=1;
+ timeout3.tv_nsec=000000000;
+ timeout3.tv_sec=2;
+ timeout4.tv_nsec=0;
+ timeout4.tv_sec=30;
+ TBasicTimerCallback* buf=&testCallback.pTimer1Callback;
+ TBasicTimerCallback* buf2=&testCallback.pTimer2Callback;
+ TBasicTimerCallback* buf3=&testCallback.pTimer3Callback;
+ TBasicTimerCallback* buf4=&testCallback.pTimer4Callback;
+ SocketHandler::timerHandle_t handle;
+ myHandler.addTimer(timeoutTime,buf,handle);
+ myHandler.addTimer(timeout2,buf2,handle);
+ myHandler.addTimer(timeout3,buf3,handle);
+ myHandler.addTimer(timeout4,buf4,handle);
+ myHandler.start_listenting();
+
+}
+
+void sockethandlerTest::SetUp()
+{
+}
+
+void sockethandlerTest::TearDown()
+{
+}
+
+int main(int argc, char **argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
+
+
+
diff --git a/AudioManagerDaemon/test/sockethandler/sockethandlerTest.h b/AudioManagerDaemon/test/sockethandler/sockethandlerTest.h
new file mode 100644
index 0000000..5b86ad9
--- /dev/null
+++ b/AudioManagerDaemon/test/sockethandler/sockethandlerTest.h
@@ -0,0 +1,56 @@
+/*
+ * sockethandlerTest.h
+ *
+ * Created on: Dec 19, 2011
+ * Author: christian
+ */
+
+#ifndef SOCKETHANDLERTEST_H_
+#define SOCKETHANDLERTEST_H_
+
+#include <gtest/gtest.h>
+#include "SocketHandler.h"
+
+namespace am {
+
+class fdCallBack
+{
+public:
+ fdCallBack(SocketHandler *SocketHandler);
+ virtual ~fdCallBack();
+ void connectSocket(int fd,const short events);
+ void handleSocketData(int fd,const short events);
+ TSpecificPollCallback<fdCallBack> pSocketDataCallback;
+ TSpecificPollCallback<fdCallBack> pSocketConnectionCallback;
+private:
+ int mSocketConnection;
+ SocketHandler *mSocketHandler;
+};
+
+class timerCallBack
+{
+public:
+ timerCallBack(SocketHandler *SocketHandler);
+ virtual ~timerCallBack();
+ void timer1Callback(SocketHandler::timerHandle_t handle);
+ void timer2Callback(SocketHandler::timerHandle_t handle);
+ void timer3Callback(SocketHandler::timerHandle_t handle);
+ void timer4Callback(SocketHandler::timerHandle_t handle);
+ TSpecificTimerCallback<timerCallBack> pTimer1Callback;
+ TSpecificTimerCallback<timerCallBack> pTimer2Callback;
+ TSpecificTimerCallback<timerCallBack> pTimer3Callback;
+ TSpecificTimerCallback<timerCallBack> pTimer4Callback;
+ SocketHandler *mSocketHandler;
+};
+
+class sockethandlerTest: public ::testing::Test
+{
+public:
+ sockethandlerTest();
+ virtual ~sockethandlerTest();
+ void SetUp();
+ void TearDown();
+};
+
+} /* namespace am */
+#endif /* SOCKETHANDLERTEST_H_ */